//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2013-2016 LunarG, Inc.
// Copyright (C) 2015-2018 Google, Inc.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//

//
// Implement the top-level of interface to the compiler/linker,
// as defined in ShaderLang.h
// This is the platform independent interface between an OGL driver
// and the shading language compiler/linker.
//
#include <cstring>
#include <iostream>
#include <sstream>
#include <memory>
#include "SymbolTable.h"
#include "ParseHelper.h"
#include "Scan.h"
#include "ScanContext.h"

#ifdef ENABLE_HLSL
#include "../../hlsl/hlslParseHelper.h"
#include "../../hlsl/hlslParseables.h"
#include "../../hlsl/hlslScanContext.h"
#endif

#include "../Include/ShHandle.h"
#include "../../OGLCompilersDLL/InitializeDll.h"

#include "preprocessor/PpContext.h"

#define SH_EXPORTING
#include "../Public/ShaderLang.h"
#include "reflection.h"
#include "iomapper.h"
#include "Initialize.h"

// TODO: this really shouldn't be here, it is only because of the trial addition
// of printing pre-processed tokens, which requires knowing the string literal
// token to print ", but none of that seems appropriate for this file.
#include "preprocessor/PpTokens.h"

namespace { // anonymous namespace for file-local functions and symbols

// Total number of successful initializers of glslang: a refcount
// Shared global; access should be protected by a global mutex/critical section.
int NumberOfClients = 0;

using namespace glslang;

// Create a language specific version of parseables.
TBuiltInParseables* CreateBuiltInParseables(TInfoSink& infoSink, EShSource source)
{
    switch (source) {
    case EShSourceGlsl: return new TBuiltIns();              // GLSL builtIns
#ifdef ENABLE_HLSL
    case EShSourceHlsl: return new TBuiltInParseablesHlsl(); // HLSL intrinsics
#endif

    default:
        infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
        return nullptr;
    }
}

// Create a language specific version of a parse context.
TParseContextBase* CreateParseContext(TSymbolTable& symbolTable, TIntermediate& intermediate,
                                      int version, EProfile profile, EShSource source,
                                      EShLanguage language, TInfoSink& infoSink,
                                      SpvVersion spvVersion, bool forwardCompatible, EShMessages messages,
                                      bool parsingBuiltIns, std::string sourceEntryPointName = "")
{
    switch (source) {
    case EShSourceGlsl: {
        if (sourceEntryPointName.size() == 0)
            intermediate.setEntryPointName("main");
        TString entryPoint = sourceEntryPointName.c_str();
        return new TParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
                                 language, infoSink, forwardCompatible, messages, &entryPoint);
    }
#ifdef ENABLE_HLSL
    case EShSourceHlsl:
        return new HlslParseContext(symbolTable, intermediate, parsingBuiltIns, version, profile, spvVersion,
                                    language, infoSink, sourceEntryPointName.c_str(), forwardCompatible, messages);
#endif
    default:
        infoSink.info.message(EPrefixInternalError, "Unable to determine source language");
        return nullptr;
    }
}

// Local mapping functions for making arrays of symbol tables....

const int VersionCount = 17;  // index range in MapVersionToIndex

int MapVersionToIndex(int version)
{
    int index = 0;

    switch (version) {
    case 100: index =  0; break;
    case 110: index =  1; break;
    case 120: index =  2; break;
    case 130: index =  3; break;
    case 140: index =  4; break;
    case 150: index =  5; break;
    case 300: index =  6; break;
    case 330: index =  7; break;
    case 400: index =  8; break;
    case 410: index =  9; break;
    case 420: index = 10; break;
    case 430: index = 11; break;
    case 440: index = 12; break;
    case 310: index = 13; break;
    case 450: index = 14; break;
    case 500: index =  0; break; // HLSL
    case 320: index = 15; break;
    case 460: index = 16; break;
    default:  assert(0);  break;
    }

    assert(index < VersionCount);

    return index;
}

const int SpvVersionCount = 3;  // index range in MapSpvVersionToIndex

int MapSpvVersionToIndex(const SpvVersion& spvVersion)
{
    int index = 0;

    if (spvVersion.openGl > 0)
        index = 1;
    else if (spvVersion.vulkan > 0)
        index = 2;

    assert(index < SpvVersionCount);

    return index;
}

const int ProfileCount = 4;   // index range in MapProfileToIndex

int MapProfileToIndex(EProfile profile)
{
    int index = 0;

    switch (profile) {
    case ENoProfile:            index = 0; break;
    case ECoreProfile:          index = 1; break;
    case ECompatibilityProfile: index = 2; break;
    case EEsProfile:            index = 3; break;
    default:                               break;
    }

    assert(index < ProfileCount);

    return index;
}

const int SourceCount = 2;

int MapSourceToIndex(EShSource source)
{
    int index = 0;

    switch (source) {
    case EShSourceGlsl: index = 0; break;
    case EShSourceHlsl: index = 1; break;
    default:                       break;
    }

    assert(index < SourceCount);

    return index;
}

// only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins
enum EPrecisionClass {
    EPcGeneral,
    EPcFragment,
    EPcCount
};

// A process-global symbol table per version per profile for built-ins common
// to multiple stages (languages), and a process-global symbol table per version
// per profile per stage for built-ins unique to each stage.  They will be sparsely
// populated, so they will only be generated as needed.
//
// Each has a different set of built-ins, and we want to preserve that from
// compile to compile.
//
TSymbolTable* CommonSymbolTable[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EPcCount] = {};
TSymbolTable* SharedSymbolTables[VersionCount][SpvVersionCount][ProfileCount][SourceCount][EShLangCount] = {};

TPoolAllocator* PerProcessGPA = nullptr;

//
// Parse and add to the given symbol table the content of the given shader string.
//
bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language,
                           EShSource source, TInfoSink& infoSink, TSymbolTable& symbolTable)
{
    TIntermediate intermediate(language, version, profile);

    intermediate.setSource(source);

    std::unique_ptr<TParseContextBase> parseContext(CreateParseContext(symbolTable, intermediate, version, profile, source,
                                                                       language, infoSink, spvVersion, true, EShMsgDefault,
                                                                       true));

    TShader::ForbidIncluder includer;
    TPpContext ppContext(*parseContext, "", includer);
    TScanContext scanContext(*parseContext);
    parseContext->setScanContext(&scanContext);
    parseContext->setPpContext(&ppContext);

    //
    // Push the symbol table to give it an initial scope.  This
    // push should not have a corresponding pop, so that built-ins
    // are preserved, and the test for an empty table fails.
    //

    symbolTable.push();

    const char* builtInShaders[2];
    size_t builtInLengths[2];
    builtInShaders[0] = builtIns.c_str();
    builtInLengths[0] = builtIns.size();

    if (builtInLengths[0] == 0)
        return true;

    TInputScanner input(1, builtInShaders, builtInLengths);
    if (! parseContext->parseShaderStrings(ppContext, input) != 0) {
        infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
        printf("Unable to parse built-ins\n%s\n", infoSink.info.c_str());
        printf("%s\n", builtInShaders[0]);

        return false;
    }

    return true;
}

int CommonIndex(EProfile profile, EShLanguage language)
{
    return (profile == EEsProfile && language == EShLangFragment) ? EPcFragment : EPcGeneral;
}

//
// To initialize per-stage shared tables, with the common table already complete.
//
void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int version, EProfile profile, const SpvVersion& spvVersion,
                                EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
                                TSymbolTable** symbolTables)
{
    (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
    InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
                          infoSink, *symbolTables[language]);
    builtInParseables.identifyBuiltIns(version, profile, spvVersion, language, *symbolTables[language]);
    if (profile == EEsProfile && version >= 300)
        (*symbolTables[language]).setNoBuiltInRedeclarations();
    if (version == 110)
        (*symbolTables[language]).setSeparateNameSpaces();
}

