//
// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
// Copyright (C) 2016 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 TParseContextBase class.

#include <cstdarg>

#include "ParseHelper.h"

extern int yyparse(glslang::TParseContext*);

namespace glslang {

//
// Used to output syntax, parsing, and semantic errors.
//

void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReason,
                                      const char* szToken,
                                      const char* szExtraInfoFormat,
                                      TPrefixType prefix, va_list args)
{
    const int maxSize = MaxTokenLength + 200;
    char szExtraInfo[maxSize];

    safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);

    infoSink.info.prefix(prefix);
    infoSink.info.location(loc);
    infoSink.info << "'" << szToken <<  "' : " << szReason << " " << szExtraInfo << "\n";

    if (prefix == EPrefixError) {
        ++numErrors;
    }
}

#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)

void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
                                     const char* szExtraInfoFormat, ...)
{
    if (messages & EShMsgOnlyPreprocessor)
        return;
    va_list args;
    va_start(args, szExtraInfoFormat);
    outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
    va_end(args);

    if ((messages & EShMsgCascadingErrors) == 0)
        currentScanner->setEndOfInput();
}

void C_DECL TParseContextBase::warn(const TSourceLoc& loc, const char* szReason, const char* szToken,
                                    const char* szExtraInfoFormat, ...)
{
    if (suppressWarnings())
        return;
    va_list args;
    va_start(args, szExtraInfoFormat);
    outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
    va_end(args);
}

void C_DECL TParseContextBase::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken,
                                       const char* szExtraInfoFormat, ...)
{
    va_list args;
    va_start(args, szExtraInfoFormat);
    outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
    va_end(args);

    if ((messages & EShMsgCascadingErrors) == 0)
        currentScanner->setEndOfInput();
}

void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken,
                                      const char* szExtraInfoFormat, ...)
{
    va_list args;
    va_start(args, szExtraInfoFormat);
    outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
    va_end(args);
}

#endif

//
// Both test and if necessary, spit out an error, to see if the node is really
// an l-value that can be operated on this way.
//
// Returns true if there was an error.
//
bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
{
    TIntermBinary* binaryNode = node->getAsBinaryNode();

    if (binaryNode) {
        switch(binaryNode->getOp()) {
        case EOpIndexDirect:
        case EOpIndexIndirect:     // fall through
        case EOpIndexDirectStruct: // fall through
        case EOpVectorSwizzle:
        case EOpMatrixSwizzle:
            return lValueErrorCheck(loc, op, binaryNode->getLeft());
        default:
            break;
        }
        error(loc, " l-value required", op, "", "");

        return true;
    }

    const char* symbol = nullptr;
    TIntermSymbol* symNode = node->getAsSymbolNode();
    if (symNode != nullptr)
        symbol = symNode->getName().c_str();

    const char* message = nullptr;
    switch (node->getQualifier().storage) {
    case EvqConst:          message = "can't modify a const";        break;
    case EvqConstReadOnly:  message = "can't modify a const";        break;
    case EvqUniform:        message = "can't modify a uniform";      break;
#ifndef GLSLANG_WEB
    case EvqBuffer:
        if (node->getQualifier().isReadOnly())
            message = "can't modify a readonly buffer";
        if (node->getQualifier().isShaderRecordNV())
            message = "can't modify a shaderrecordnv qualified buffer";
        break;
    case EvqHitAttrNV:
        if (language != EShLangIntersectNV)
            message = "cannot modify hitAttributeNV in this stage";
        break;
#endif

    default:
        //
        // Type that can't be written to?
        //
        switch (node->getBasicType()) {
        case EbtSampler:
            message = "can't modify a sampler";
            break;
        case EbtVoid:
            message = "can't modify void";
            break;
#ifndef GLSLANG_WEB
        case EbtAtomicUint:
            message = "can't modify an atomic_uint";
            break;
        case EbtAccStructNV:
            message = "can't modify accelerationStructureNV";
            break;
#endif
        default:
            break;
        }
    }

    if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
        error(loc, " l-value required", op, "", "");

        return true;
    }

    //
    // Everything else is okay, no error.
    //
    if (message == nullptr)
        return false;

    //
    // If we get here, we have an error and a message.
    //
    if (symNode)
        error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
    else
        error(loc, " l-value required", op, "(%s)", message);

    return true;
}