//
// Initialize the full set of shareable symbol tables;
// The common (cross-stage) and those shareable per-stage.
//
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable,  TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
    std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));

    if (builtInParseables == nullptr)
        return false;

    builtInParseables->initialize(version, profile, spvVersion);

    // do the common tables
    InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangVertex, source,
                          infoSink, *commonTable[EPcGeneral]);
    if (profile == EEsProfile)
        InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, EShLangFragment, source,
                              infoSink, *commonTable[EPcFragment]);

    // do the per-stage tables

    // always have vertex and fragment
    InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangVertex, source,
                               infoSink, commonTable, symbolTables);
    InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
                               infoSink, commonTable, symbolTables);

#ifndef GLSLANG_WEB
    // check for tessellation
    if ((profile != EEsProfile && version >= 150) ||
        (profile == EEsProfile && version >= 310)) {
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessControl, source,
                                   infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTessEvaluation, source,
                                   infoSink, commonTable, symbolTables);
    }

    // check for geometry
    if ((profile != EEsProfile && version >= 150) ||
        (profile == EEsProfile && version >= 310))
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
                                   infoSink, commonTable, symbolTables);

    // check for compute
    if ((profile != EEsProfile && version >= 420) ||
        (profile == EEsProfile && version >= 310))
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
                                   infoSink, commonTable, symbolTables);

    // check for ray tracing stages
    if (profile != EEsProfile && version >= 450) {
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
            infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangIntersectNV, source,
            infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangAnyHitNV, source,
            infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangClosestHitNV, source,
            infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMissNV, source,
            infoSink, commonTable, symbolTables);
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCallableNV, source,
            infoSink, commonTable, symbolTables);
    }

    // check for mesh
    if ((profile != EEsProfile && version >= 450) ||
        (profile == EEsProfile && version >= 320))
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source,
                                   infoSink, commonTable, symbolTables);

    // check for task
    if ((profile != EEsProfile && version >= 450) ||
        (profile == EEsProfile && version >= 320))
        InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
                                   infoSink, commonTable, symbolTables);
#endif

    return true;
}

bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version,
                               EProfile profile, const SpvVersion& spvVersion, EShLanguage language, EShSource source)
{
    std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));

    if (builtInParseables == nullptr)
        return false;

    builtInParseables->initialize(*resources, version, profile, spvVersion, language);
    InitializeSymbolTable(builtInParseables->getCommonString(), version, profile, spvVersion, language, source, infoSink, symbolTable);
    builtInParseables->identifyBuiltIns(version, profile, spvVersion, language, symbolTable, *resources);

    return true;
}

//
// To do this on the fly, we want to leave the current state of our thread's
// pool allocator intact, so:
//  - Switch to a new pool for parsing the built-ins
//  - Do the parsing, which builds the symbol table, using the new pool
//  - Switch to the process-global pool to save a copy of the resulting symbol table
//  - Free up the new pool used to parse the built-ins
//  - Switch back to the original thread's pool
//
// This only gets done the first time any thread needs a particular symbol table
// (lazy evaluation).
//
void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
    TInfoSink infoSink;

    // Make sure only one thread tries to do this at a time
    glslang::GetGlobalLock();

    // See if it's already been done for this version/profile combination
    int versionIndex = MapVersionToIndex(version);
    int spvVersionIndex = MapSpvVersionToIndex(spvVersion);
    int profileIndex = MapProfileToIndex(profile);
    int sourceIndex = MapSourceToIndex(source);
    if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) {
        glslang::ReleaseGlobalLock();

        return;
    }

    // Switch to a new pool
    TPoolAllocator& previousAllocator = GetThreadPoolAllocator();
    TPoolAllocator* builtInPoolAllocator = new TPoolAllocator;
    SetThreadPoolAllocator(builtInPoolAllocator);

    // Dynamically allocate the local symbol tables so we can control when they are deallocated WRT when the pool is popped.
    TSymbolTable* commonTable[EPcCount];
    TSymbolTable* stageTables[EShLangCount];
    for (int precClass = 0; precClass < EPcCount; ++precClass)
        commonTable[precClass] = new TSymbolTable;
    for (int stage = 0; stage < EShLangCount; ++stage)
        stageTables[stage] = new TSymbolTable;

    // Generate the local symbol tables using the new pool
    InitializeSymbolTables(infoSink, commonTable, stageTables, version, profile, spvVersion, source);

    // Switch to the process-global pool
    SetThreadPoolAllocator(PerProcessGPA);

    // Copy the local symbol tables from the new pool to the global tables using the process-global pool
    for (int precClass = 0; precClass < EPcCount; ++precClass) {
        if (! commonTable[precClass]->isEmpty()) {
            CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass] = new TSymbolTable;
            CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->copyTable(*commonTable[precClass]);
            CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][precClass]->readOnly();
        }
    }
    for (int stage = 0; stage < EShLangCount; ++stage) {
        if (! stageTables[stage]->isEmpty()) {
            SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage] = new TSymbolTable;
            SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->adoptLevels(*CommonSymbolTable
                              [versionIndex][spvVersionIndex][profileIndex][sourceIndex][CommonIndex(profile, (EShLanguage)stage)]);
            SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->copyTable(*stageTables[stage]);
            SharedSymbolTables[versionIndex][spvVersionIndex][profileIndex][sourceIndex][stage]->readOnly();
        }
    }

    // Clean up the local tables before deleting the pool they used.
    for (int precClass = 0; precClass < EPcCount; ++precClass)
        delete commonTable[precClass];
    for (int stage = 0; stage < EShLangCount; ++stage)
        delete stageTables[stage];

    delete builtInPoolAllocator;
    SetThreadPoolAllocator(&previousAllocator);

    glslang::ReleaseGlobalLock();
}

// Function to Print all builtins
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
{
#ifndef GLSLANG_WEB
    infoSink.debug << "BuiltinSymbolTable {\n";

    symbolTable.dump(infoSink, true);

    infoSink.debug << "}\n";
#endif
}

// Return true if the shader was correctly specified for version/profile/stage.
bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion,
                          EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion)
{
    const int FirstProfileVersion = 150;
    bool correct = true;

    if (source == EShSourceHlsl) {
        version = 500;          // shader model; currently a characteristic of glslang, not the input
        profile = ECoreProfile; // allow doubles in prototype parsing
        return correct;
    }

    // Get a version...
    if (version == 0) {
        version = defaultVersion;
        // infoSink.info.message(EPrefixWarning, "#version: statement missing; use #version on first line of shader");
    }

    // Get a good profile...
    if (profile == ENoProfile) {
        if (version == 300 || version == 310 || version == 320) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: versions 300, 310, and 320 require specifying the 'es' profile");
            profile = EEsProfile;
        } else if (version == 100)
            profile = EEsProfile;
        else if (version >= FirstProfileVersion)
            profile = ECoreProfile;
        else
            profile = ENoProfile;
    } else {
        // a profile was provided...
        if (version < 150) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: versions before 150 do not allow a profile token");
            if (version == 100)
                profile = EEsProfile;
            else
                profile = ENoProfile;
        } else if (version == 300 || version == 310 || version == 320) {
            if (profile != EEsProfile) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: versions 300, 310, and 320 support only the es profile");
            }
            profile = EEsProfile;
        } else {
            if (profile == EEsProfile) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: only version 300, 310, and 320 support the es profile");
                if (version >= FirstProfileVersion)
                    profile = ECoreProfile;
                else
                    profile = ENoProfile;
            }
            // else: typical desktop case... e.g., "#version 410 core"
        }
    }

    // Fix version...
    switch (version) {
    // ES versions
    case 100: break;
    case 300: break;
    case 310: break;
    case 320: break;

    // desktop versions
    case 110: break;
    case 120: break;
    case 130: break;
    case 140: break;
    case 150: break;
    case 330: break;
    case 400: break;
    case 410: break;
    case 420: break;
    case 430: break;
    case 440: break;
    case 450: break;
    case 460: break;

    // unknown version
    default:
        correct = false;
        infoSink.info.message(EPrefixError, "version not supported");
        if (profile == EEsProfile)
            version = 310;
        else {
            version = 450;
            profile = ECoreProfile;
        }
        break;
    }