// Test for and give an error if the node can't be read from.
void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
{
    if (! node)
        return;

    TIntermBinary* binaryNode = node->getAsBinaryNode();
    if (binaryNode) {
        switch(binaryNode->getOp()) {
        case EOpIndexDirect:
        case EOpIndexIndirect:
        case EOpIndexDirectStruct:
        case EOpVectorSwizzle:
        case EOpMatrixSwizzle:
            rValueErrorCheck(loc, op, binaryNode->getLeft());
        default:
            break;
        }

        return;
    }

    TIntermSymbol* symNode = node->getAsSymbolNode();
    if (symNode && symNode->getQualifier().isWriteOnly())
        error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
}

// Add 'symbol' to the list of deferred linkage symbols, which
// are later processed in finish(), at which point the symbol
// must still be valid.
// It is okay if the symbol's type will be subsequently edited;
// the modifications will be tracked.
// Order is preserved, to avoid creating novel forward references.
void TParseContextBase::trackLinkage(TSymbol& symbol)
{
    if (!parsingBuiltins)
        linkageSymbols.push_back(&symbol);
}

// Ensure index is in bounds, correct if necessary.
// Give an error if not.
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
{
    const auto sizeIsSpecializationExpression = [&type]() {
        return type.containsSpecializationSize() &&
               type.getArraySizes()->getOuterNode() != nullptr &&
               type.getArraySizes()->getOuterNode()->getAsSymbolNode() == nullptr; };

    if (index < 0) {
        error(loc, "", "[", "index out of range '%d'", index);
        index = 0;
    } else if (type.isArray()) {
        if (type.isSizedArray() && !sizeIsSpecializationExpression() &&
            index >= type.getOuterArraySize()) {
            error(loc, "", "[", "array index out of range '%d'", index);
            index = type.getOuterArraySize() - 1;
        }
    } else if (type.isVector()) {
        if (index >= type.getVectorSize()) {
            error(loc, "", "[", "vector index out of range '%d'", index);
            index = type.getVectorSize() - 1;
        }
    } else if (type.isMatrix()) {
        if (index >= type.getMatrixCols()) {
            error(loc, "", "[", "matrix index out of range '%d'", index);
            index = type.getMatrixCols() - 1;
        }
    }
}

// Make a shared symbol have a non-shared version that can be edited by the current
// compile, such that editing its type will not change the shared version and will
// effect all nodes already sharing it (non-shallow type),
// or adopting its full type after being edited (shallow type).
void TParseContextBase::makeEditable(TSymbol*& symbol)
{
    // copyUp() does a deep copy of the type.
    symbol = symbolTable.copyUp(symbol);

    // Save it (deferred, so it can be edited first) in the AST for linker use.
    if (symbol)
        trackLinkage(*symbol);
}

// Return a writable version of the variable 'name'.
//
// Return nullptr if 'name' is not found.  This should mean
// something is seriously wrong (e.g., compiler asking self for
// built-in that doesn't exist).
TVariable* TParseContextBase::getEditableVariable(const char* name)
{
    bool builtIn;
    TSymbol* symbol = symbolTable.find(name, &builtIn);

    assert(symbol != nullptr);
    if (symbol == nullptr)
        return nullptr;

    if (builtIn)
        makeEditable(symbol);

    return symbol->getAsVariable();
}