#ifndef GLSLANG_WEB
    // Correct for stage type...
    switch (stage) {
    case EShLangGeometry:
        if ((profile == EEsProfile && version < 310) ||
            (profile != EEsProfile && version < 150)) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: geometry shaders require es profile with version 310 or non-es profile with version 150 or above");
            version = (profile == EEsProfile) ? 310 : 150;
            if (profile == EEsProfile || profile == ENoProfile)
                profile = ECoreProfile;
        }
        break;
    case EShLangTessControl:
    case EShLangTessEvaluation:
        if ((profile == EEsProfile && version < 310) ||
            (profile != EEsProfile && version < 150)) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: tessellation shaders require es profile with version 310 or non-es profile with version 150 or above");
            version = (profile == EEsProfile) ? 310 : 400; // 150 supports the extension, correction is to 400 which does not
            if (profile == EEsProfile || profile == ENoProfile)
                profile = ECoreProfile;
        }
        break;
    case EShLangCompute:
        if ((profile == EEsProfile && version < 310) ||
            (profile != EEsProfile && version < 420)) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: compute shaders require es profile with version 310 or above, or non-es profile with version 420 or above");
            version = profile == EEsProfile ? 310 : 420;
        }
        break;
    case EShLangRayGenNV:
    case EShLangIntersectNV:
    case EShLangAnyHitNV:
    case EShLangClosestHitNV:
    case EShLangMissNV:
    case EShLangCallableNV:
        if (profile == EEsProfile || version < 460) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: ray tracing shaders require non-es profile with version 460 or above");
            version = 460;
        }
        break;
    case EShLangMeshNV:
    case EShLangTaskNV:
        if ((profile == EEsProfile && version < 320) ||
            (profile != EEsProfile && version < 450)) {
            correct = false;
            infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
            version = profile == EEsProfile ? 320 : 450;
        }
    default:
        break;
    }

    if (profile == EEsProfile && version >= 300 && versionNotFirst) {
        correct = false;
        infoSink.info.message(EPrefixError, "#version: statement must appear first in es-profile shader; before comments or newlines");
    }

    // Check for SPIR-V compatibility
    if (spvVersion.spv != 0) {
        switch (profile) {
        case EEsProfile:
            if (spvVersion.vulkan > 0 && version < 310) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher");
                version = 310;
            }
            if (spvVersion.openGl >= 100) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: ES shaders for OpenGL SPIR-V are not supported");
                version = 310;
            }
            break;
        case ECompatibilityProfile:
            infoSink.info.message(EPrefixError, "#version: compilation for SPIR-V does not support the compatibility profile");
            break;
        default:
            if (spvVersion.vulkan > 0 && version < 140) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: Desktop shaders for Vulkan SPIR-V require version 140 or higher");
                version = 140;
            }
            if (spvVersion.openGl >= 100 && version < 330) {
                correct = false;
                infoSink.info.message(EPrefixError, "#version: Desktop shaders for OpenGL SPIR-V require version 330 or higher");
                version = 330;
            }
            break;
        }
    }
#endif

    return correct;
}

// There are multiple paths in for setting environment stuff.
// TEnvironment takes precedence, for what it sets, so sort all this out.
// Ideally, the internal code could be made to use TEnvironment, but for
// now, translate it to the historically used parameters.
void TranslateEnvironment(const TEnvironment* environment, EShMessages& messages, EShSource& source,
                          EShLanguage& stage, SpvVersion& spvVersion)
{
    // Set up environmental defaults, first ignoring 'environment'.
    if (messages & EShMsgSpvRules)
        spvVersion.spv = EShTargetSpv_1_0;
    if (messages & EShMsgVulkanRules) {
        spvVersion.vulkan = EShTargetVulkan_1_0;
        spvVersion.vulkanGlsl = 100;
    } else if (spvVersion.spv != 0)
        spvVersion.openGl = 100;

    // Now, override, based on any content set in 'environment'.
    // 'environment' must be cleared to ESh*None settings when items
    // are not being set.
    if (environment != nullptr) {
        // input language
        if (environment->input.languageFamily != EShSourceNone) {
            stage = environment->input.stage;
            switch (environment->input.dialect) {
            case EShClientNone:
                break;
            case EShClientVulkan:
                spvVersion.vulkanGlsl = environment->input.dialectVersion;
                break;
            case EShClientOpenGL:
                spvVersion.openGl = environment->input.dialectVersion;
                break;
            }
            switch (environment->input.languageFamily) {
            case EShSourceNone:
                break;
            case EShSourceGlsl:
                source = EShSourceGlsl;
                messages = static_cast<EShMessages>(messages & ~EShMsgReadHlsl);
                break;
            case EShSourceHlsl:
                source = EShSourceHlsl;
                messages = static_cast<EShMessages>(messages | EShMsgReadHlsl);
                break;
            }
        }

        // client
        switch (environment->client.client) {
        case EShClientVulkan:
            spvVersion.vulkan = environment->client.version;
            break;
        default:
            break;
        }

        // generated code
        switch (environment->target.language) {
        case EshTargetSpv:
            spvVersion.spv = environment->target.version;
            break;
        default:
            break;
        }
    }
}

// Most processes are recorded when set in the intermediate representation,
// These are the few that are not.
void RecordProcesses(TIntermediate& intermediate, EShMessages messages, const std::string& sourceEntryPointName)
{
    if ((messages & EShMsgRelaxedErrors) != 0)
        intermediate.addProcess("relaxed-errors");
    if ((messages & EShMsgSuppressWarnings) != 0)
        intermediate.addProcess("suppress-warnings");
    if ((messages & EShMsgKeepUncalled) != 0)
        intermediate.addProcess("keep-uncalled");
    if (sourceEntryPointName.size() > 0) {
        intermediate.addProcess("source-entrypoint");
        intermediate.addProcessArgument(sourceEntryPointName);
    }
}