// Select the best matching function for 'call' from 'candidateList'.
//
// Assumptions
//
// There is no exact match, so a selection algorithm needs to run. That is, the
// language-specific handler should check for exact match first, to
// decide what to do, before calling this selector.
//
// Input
//
//  * list of candidate signatures to select from
//  * the call
//  * a predicate function convertible(from, to) that says whether or not type
//    'from' can implicitly convert to type 'to' (it includes the case of what
//    the calling language would consider a matching type with no conversion
//    needed)
//  * a predicate function better(from1, from2, to1, to2) that says whether or
//    not a conversion from <-> to2 is considered better than a conversion
//    from <-> to1 (both in and out directions need testing, as declared by the
//    formal parameter)
//
// Output
//
//  * best matching candidate (or none, if no viable candidates found)
//  * whether there was a tie for the best match (ambiguous overload selection,
//    caller's choice for how to report)
//
const TFunction* TParseContextBase::selectFunction(
    const TVector<const TFunction*> candidateList,
    const TFunction& call,
    std::function<bool(const TType& from, const TType& to, TOperator op, int arg)> convertible,
    std::function<bool(const TType& from, const TType& to1, const TType& to2)> better,
    /* output */ bool& tie)
{
//
// Operation
//
// 1. Prune the input list of candidates down to a list of viable candidates,
// where each viable candidate has
//
//  * at least as many parameters as there are calling arguments, with any
//    remaining parameters being optional or having default values
//  * each parameter is true under convertible(A, B), where A is the calling
//    type for in and B is the formal type, and in addition, for out B is the
//    calling type and A is the formal type
//
// 2. If there are no viable candidates, return with no match.
//
// 3. If there is only one viable candidate, it is the best match.
//
// 4. If there are multiple viable candidates, select the first viable candidate
// as the incumbent. Compare the incumbent to the next viable candidate, and if
// that candidate is better (bullets below), make it the incumbent. Repeat, with
// a linear walk through the viable candidate list. The final incumbent will be
// returned as the best match. A viable candidate is better than the incumbent if
//
//  * it has a function argument with a better(...) conversion than the incumbent,
//    for all directions needed by in and out
//  * the incumbent has no argument with a better(...) conversion then the
//    candidate, for either in or out (as needed)
//
// 5. Check for ambiguity by comparing the best match against all other viable
// candidates. If any other viable candidate has a function argument with a
// better(...) conversion than the best candidate (for either in or out
// directions), return that there was a tie for best.
//

    tie = false;

    // 1. prune to viable...
    TVector<const TFunction*> viableCandidates;
    for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
        const TFunction& candidate = *(*it);

        // to even be a potential match, number of arguments must be >= the number of
        // fixed (non-default) parameters, and <= the total (including parameter with defaults).
        if (call.getParamCount() < candidate.getFixedParamCount() ||
            call.getParamCount() > candidate.getParamCount())
            continue;

        // see if arguments are convertible
        bool viable = true;

        // The call can have fewer parameters than the candidate, if some have defaults.
        const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
        for (int param = 0; param < paramCount; ++param) {
            if (candidate[param].type->getQualifier().isParamInput()) {
                if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
                    viable = false;
                    break;
                }
            }
            if (candidate[param].type->getQualifier().isParamOutput()) {
                if (! convertible(*candidate[param].type, *call[param].type, candidate.getBuiltInOp(), param)) {
                    viable = false;
                    break;
                }
            }
        }

        if (viable)
            viableCandidates.push_back(&candidate);
    }

    // 2. none viable...
    if (viableCandidates.size() == 0)
        return nullptr;

    // 3. only one viable...
    if (viableCandidates.size() == 1)
        return viableCandidates.front();

    // 4. find best...
    const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
        // is call -> can2 better than call -> can1 for any parameter
        bool hasBetterParam = false;
        for (int param = 0; param < call.getParamCount(); ++param) {
            if (better(*call[param].type, *can1[param].type, *can2[param].type)) {
                hasBetterParam = true;
                break;
            }
        }
        return hasBetterParam;
    };

    const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
        // is call -> can2 equivalent to call -> can1 for all the call parameters?
        for (int param = 0; param < call.getParamCount(); ++param) {
            if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
                better(*call[param].type, *can2[param].type, *can1[param].type))
                return false;
        }
        return true;
    };

    const TFunction* incumbent = viableCandidates.front();
    for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
        const TFunction& candidate = *(*it);
        if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent))
            incumbent = &candidate;
    }

    // 5. ambiguity...
    for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) {
        if (incumbent == *it)
            continue;
        const TFunction& candidate = *(*it);

        // In the case of default parameters, it may have an identical initial set, which is
        // also ambiguous
        if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
            tie = true;
    }

    return incumbent;
}