// This is the common setup and cleanup code for PreprocessDeferred and
// CompileDeferred.
// It takes any callable with a signature of
//  bool (TParseContextBase& parseContext, TPpContext& ppContext,
//                  TInputScanner& input, bool versionWillBeError,
//                  TSymbolTable& , TIntermediate& ,
//                  EShOptimizationLevel , EShMessages );
// Which returns false if a failure was detected and true otherwise.
//
template<typename ProcessingContext>
bool ProcessDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* customPreamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,  // use 100 for ES environment, 110 for desktop; this is the GLSL version, not SPIR-V or Vulkan
    EProfile defaultProfile,
    // set version/profile to defaultVersion/defaultProfile regardless of the #version
    // directive in the source code
    bool forceDefaultVersionAndProfile,
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TIntermediate& intermediate, // returned tree, etc.
    ProcessingContext& processingContext,
    bool requireNonempty,
    TShader::Includer& includer,
    const std::string sourceEntryPointName = "",
    const TEnvironment* environment = nullptr)  // optional way of fully setting all versions, overriding the above
{
    // This must be undone (.pop()) by the caller, after it finishes consuming the created tree.
    GetThreadPoolAllocator().push();

    if (numStrings == 0)
        return true;

    // Move to length-based strings, rather than null-terminated strings.
    // Also, add strings to include the preamble and to ensure the shader is not null,
    // which lets the grammar accept what was a null (post preprocessing) shader.
    //
    // Shader will look like
    //   string 0:                system preamble
    //   string 1:                custom preamble
    //   string 2...numStrings+1: user's shader
    //   string numStrings+2:     "int;"
    const int numPre = 2;
    const int numPost = requireNonempty? 1 : 0;
    const int numTotal = numPre + numStrings + numPost;
    std::unique_ptr<size_t[]> lengths(new size_t[numTotal]);
    std::unique_ptr<const char*[]> strings(new const char*[numTotal]);
    std::unique_ptr<const char*[]> names(new const char*[numTotal]);
    for (int s = 0; s < numStrings; ++s) {
        strings[s + numPre] = shaderStrings[s];
        if (inputLengths == nullptr || inputLengths[s] < 0)
            lengths[s + numPre] = strlen(shaderStrings[s]);
        else
            lengths[s + numPre] = inputLengths[s];
    }
    if (stringNames != nullptr) {
        for (int s = 0; s < numStrings; ++s)
            names[s + numPre] = stringNames[s];
    } else {
        for (int s = 0; s < numStrings; ++s)
            names[s + numPre] = nullptr;
    }

    // Get all the stages, languages, clients, and other environment
    // stuff sorted out.
    EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
    SpvVersion spvVersion;
    EShLanguage stage = compiler->getLanguage();
    TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion);
#ifdef ENABLE_HLSL
    EShSource source = sourceGuess;
    if (environment != nullptr && environment->target.hlslFunctionality1)
        intermediate.setHlslFunctionality1();
#else
    const EShSource source = EShSourceGlsl;
#endif
    // First, without using the preprocessor or parser, find the #version, so we know what
    // symbol tables, processing rules, etc. to set up.  This does not need the extra strings
    // outlined above, just the user shader, after the system and user preambles.
    glslang::TInputScanner userInput(numStrings, &strings[numPre], &lengths[numPre]);
    int version = 0;
    EProfile profile = ENoProfile;
    bool versionNotFirstToken = false;
    bool versionNotFirst = (source == EShSourceHlsl)
                                ? true
                                : userInput.scanVersion(version, profile, versionNotFirstToken);
    bool versionNotFound = version == 0;
    if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
#ifndef GLSLANG_WEB
        if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
            (version != defaultVersion || profile != defaultProfile)) {
            compiler->infoSink.info << "Warning, (version, profile) forced to be ("
                                    << defaultVersion << ", " << ProfileName(defaultProfile)
                                    << "), while in source code it is ("
                                    << version << ", " << ProfileName(profile) << ")\n";
        }
#endif
        if (versionNotFound) {
            versionNotFirstToken = false;
            versionNotFirst = false;
            versionNotFound = false;
        }
        version = defaultVersion;
        profile = defaultProfile;
    }

    bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
                                            versionNotFirst, defaultVersion, source, version, profile, spvVersion);
    bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
#ifndef GLSLANG_WEB
    bool warnVersionNotFirst = false;
    if (! versionWillBeError && versionNotFirstToken) {
        if (messages & EShMsgRelaxedErrors)
            warnVersionNotFirst = true;
        else
            versionWillBeError = true;
    }
#endif

    intermediate.setSource(source);
    intermediate.setVersion(version);
    intermediate.setProfile(profile);
    intermediate.setSpv(spvVersion);
    RecordProcesses(intermediate, messages, sourceEntryPointName);
    if (spvVersion.vulkan > 0)
        intermediate.setOriginUpperLeft();
#ifdef ENABLE_HLSL
    if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
        intermediate.setHlslOffsets();
#endif
    if (messages & EShMsgDebugInfo) {
        intermediate.setSourceFile(names[numPre]);
        for (int s = 0; s < numStrings; ++s) {
            // The string may not be null-terminated, so make sure we provide
            // the length along with the string.
            intermediate.addSourceText(strings[numPre + s], lengths[numPre + s]);
        }
    }
    SetupBuiltinSymbolTable(version, profile, spvVersion, source);

    TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
                                                  [MapSpvVersionToIndex(spvVersion)]
                                                  [MapProfileToIndex(profile)]
                                                  [MapSourceToIndex(source)]
                                                  [stage];

    // Dynamically allocate the symbol table so we can control when it is deallocated WRT the pool.
    std::unique_ptr<TSymbolTable> symbolTable(new TSymbolTable);
    if (cachedTable)
        symbolTable->adoptLevels(*cachedTable);

    // Add built-in symbols that are potentially context dependent;
    // they get popped again further down.
    if (! AddContextSpecificSymbols(resources, compiler->infoSink, *symbolTable, version, profile, spvVersion,
                                    stage, source)) {
        return false;
    }

    if (messages & EShMsgBuiltinSymbolTable)
        DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable);

    //
    // Now we can process the full shader under proper symbols and rules.
    //

    std::unique_ptr<TParseContextBase> parseContext(CreateParseContext(*symbolTable, intermediate, version, profile, source,
                                                    stage, compiler->infoSink,
                                                    spvVersion, forwardCompatible, messages, false, sourceEntryPointName));
    TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer);

    // only GLSL (bison triggered, really) needs an externally set scan context
    glslang::TScanContext scanContext(*parseContext);
    if (source == EShSourceGlsl)
        parseContext->setScanContext(&scanContext);

    parseContext->setPpContext(&ppContext);
    parseContext->setLimits(*resources);
    if (! goodVersion)
        parseContext->addError();
#ifndef GLSLANG_WEB
    if (warnVersionNotFirst) {
        TSourceLoc loc;
        loc.init();
        parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
    }
#endif

    parseContext->initializeExtensionBehavior();

    // Fill in the strings as outlined above.
    std::string preamble;
    parseContext->getPreamble(preamble);
    strings[0] = preamble.c_str();
    lengths[0] = strlen(strings[0]);
    names[0] = nullptr;
    strings[1] = customPreamble;
    lengths[1] = strlen(strings[1]);
    names[1] = nullptr;
    assert(2 == numPre);
    if (requireNonempty) {
        const int postIndex = numStrings + numPre;
        strings[postIndex] = "\n int;";
        lengths[postIndex] = strlen(strings[numStrings + numPre]);
        names[postIndex] = nullptr;
    }
    TInputScanner fullInput(numStrings + numPre + numPost, strings.get(), lengths.get(), names.get(), numPre, numPost);

    // Push a new symbol allocation scope that will get used for the shader's globals.
    symbolTable->push();

    bool success = processingContext(*parseContext, ppContext, fullInput,
                                     versionWillBeError, *symbolTable,
                                     intermediate, optLevel, messages);
    return success;
}

#ifndef GLSLANG_WEB

// Responsible for keeping track of the most recent source string and line in
// the preprocessor and outputting newlines appropriately if the source string
// or line changes.
class SourceLineSynchronizer {
public:
    SourceLineSynchronizer(const std::function<int()>& lastSourceIndex,
                           std::string* output)
      : getLastSourceIndex(lastSourceIndex), output(output), lastSource(-1), lastLine(0) {}
//    SourceLineSynchronizer(const SourceLineSynchronizer&) = delete;
//    SourceLineSynchronizer& operator=(const SourceLineSynchronizer&) = delete;

    // Sets the internally tracked source string index to that of the most
    // recently read token. If we switched to a new source string, returns
    // true and inserts a newline. Otherwise, returns false and outputs nothing.
    bool syncToMostRecentString() {
        if (getLastSourceIndex() != lastSource) {
            // After switching to a new source string, we need to reset lastLine
            // because line number resets every time a new source string is
            // used. We also need to output a newline to separate the output
            // from the previous source string (if there is one).
            if (lastSource != -1 || lastLine != 0)
                *output += '\n';
            lastSource = getLastSourceIndex();
            lastLine = -1;
            return true;
        }
        return false;
    }

    // Calls syncToMostRecentString() and then sets the internally tracked line
    // number to tokenLine. If we switched to a new line, returns true and inserts
    // newlines appropriately. Otherwise, returns false and outputs nothing.
    bool syncToLine(int tokenLine) {
        syncToMostRecentString();
        const bool newLineStarted = lastLine < tokenLine;
        for (; lastLine < tokenLine; ++lastLine) {
            if (lastLine > 0) *output += '\n';
        }
        return newLineStarted;
    }

    // Sets the internally tracked line number to newLineNum.
    void setLineNum(int newLineNum) { lastLine = newLineNum; }

private:
    SourceLineSynchronizer& operator=(const SourceLineSynchronizer&);

    // A function for getting the index of the last valid source string we've
    // read tokens from.
    const std::function<int()> getLastSourceIndex;
    // output string for newlines.
    std::string* output;
    // lastSource is the source string index (starting from 0) of the last token
    // processed. It is tracked in order for newlines to be inserted when a new
    // source string starts. -1 means we haven't started processing any source
    // string.
    int lastSource;
    // lastLine is the line number (starting from 1) of the last token processed.
    // It is tracked in order for newlines to be inserted when a token appears
    // on a new line. 0 means we haven't started processing any line in the
    // current source string.
    int lastLine;
};

// DoPreprocessing is a valid ProcessingContext template argument,
// which only performs the preprocessing step of compilation.
// It places the result in the "string" argument to its constructor.
//
// This is not an officially supported or fully working path.
struct DoPreprocessing {
    explicit DoPreprocessing(std::string* string): outputString(string) {}
    bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
                    TInputScanner& input, bool versionWillBeError,
                    TSymbolTable&, TIntermediate&,
                    EShOptimizationLevel, EShMessages)
    {
        // This is a list of tokens that do not require a space before or after.
        static const std::string unNeededSpaceTokens = ";()[]";
        static const std::string noSpaceBeforeTokens = ",";
        glslang::TPpToken ppToken;

        parseContext.setScanner(&input);
        ppContext.setInput(input, versionWillBeError);

        std::string outputBuffer;
        SourceLineSynchronizer lineSync(
            std::bind(&TInputScanner::getLastValidSourceIndex, &input), &outputBuffer);

        parseContext.setExtensionCallback([&lineSync, &outputBuffer](
            int line, const char* extension, const char* behavior) {
                lineSync.syncToLine(line);
                outputBuffer += "#extension ";
                outputBuffer += extension;
                outputBuffer += " : ";
                outputBuffer += behavior;
        });

        parseContext.setLineCallback([&lineSync, &outputBuffer, &parseContext](
            int curLineNum, int newLineNum, bool hasSource, int sourceNum, const char* sourceName) {
            // SourceNum is the number of the source-string that is being parsed.
            lineSync.syncToLine(curLineNum);
            outputBuffer += "#line ";
            outputBuffer += std::to_string(newLineNum);
            if (hasSource) {
                outputBuffer += ' ';
                if (sourceName != nullptr) {
                    outputBuffer += '\"';
                    outputBuffer += sourceName;
                    outputBuffer += '\"';
                } else {
                    outputBuffer += std::to_string(sourceNum);
                }
            }
            if (parseContext.lineDirectiveShouldSetNextLine()) {
                // newLineNum is the new line number for the line following the #line
                // directive. So the new line number for the current line is
                newLineNum -= 1;
            }
            outputBuffer += '\n';
            // And we are at the next line of the #line directive now.
            lineSync.setLineNum(newLineNum + 1);
        });

        parseContext.setVersionCallback(
            [&lineSync, &outputBuffer](int line, int version, const char* str) {
                lineSync.syncToLine(line);
                outputBuffer += "#version ";
                outputBuffer += std::to_string(version);
                if (str) {
                    outputBuffer += ' ';
                    outputBuffer += str;
                }
            });

        parseContext.setPragmaCallback([&lineSync, &outputBuffer](
            int line, const glslang::TVector<glslang::TString>& ops) {
                lineSync.syncToLine(line);
                outputBuffer += "#pragma ";
                for(size_t i = 0; i < ops.size(); ++i) {
                    outputBuffer += ops[i].c_str();
                }
        });

        parseContext.setErrorCallback([&lineSync, &outputBuffer](
            int line, const char* errorMessage) {
                lineSync.syncToLine(line);
                outputBuffer += "#error ";
                outputBuffer += errorMessage;
        });

        int lastToken = EndOfInput; // lastToken records the last token processed.
        do {
            int token = ppContext.tokenize(ppToken);
            if (token == EndOfInput)
                break;

            bool isNewString = lineSync.syncToMostRecentString();
            bool isNewLine = lineSync.syncToLine(ppToken.loc.line);

            if (isNewLine) {
                // Don't emit whitespace onto empty lines.
                // Copy any whitespace characters at the start of a line
                // from the input to the output.
                outputBuffer += std::string(ppToken.loc.column - 1, ' ');
            }

            // Output a space in between tokens, but not at the start of a line,
            // and also not around special tokens. This helps with readability
            // and consistency.
            if (!isNewString && !isNewLine && lastToken != EndOfInput &&
                (unNeededSpaceTokens.find((char)token) == std::string::npos) &&
                (unNeededSpaceTokens.find((char)lastToken) == std::string::npos) &&
                (noSpaceBeforeTokens.find((char)token) == std::string::npos)) {
                outputBuffer += ' ';
            }
            lastToken = token;
            if (token == PpAtomConstString)
                outputBuffer += "\"";
            outputBuffer += ppToken.name;
            if (token == PpAtomConstString)
                outputBuffer += "\"";
        } while (true);
        outputBuffer += '\n';
        *outputString = std::move(outputBuffer);

        bool success = true;
        if (parseContext.getNumErrors() > 0) {
            success = false;
            parseContext.infoSink.info.prefix(EPrefixError);
            parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors.  No code generated.\n\n";
        }
        return success;
    }
    std::string* outputString;
};

#endif

// DoFullParse is a valid ProcessingConext template argument for fully
// parsing the shader.  It populates the "intermediate" with the AST.
struct DoFullParse{
  bool operator()(TParseContextBase& parseContext, TPpContext& ppContext,
                  TInputScanner& fullInput, bool versionWillBeError,
                  TSymbolTable&, TIntermediate& intermediate,
                  EShOptimizationLevel optLevel, EShMessages messages)
    {
        bool success = true;
        // Parse the full shader.
        if (! parseContext.parseShaderStrings(ppContext, fullInput, versionWillBeError))
            success = false;

        if (success && intermediate.getTreeRoot()) {
            if (optLevel == EShOptNoGeneration)
                parseContext.infoSink.info.message(EPrefixNone, "No errors.  No code generation or linking was requested.");
            else
                success = intermediate.postProcess(intermediate.getTreeRoot(), parseContext.getLanguage());
        } else if (! success) {
            parseContext.infoSink.info.prefix(EPrefixError);
            parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors.  No code generated.\n\n";
        }

        if (messages & EShMsgAST)
            intermediate.output(parseContext.infoSink, true);

        return success;
    }
};

#ifndef GLSLANG_WEB
// Take a single compilation unit, and run the preprocessor on it.
// Return: True if there were no issues found in preprocessing,
//         False if during preprocessing any unknown version, pragmas or
//         extensions were found.
//
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
bool PreprocessDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* preamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,         // use 100 for ES environment, 110 for desktop
    EProfile defaultProfile,
    bool forceDefaultVersionAndProfile,
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TShader::Includer& includer,
    TIntermediate& intermediate, // returned tree, etc.
    std::string* outputString)
{
    DoPreprocessing parser(outputString);
    return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
                           preamble, optLevel, resources, defaultVersion,
                           defaultProfile, forceDefaultVersionAndProfile,
                           forwardCompatible, messages, intermediate, parser,
                           false, includer);
}
#endif