//
// Look at a '.' field selector string and change it into numerical selectors
// for a vector or scalar.
//
// Always return some form of swizzle, so the result is always usable.
//
void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize,
                                             TSwizzleSelectors<TVectorSelector>& selector)
{
    // Too long?
    if (compString.size() > MaxSwizzleSelectors)
        error(loc, "vector swizzle too long", compString.c_str(), "");

    // Use this to test that all swizzle characters are from the same swizzle-namespace-set
    enum {
        exyzw,
        ergba,
        estpq,
    } fieldSet[MaxSwizzleSelectors];

    // Decode the swizzle string.
    int size = std::min(MaxSwizzleSelectors, (int)compString.size());
    for (int i = 0; i < size; ++i) {
        switch (compString[i])  {
        case 'x':
            selector.push_back(0);
            fieldSet[i] = exyzw;
            break;
        case 'r':
            selector.push_back(0);
            fieldSet[i] = ergba;
            break;
        case 's':
            selector.push_back(0);
            fieldSet[i] = estpq;
            break;

        case 'y':
            selector.push_back(1);
            fieldSet[i] = exyzw;
            break;
        case 'g':
            selector.push_back(1);
            fieldSet[i] = ergba;
            break;
        case 't':
            selector.push_back(1);
            fieldSet[i] = estpq;
            break;

        case 'z':
            selector.push_back(2);
            fieldSet[i] = exyzw;
            break;
        case 'b':
            selector.push_back(2);
            fieldSet[i] = ergba;
            break;
        case 'p':
            selector.push_back(2);
            fieldSet[i] = estpq;
            break;

        case 'w':
            selector.push_back(3);
            fieldSet[i] = exyzw;
            break;
        case 'a':
            selector.push_back(3);
            fieldSet[i] = ergba;
            break;
        case 'q':
            selector.push_back(3);
            fieldSet[i] = estpq;
            break;

        default:
            error(loc, "unknown swizzle selection", compString.c_str(), "");
            break;
        }
    }

    // Additional error checking.
    for (int i = 0; i < selector.size(); ++i) {
        if (selector[i] >= vecSize) {
            error(loc, "vector swizzle selection out of range",  compString.c_str(), "");
            selector.resize(i);
            break;
        }

        if (i > 0 && fieldSet[i] != fieldSet[i-1]) {
            error(loc, "vector swizzle selectors not from the same set", compString.c_str(), "");
            selector.resize(i);
            break;
        }
    }

    // Ensure it is valid.
    if (selector.size() == 0)
        selector.push_back(0);
}

#ifdef ENABLE_HLSL
//
// Make the passed-in variable information become a member of the
// global uniform block.  If this doesn't exist yet, make it.
//
void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList)
{
    // Make the global block, if not yet made.
    if (globalUniformBlock == nullptr) {
        TQualifier blockQualifier;
        blockQualifier.clear();
        blockQualifier.storage = EvqUniform;
        TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
        setUniformBlockDefaults(blockType);
        globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
        firstNewMember = 0;
    }

    // Update with binding and set
    globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
    globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;

    // Add the requested member as a member to the global block.
    TType* type = new TType;
    type->shallowCopy(memberType);
    type->setFieldName(memberName);
    if (typeList)
        type->setStruct(typeList);
    TTypeLoc typeLoc = {type, loc};
    globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);

    // Insert into the symbol table.
    if (firstNewMember == 0) {
        // This is the first request; we need a normal symbol table insert
        if (symbolTable.insert(*globalUniformBlock))
            trackLinkage(*globalUniformBlock);
        else
            error(loc, "failed to insert the global constant buffer", "uniform", "");
    } else {
        // This is a follow-on request; we need to amend the first insert
        symbolTable.amend(*globalUniformBlock, firstNewMember);
    }

    ++firstNewMember;
}
#endif

void TParseContextBase::finish()
{
    if (parsingBuiltins)
        return;

    // Transfer the linkage symbols to AST nodes, preserving order.
    TIntermAggregate* linkage = new TIntermAggregate;
    for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
        intermediate.addSymbolLinkageNode(linkage, **i);
    intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable);
}

} // end namespace glslang