//
// do a partial compile on the given strings for a single compilation unit
// for a potential deferred link into a single stage (and deferred full compile of that
// stage through machine-dependent compilation).
//
// all preprocessing, parsing, semantic checks, etc. for a single compilation unit
// are done here.
//
// return:  the tree and other information is filled into the intermediate argument,
//          and true is returned by the function for success.
//
bool CompileDeferred(
    TCompiler* compiler,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const char* const stringNames[],
    const char* preamble,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int defaultVersion,         // use 100 for ES environment, 110 for desktop
    EProfile defaultProfile,
    bool forceDefaultVersionAndProfile,
    bool forwardCompatible,     // give errors for use of deprecated features
    EShMessages messages,       // warnings/errors/AST; things to print out
    TIntermediate& intermediate,// returned tree, etc.
    TShader::Includer& includer,
    const std::string sourceEntryPointName = "",
    TEnvironment* environment = nullptr)
{
    DoFullParse parser;
    return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
                           preamble, optLevel, resources, defaultVersion,
                           defaultProfile, forceDefaultVersionAndProfile,
                           forwardCompatible, messages, intermediate, parser,
                           true, includer, sourceEntryPointName, environment);
}

} // end anonymous namespace for local functions

//
// ShInitialize() should be called exactly once per process, not per thread.
//
int ShInitialize()
{
    glslang::InitGlobalLock();

    if (! InitProcess())
        return 0;

    glslang::GetGlobalLock();
    ++NumberOfClients;
    glslang::ReleaseGlobalLock();

    if (PerProcessGPA == nullptr)
        PerProcessGPA = new TPoolAllocator();

    glslang::TScanContext::fillInKeywordMap();
#ifdef ENABLE_HLSL
    glslang::HlslScanContext::fillInKeywordMap();
#endif

    return 1;
}

//
// Driver calls these to create and destroy compiler/linker
// objects.
//

ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
{
    if (!InitThread())
        return 0;

    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));

    return reinterpret_cast<void*>(base);
}

ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions)
{
    if (!InitThread())
        return 0;

    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, debugOptions));

    return reinterpret_cast<void*>(base);
}

ShHandle ShConstructUniformMap()
{
    if (!InitThread())
        return 0;

    TShHandleBase* base = static_cast<TShHandleBase*>(ConstructUniformMap());

    return reinterpret_cast<void*>(base);
}

void ShDestruct(ShHandle handle)
{
    if (handle == 0)
        return;

    TShHandleBase* base = static_cast<TShHandleBase*>(handle);

    if (base->getAsCompiler())
        DeleteCompiler(base->getAsCompiler());
    else if (base->getAsLinker())
        DeleteLinker(base->getAsLinker());
    else if (base->getAsUniformMap())
        DeleteUniformMap(base->getAsUniformMap());
}

//
// Cleanup symbol tables
//
int ShFinalize()
{
    glslang::GetGlobalLock();
    --NumberOfClients;
    assert(NumberOfClients >= 0);
    bool finalize = NumberOfClients == 0;
    glslang::ReleaseGlobalLock();
    if (! finalize)
        return 1;

    for (int version = 0; version < VersionCount; ++version) {
        for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
            for (int p = 0; p < ProfileCount; ++p) {
                for (int source = 0; source < SourceCount; ++source) {
                    for (int stage = 0; stage < EShLangCount; ++stage) {
                        delete SharedSymbolTables[version][spvVersion][p][source][stage];
                        SharedSymbolTables[version][spvVersion][p][source][stage] = 0;
                    }
                }
            }
        }
    }

    for (int version = 0; version < VersionCount; ++version) {
        for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
            for (int p = 0; p < ProfileCount; ++p) {
                for (int source = 0; source < SourceCount; ++source) {
                    for (int pc = 0; pc < EPcCount; ++pc) {
                        delete CommonSymbolTable[version][spvVersion][p][source][pc];
                        CommonSymbolTable[version][spvVersion][p][source][pc] = 0;
                    }
                }
            }
        }
    }

    if (PerProcessGPA != nullptr) {
        delete PerProcessGPA;
        PerProcessGPA = nullptr;
    }

    glslang::TScanContext::deleteKeywordMap();
#ifdef ENABLE_HLSL
    glslang::HlslScanContext::deleteKeywordMap();
#endif

    return 1;
}

//
// Do a full compile on the given strings for a single compilation unit
// forming a complete stage.  The result of the machine dependent compilation
// is left in the provided compile object.
//
// Return:  The return value is really boolean, indicating
// success (1) or failure (0).
//
int ShCompile(
    const ShHandle handle,
    const char* const shaderStrings[],
    const int numStrings,
    const int* inputLengths,
    const EShOptimizationLevel optLevel,
    const TBuiltInResource* resources,
    int /*debugOptions*/,
    int defaultVersion,        // use 100 for ES environment, 110 for desktop
    bool forwardCompatible,    // give errors for use of deprecated features
    EShMessages messages       // warnings/errors/AST; things to print out
    )
{
    // Map the generic handle to the C++ object
    if (handle == 0)
        return 0;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    TCompiler* compiler = base->getAsCompiler();
    if (compiler == 0)
        return 0;

    SetThreadPoolAllocator(compiler->getPool());

    compiler->infoSink.info.erase();
    compiler->infoSink.debug.erase();

    TIntermediate intermediate(compiler->getLanguage());
    TShader::ForbidIncluder includer;
    bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr,
                                   "", optLevel, resources, defaultVersion, ENoProfile, false,
                                   forwardCompatible, messages, intermediate, includer);

    //
    // Call the machine dependent compiler
    //
    if (success && intermediate.getTreeRoot() && optLevel != EShOptNoGeneration)
        success = compiler->compile(intermediate.getTreeRoot(), intermediate.getVersion(), intermediate.getProfile());

    intermediate.removeTree();

    // Throw away all the temporary memory used by the compilation process.
    // The push was done in the CompileDeferred() call above.
    GetThreadPoolAllocator().pop();

    return success ? 1 : 0;
}

//
// Link the given compile objects.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShLinkExt(
    const ShHandle linkHandle,
    const ShHandle compHandles[],
    const int numHandles)
{
    if (linkHandle == 0 || numHandles == 0)
        return 0;

    THandleList cObjects;

    for (int i = 0; i < numHandles; ++i) {
        if (compHandles[i] == 0)
            return 0;
        TShHandleBase* base = reinterpret_cast<TShHandleBase*>(compHandles[i]);
        if (base->getAsLinker()) {
            cObjects.push_back(base->getAsLinker());
        }
        if (base->getAsCompiler())
            cObjects.push_back(base->getAsCompiler());

        if (cObjects[i] == 0)
            return 0;
    }

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(linkHandle);
    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());

    SetThreadPoolAllocator(linker->getPool());

    if (linker == 0)
        return 0;

    linker->infoSink.info.erase();

    for (int i = 0; i < numHandles; ++i) {
        if (cObjects[i]->getAsCompiler()) {
            if (! cObjects[i]->getAsCompiler()->linkable()) {
                linker->infoSink.info.message(EPrefixError, "Not all shaders have valid object code.");
                return 0;
            }
        }
    }

    bool ret = linker->link(cObjects);

    return ret ? 1 : 0;
}

//
// ShSetEncrpytionMethod is a place-holder for specifying
// how source code is encrypted.
//
void ShSetEncryptionMethod(ShHandle handle)
{
    if (handle == 0)
        return;
}

//
// Return any compiler/linker/uniformmap log of messages for the application.
//
const char* ShGetInfoLog(const ShHandle handle)
{
    if (handle == 0)
        return 0;

    TShHandleBase* base = static_cast<TShHandleBase*>(handle);
    TInfoSink* infoSink;

    if (base->getAsCompiler())
        infoSink = &(base->getAsCompiler()->getInfoSink());
    else if (base->getAsLinker())
        infoSink = &(base->getAsLinker()->getInfoSink());
    else
        return 0;

    infoSink->info << infoSink->debug.c_str();
    return infoSink->info.c_str();
}

//
// Return the resulting binary code from the link process.  Structure
// is machine dependent.
//
const void* ShGetExecutable(const ShHandle handle)
{
    if (handle == 0)
        return 0;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);

    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
    if (linker == 0)
        return 0;

    return linker->getObjectCode();
}

//
// Let the linker know where the application said it's attributes are bound.
// The linker does not use these values, they are remapped by the ICD or
// hardware.  It just needs them to know what's aliased.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table)
{
    if (handle == 0)
        return 0;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());

    if (linker == 0)
        return 0;

    linker->setAppAttributeBindings(table);

    return 1;
}

//
// Let the linker know where the predefined attributes have to live.
//
int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table)
{
    if (handle == 0)
        return 0;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());

    if (linker == 0)
        return 0;

    linker->setFixedAttributeBindings(table);
    return 1;
}

//
// Some attribute locations are off-limits to the linker...
//
int ShExcludeAttributes(const ShHandle handle, int *attributes, int count)
{
    if (handle == 0)
        return 0;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    TLinker* linker = static_cast<TLinker*>(base->getAsLinker());
    if (linker == 0)
        return 0;

    linker->setExcludedAttributes(attributes, count);

    return 1;
}

//
// Return the index for OpenGL to use for knowing where a uniform lives.
//
// Return:  The return value of is really boolean, indicating
// success or failure.
//
int ShGetUniformLocation(const ShHandle handle, const char* name)
{
    if (handle == 0)
        return -1;

    TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
    TUniformMap* uniformMap= base->getAsUniformMap();
    if (uniformMap == 0)
        return -1;

    return uniformMap->getLocation(name);
}

////////////////////////////////////////////////////////////////////////////////////////////
//
// Deferred-Lowering C++ Interface
// -----------------------------------
//
// Below is a new alternate C++ interface that might potentially replace the above
// opaque handle-based interface.
//
// See more detailed comment in ShaderLang.h
//

namespace glslang {

#include "../Include/revision.h"

#define QUOTE(s) #s
#define STR(n) QUOTE(n)

const char* GetEsslVersionString()
{
    return "OpenGL ES GLSL 3.20 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
}

const char* GetGlslVersionString()
{
    return "4.60 glslang Khronos. " STR(GLSLANG_MINOR_VERSION) "." STR(GLSLANG_PATCH_LEVEL);
}

int GetKhronosToolId()
{
    return 8;
}

bool InitializeProcess()
{
    return ShInitialize() != 0;
}

void FinalizeProcess()
{
    ShFinalize();
}

class TDeferredCompiler : public TCompiler {
public:
    TDeferredCompiler(EShLanguage s, TInfoSink& i) : TCompiler(s, i) { }
    virtual bool compile(TIntermNode*, int = 0, EProfile = ENoProfile) { return true; }
};

TShader::TShader(EShLanguage s)
    : stage(s), lengths(nullptr), stringNames(nullptr), preamble("")
{
    pool = new TPoolAllocator;
    infoSink = new TInfoSink;
    compiler = new TDeferredCompiler(stage, *infoSink);
    intermediate = new TIntermediate(s);

    // clear environment (avoid constructors in them for use in a C interface)
    environment.input.languageFamily = EShSourceNone;
    environment.input.dialect = EShClientNone;
    environment.client.client = EShClientNone;
    environment.target.language = EShTargetNone;
    environment.target.hlslFunctionality1 = false;
}

TShader::~TShader()
{
    delete infoSink;
    delete compiler;
    delete intermediate;
    delete pool;
}

void TShader::setStrings(const char* const* s, int n)
{
    strings = s;
    numStrings = n;
    lengths = nullptr;
}

void TShader::setStringsWithLengths(const char* const* s, const int* l, int n)
{
    strings = s;
    numStrings = n;
    lengths = l;
}

void TShader::setStringsWithLengthsAndNames(
    const char* const* s, const int* l, const char* const* names, int n)
{
    strings = s;
    numStrings = n;
    lengths = l;
    stringNames = names;
}

void TShader::setEntryPoint(const char* entryPoint)
{
    intermediate->setEntryPointName(entryPoint);
}

void TShader::setSourceEntryPoint(const char* name)
{
    sourceEntryPointName = name;
}

void TShader::addProcesses(const std::vector<std::string>& p)
{
    intermediate->addProcesses(p);
}

void TShader::setInvertY(bool invert)                   { intermediate->setInvertY(invert); }
void TShader::setNanMinMaxClamp(bool useNonNan)         { intermediate->setNanMinMaxClamp(useNonNan); }

#ifndef GLSLANG_WEB

// Set binding base for given resource type
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
    intermediate->setShiftBinding(res, base);
}

// Set binding base for given resource type for a given binding set.
void TShader::setShiftBindingForSet(TResourceType res, unsigned int base, unsigned int set) {
    intermediate->setShiftBindingForSet(res, base, set);
}

// Set binding base for sampler types
void TShader::setShiftSamplerBinding(unsigned int base) { setShiftBinding(EResSampler, base); }
// Set binding base for texture types (SRV)
void TShader::setShiftTextureBinding(unsigned int base) { setShiftBinding(EResTexture, base); }
// Set binding base for image types
void TShader::setShiftImageBinding(unsigned int base)   { setShiftBinding(EResImage, base); }
// Set binding base for uniform buffer objects (CBV)
void TShader::setShiftUboBinding(unsigned int base)     { setShiftBinding(EResUbo, base); }
// Synonym for setShiftUboBinding, to match HLSL language.
void TShader::setShiftCbufferBinding(unsigned int base) { setShiftBinding(EResUbo, base); }
// Set binding base for UAV (unordered access view)
void TShader::setShiftUavBinding(unsigned int base)     { setShiftBinding(EResUav, base); }
// Set binding base for SSBOs
void TShader::setShiftSsboBinding(unsigned int base)    { setShiftBinding(EResSsbo, base); }
// Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map)              { intermediate->setAutoMapBindings(map); }
// Enables position.Y output negation in vertex shader

// Fragile: currently within one stage: simple auto-assignment of location
void TShader::setAutoMapLocations(bool map)             { intermediate->setAutoMapLocations(map); }
void TShader::addUniformLocationOverride(const char* name, int loc)
{
    intermediate->addUniformLocationOverride(name, loc);
}
void TShader::setUniformLocationBase(int base)
{
    intermediate->setUniformLocationBase(base);
}
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
void TShader::setResourceSetBinding(const std::vector<std::string>& base)   { intermediate->setResourceSetBinding(base); }
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
#endif

#ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }
void TShader::setFlattenUniformArrays(bool flatten)     { intermediate->setFlattenUniformArrays(flatten); }
#endif

//
// Turn the shader strings into a parse tree in the TIntermediate.
//
// Returns true for success.
//
bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile,
                    bool forwardCompatible, EShMessages messages, Includer& includer)
{
    if (! InitThread())
        return false;
    SetThreadPoolAllocator(pool);

    if (! preamble)
        preamble = "";

    return CompileDeferred(compiler, strings, numStrings, lengths, stringNames,
                           preamble, EShOptNone, builtInResources, defaultVersion,
                           defaultProfile, forceDefaultVersionAndProfile,
                           forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
                           &environment);
}

#ifndef GLSLANG_WEB
// Fill in a string with the result of preprocessing ShaderStrings
// Returns true if all extensions, pragmas and version strings were valid.
//
// NOTE: Doing just preprocessing to obtain a correct preprocessed shader string
// is not an officially supported or fully working path.
bool TShader::preprocess(const TBuiltInResource* builtInResources,
                         int defaultVersion, EProfile defaultProfile,
                         bool forceDefaultVersionAndProfile,
                         bool forwardCompatible, EShMessages message,
                         std::string* output_string,
                         Includer& includer)
{
    if (! InitThread())
        return false;
    SetThreadPoolAllocator(pool);

    if (! preamble)
        preamble = "";

    return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble,
                              EShOptNone, builtInResources, defaultVersion,
                              defaultProfile, forceDefaultVersionAndProfile,
                              forwardCompatible, message, includer, *intermediate, output_string);
}
#endif

const char* TShader::getInfoLog()
{
    return infoSink->info.c_str();
}

const char* TShader::getInfoDebugLog()
{
    return infoSink->debug.c_str();
}

TProgram::TProgram() :
#ifndef GLSLANG_WEB
    reflection(0),
#endif
    linked(false)
{
    pool = new TPoolAllocator;
    infoSink = new TInfoSink;
    for (int s = 0; s < EShLangCount; ++s) {
        intermediate[s] = 0;
        newedIntermediate[s] = false;
    }
}

TProgram::~TProgram()
{
    delete infoSink;
#ifndef GLSLANG_WEB
    delete reflection;
#endif

    for (int s = 0; s < EShLangCount; ++s)
        if (newedIntermediate[s])
            delete intermediate[s];

    delete pool;
}

//
// Merge the compilation units within each stage into a single TIntermediate.
// All starting compilation units need to be the result of calling TShader::parse().
//
// Return true for success.
//
bool TProgram::link(EShMessages messages)
{
    if (linked)
        return false;
    linked = true;

    bool error = false;

    SetThreadPoolAllocator(pool);

    for (int s = 0; s < EShLangCount; ++s) {
        if (! linkStage((EShLanguage)s, messages))
            error = true;
    }

    // TODO: Link: cross-stage error checking

    return ! error;
}

//
// Merge the compilation units within the given stage into a single TIntermediate.
//
// Return true for success.
//
bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
{
    if (stages[stage].size() == 0)
        return true;

#ifndef GLSLANG_WEB
    int numEsShaders = 0, numNonEsShaders = 0;
    for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
        if ((*it)->intermediate->getProfile() == EEsProfile) {
            numEsShaders++;
        } else {
            numNonEsShaders++;
        }
    }

    if (numEsShaders > 0 && numNonEsShaders > 0) {
        infoSink->info.message(EPrefixError, "Cannot mix ES profile with non-ES profile shaders");
        return false;
    } else if (numEsShaders > 1) {
        infoSink->info.message(EPrefixError, "Cannot attach multiple ES shaders of the same type to a single program");
        return false;
    }

    //
    // Be efficient for the common single compilation unit per stage case,
    // reusing it's TIntermediate instead of merging into a new one.
    //
    TIntermediate *firstIntermediate = stages[stage].front()->intermediate;
    if (stages[stage].size() == 1)
        intermediate[stage] = firstIntermediate;
    else {
        intermediate[stage] = new TIntermediate(stage,
                                                firstIntermediate->getVersion(),
                                                firstIntermediate->getProfile());


        // The new TIntermediate must use the same origin as the original TIntermediates.
        // Otherwise linking will fail due to different coordinate systems.
        if (firstIntermediate->getOriginUpperLeft()) {
            intermediate[stage]->setOriginUpperLeft();
        }
        intermediate[stage]->setSpv(firstIntermediate->getSpv());

        newedIntermediate[stage] = true;
    }

    if (messages & EShMsgAST)
        infoSink->info << "\nLinked " << StageName(stage) << " stage:\n\n";

    if (stages[stage].size() > 1) {
        std::list<TShader*>::const_iterator it;
        for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
            intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
    }
#else
    intermediate[stage] = stages[stage].front()->intermediate;
#endif
    intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);

    if (messages & EShMsgAST)
        intermediate[stage]->output(*infoSink, true);

    return intermediate[stage]->getNumErrors() == 0;
}

const char* TProgram::getInfoLog()
{
    return infoSink->info.c_str();
}

const char* TProgram::getInfoDebugLog()
{
    return infoSink->debug.c_str();
}

#ifndef GLSLANG_WEB

//
// Reflection implementation.
//

bool TProgram::buildReflection(int opts)
{
    if (! linked || reflection != nullptr)
        return false;

    int firstStage = EShLangVertex, lastStage = EShLangFragment;

    if (opts & EShReflectionIntermediateIO) {
        // if we're reflecting intermediate I/O, determine the first and last stage linked and use those as the
        // boundaries for which stages generate pipeline inputs/outputs
        firstStage = EShLangCount;
        lastStage = 0;
        for (int s = 0; s < EShLangCount; ++s) {
            if (intermediate[s]) {
                firstStage = std::min(firstStage, s);
                lastStage = std::max(lastStage, s);
            }
        }
    }

    reflection = new TReflection((EShReflectionOptions)opts, (EShLanguage)firstStage, (EShLanguage)lastStage);

    for (int s = 0; s < EShLangCount; ++s) {
        if (intermediate[s]) {
            if (! reflection->addStage((EShLanguage)s, *intermediate[s]))
                return false;
        }
    }

    return true;
}

unsigned TProgram::getLocalSize(int dim) const                        { return reflection->getLocalSize(dim); }
int TProgram::getReflectionIndex(const char* name) const              { return reflection->getIndex(name); }
int TProgram::getNumUniformVariables() const                          { return reflection->getNumUniforms(); }
const TObjectReflection& TProgram::getUniform(int index) const        { return reflection->getUniform(index); }
int TProgram::getNumUniformBlocks() const                             { return reflection->getNumUniformBlocks(); }
const TObjectReflection& TProgram::getUniformBlock(int index) const   { return reflection->getUniformBlock(index); }
int TProgram::getNumPipeInputs() const                                { return reflection->getNumPipeInputs(); }
const TObjectReflection& TProgram::getPipeInput(int index) const      { return reflection->getPipeInput(index); }
int TProgram::getNumPipeOutputs() const                               { return reflection->getNumPipeOutputs(); }
const TObjectReflection& TProgram::getPipeOutput(int index) const     { return reflection->getPipeOutput(index); }
int TProgram::getNumBufferVariables() const                           { return reflection->getNumBufferVariables(); }
const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); }
int TProgram::getNumBufferBlocks() const                              { return reflection->getNumStorageBuffers(); }
const TObjectReflection& TProgram::getBufferBlock(int index) const    { return reflection->getStorageBufferBlock(index); }
int TProgram::getNumAtomicCounters() const                            { return reflection->getNumAtomicCounters(); }
const TObjectReflection& TProgram::getAtomicCounter(int index) const  { return reflection->getAtomicCounter(index); }
void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); }

//
// I/O mapping implementation.
//
bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
{
    if (! linked)
        return false;
    TIoMapper* ioMapper = nullptr;
    TIoMapper defaultIOMapper;
    if (pIoMapper == nullptr)
        ioMapper = &defaultIOMapper;
    else
        ioMapper = pIoMapper;
    for (int s = 0; s < EShLangCount; ++s) {
        if (intermediate[s]) {
            if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver))
                return false;
        }
    }

    return ioMapper->doMap(pResolver, *infoSink);
}

#endif // GLSLANG_WEB

} // end namespace glslang
