//
// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#ifndef COMPILER_TRANSLATOR_TYPES_H_
#define COMPILER_TRANSLATOR_TYPES_H_

#include "common/angleutils.h"
#include "common/debug.h"

#include "compiler/translator/BaseTypes.h"
#include "compiler/translator/Common.h"
#include "compiler/translator/ImmutableString.h"
#include "compiler/translator/SymbolUniqueId.h"

namespace sh
{

struct TPublicType;
class TType;
class TInterfaceBlock;
class TStructure;
class TSymbol;
class TVariable;
class TIntermSymbol;
class TSymbolTable;

class TField : angle::NonCopyable
{
  public:
    POOL_ALLOCATOR_NEW_DELETE
    TField(TType *type, const ImmutableString &name, const TSourceLoc &line, SymbolType symbolType)
        : mType(type), mName(name), mLine(line), mSymbolType(symbolType)
    {
        ASSERT(mSymbolType != SymbolType::Empty);
    }

    // TODO(alokp): We should only return const type.
    // Fix it by tweaking grammar.
    TType *type() { return mType; }
    const TType *type() const { return mType; }
    const ImmutableString &name() const { return mName; }
    const TSourceLoc &line() const { return mLine; }
    SymbolType symbolType() const { return mSymbolType; }

  private:
    TType *mType;
    const ImmutableString mName;
    const TSourceLoc mLine;
    const SymbolType mSymbolType;
};

typedef TVector<TField *> TFieldList;

class TFieldListCollection : angle::NonCopyable
{
  public:
    const TFieldList &fields() const { return *mFields; }

    bool containsArrays() const;
    bool containsMatrices() const;
    bool containsType(TBasicType t) const;
    bool containsSamplers() const;

    size_t objectSize() const;
    // How many locations the field list consumes as a uniform.
    int getLocationCount() const;
    int deepestNesting() const;
    const TString &mangledFieldList() const;

  protected:
    TFieldListCollection(const TFieldList *fields);

    const TFieldList *mFields;

  private:
    size_t calculateObjectSize() const;
    int calculateDeepestNesting() const;
    TString buildMangledFieldList() const;

    mutable size_t mObjectSize;
    mutable int mDeepestNesting;
    mutable TString mMangledFieldList;
};

//
// Base class for things that have a type.
//
class TType
{
  public:
    POOL_ALLOCATOR_NEW_DELETE
    TType();
    explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1);
    TType(TBasicType t,
          TPrecision p,
          TQualifier q     = EvqTemporary,
          unsigned char ps = 1,
          unsigned char ss = 1);
    explicit TType(const TPublicType &p);
    TType(const TStructure *userDef, bool isStructSpecifier);
    TType(const TInterfaceBlock *interfaceBlockIn,
          TQualifier qualifierIn,
          TLayoutQualifier layoutQualifierIn);
    TType(const TType &t);
    TType &operator=(const TType &t);

    constexpr TType(TBasicType t,
                    TPrecision p,
                    TQualifier q,
                    unsigned char ps,
                    unsigned char ss,
                    const char *mangledName)
        : type(t),
          precision(p),
          qualifier(q),
          invariant(false),
          memoryQualifier(TMemoryQualifier::Create()),
          layoutQualifier(TLayoutQualifier::Create()),
          primarySize(ps),
          secondarySize(ss),
          mArraySizes(nullptr),
          mInterfaceBlock(nullptr),
          mStructure(nullptr),
          mIsStructSpecifier(false),
          mMangledName(mangledName)
    {}

    constexpr TType(TType &&t)
        : type(t.type),
          precision(t.precision),
          qualifier(t.qualifier),
          invariant(t.invariant),
          memoryQualifier(t.memoryQualifier),
          layoutQualifier(t.layoutQualifier),
          primarySize(t.primarySize),
          secondarySize(t.secondarySize),
          mArraySizes(t.mArraySizes),
          mInterfaceBlock(t.mInterfaceBlock),
          mStructure(t.mStructure),
          mIsStructSpecifier(t.mIsStructSpecifier),
          mMangledName(t.mMangledName)
    {}

    constexpr TBasicType getBasicType() const { return type; }
    void setBasicType(TBasicType t);

    TPrecision getPrecision() const { return precision; }
    void setPrecision(TPrecision p) { precision = p; }

    constexpr TQualifier getQualifier() const { return qualifier; }
    void setQualifier(TQualifier q) { qualifier = q; }

    bool isInvariant() const { return invariant; }

    void setInvariant(bool i) { invariant = i; }

    TMemoryQualifier getMemoryQualifier() const { return memoryQualifier; }
    void setMemoryQualifier(const TMemoryQualifier &mq) { memoryQualifier = mq; }

    TLayoutQualifier getLayoutQualifier() const { return layoutQualifier; }
    void setLayoutQualifier(TLayoutQualifier lq) { layoutQualifier = lq; }

    int getNominalSize() const { return primarySize; }
    int getSecondarySize() const { return secondarySize; }
    int getCols() const
    {
        ASSERT(isMatrix());
        return primarySize;
    }
    int getRows() const
    {
        ASSERT(isMatrix());
        return secondarySize;
    }
    void setPrimarySize(unsigned char ps);
    void setSecondarySize(unsigned char ss);

    // Full size of single instance of type
    size_t getObjectSize() const;

    // Get how many locations this type consumes as a uniform.
    int getLocationCount() const;

    bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }
    bool isNonSquareMatrix() const { return isMatrix() && primarySize != secondarySize; }
    bool isArray() const { return mArraySizes != nullptr && !mArraySizes->empty(); }
    bool isArrayOfArrays() const { return isArray() && mArraySizes->size() > 1u; }
    size_t getNumArraySizes() const { return isArray() ? mArraySizes->size() : 0; }
    const TVector<unsigned int> *getArraySizes() const { return mArraySizes; }
    unsigned int getArraySizeProduct() const;
    bool isUnsizedArray() const;
    unsigned int getOutermostArraySize() const
    {
        ASSERT(isArray());
        return mArraySizes->back();
    }
    void makeArray(unsigned int s);

    // sizes contain new outermost array sizes.
    void makeArrays(const TVector<unsigned int> &sizes);
    // Here, the array dimension value 0 corresponds to the innermost array.
    void setArraySize(size_t arrayDimension, unsigned int s);

    // Will set unsized array sizes according to newArraySizes. In case there are more
    // unsized arrays than there are sizes in newArraySizes, defaults to setting any
    // remaining array sizes to 1.
    void sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes);

    // Will size the outermost array according to arraySize.
    void sizeOutermostUnsizedArray(unsigned int arraySize);

    // Note that the array element type might still be an array type in GLSL ES version >= 3.10.
    void toArrayElementType();

    const TInterfaceBlock *getInterfaceBlock() const { return mInterfaceBlock; }
    void setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn);
    bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }

    bool isVector() const { return primarySize > 1 && secondarySize == 1; }
    bool isScalar() const
    {
        return primarySize == 1 && secondarySize == 1 && !mStructure && !isArray();
    }
    bool isScalarFloat() const { return isScalar() && type == EbtFloat; }
    bool isScalarInt() const { return isScalar() && (type == EbtInt || type == EbtUInt); }

    bool canBeConstructed() const;

    const TStructure *getStruct() const { return mStructure; }

    static constexpr char GetSizeMangledName(unsigned char primarySize, unsigned char secondarySize)
    {
        unsigned int sizeKey = (secondarySize - 1u) * 4u + primarySize - 1u;
        if (sizeKey < 10u)
        {
            return static_cast<char>('0' + sizeKey);
        }
        return static_cast<char>('A' + sizeKey - 10);
    }
    const char *getMangledName() const;

    bool sameNonArrayType(const TType &right) const;

    // Returns true if arrayType is an array made of this type.
    bool isElementTypeOf(const TType &arrayType) const;

    bool operator==(const TType &right) const
    {
        size_t numArraySizesL = getNumArraySizes();
        size_t numArraySizesR = right.getNumArraySizes();
        bool arraySizesEqual  = numArraySizesL == numArraySizesR &&
                               (numArraySizesL == 0 || *mArraySizes == *right.mArraySizes);
        return type == right.type && primarySize == right.primarySize &&
               secondarySize == right.secondarySize && arraySizesEqual &&
               mStructure == right.mStructure;
        // don't check the qualifier, it's not ever what's being sought after
    }
    bool operator!=(const TType &right) const { return !operator==(right); }
    bool operator<(const TType &right) const
    {
        if (type != right.type)
            return type < right.type;
        if (primarySize != right.primarySize)
            return primarySize < right.primarySize;
        if (secondarySize != right.secondarySize)
            return secondarySize < right.secondarySize;
        size_t numArraySizesL = getNumArraySizes();
        size_t numArraySizesR = right.getNumArraySizes();
        if (numArraySizesL != numArraySizesR)
            return numArraySizesL < numArraySizesR;
        for (size_t i = 0; i < numArraySizesL; ++i)
        {
            if ((*mArraySizes)[i] != (*right.mArraySizes)[i])
                return (*mArraySizes)[i] < (*right.mArraySizes)[i];
        }
        if (mStructure != right.mStructure)
            return mStructure < right.mStructure;

        return false;
    }

    const char *getBasicString() const { return sh::getBasicString(type); }

    const char *getPrecisionString() const { return sh::getPrecisionString(precision); }
    const char *getQualifierString() const { return sh::getQualifierString(qualifier); }

    const char *getBuiltInTypeNameString() const;

    // If this type is a struct, returns the deepest struct nesting of
    // any field in the struct. For example:
    //   struct nesting1 {
    //     vec4 position;
    //   };
    //   struct nesting2 {
    //     nesting1 field1;
    //     vec4 field2;
    //   };
    // For type "nesting2", this method would return 2 -- the number
    // of structures through which indirection must occur to reach the
    // deepest field (nesting2.field1.position).
    int getDeepestStructNesting() const;

    bool isNamelessStruct() const;

    bool isStructureContainingArrays() const;
    bool isStructureContainingMatrices() const;
    bool isStructureContainingType(TBasicType t) const;
    bool isStructureContainingSamplers() const;

    bool isStructSpecifier() const { return mIsStructSpecifier; }

    // Return true if variables of this type should be replaced with an inline constant value if
    // such is available. False will be returned in cases where output doesn't support
    // TIntermConstantUnion nodes of the type, or if the type contains a lot of fields and creating
    // several copies of it in the output code is undesirable for performance.
    bool canReplaceWithConstantUnion() const;

    // The char arrays passed in must be pool allocated or static.
    void createSamplerSymbols(const ImmutableString &namePrefix,
                              const TString &apiNamePrefix,
                              TVector<const TVariable *> *outputSymbols,
                              TMap<const TVariable *, TString> *outputSymbolsToAPINames,
                              TSymbolTable *symbolTable) const;

    // Initializes all lazily-initialized members.
    void realize();

    bool isSampler() const { return IsSampler(type); }

  private:
    void invalidateMangledName();
    const char *buildMangledName() const;

    TBasicType type;
    TPrecision precision;
    TQualifier qualifier;
    bool invariant;
    TMemoryQualifier memoryQualifier;
    TLayoutQualifier layoutQualifier;
    unsigned char primarySize;    // size of vector or cols matrix
    unsigned char secondarySize;  // rows of a matrix

    // Used to make an array type. Outermost array size is stored at the end of the vector. Having 0
    // in this vector means an unsized array.
    TVector<unsigned int> *mArraySizes;

    // This is set only in the following two cases:
    // 1) Represents an interface block.
    // 2) Represents the member variable of an unnamed interface block.
    // It's nullptr also for members of named interface blocks.
    const TInterfaceBlock *mInterfaceBlock;

    // nullptr unless this is a struct
    const TStructure *mStructure;
    bool mIsStructSpecifier;

    mutable const char *mMangledName;
};

// TTypeSpecifierNonArray stores all of the necessary fields for type_specifier_nonarray from the
// grammar
struct TTypeSpecifierNonArray
{
    TBasicType type;
    unsigned char primarySize;    // size of vector or cols of matrix
    unsigned char secondarySize;  // rows of matrix
    const TStructure *userDef;
    TSourceLoc line;

    // true if the type was defined by a struct specifier rather than a reference to a type name.
    bool isStructSpecifier;

    void initialize(TBasicType aType, const TSourceLoc &aLine)
    {
        ASSERT(aType != EbtStruct);
        type              = aType;
        primarySize       = 1;
        secondarySize     = 1;
        userDef           = nullptr;
        line              = aLine;
        isStructSpecifier = false;
    }

    void initializeStruct(const TStructure *aUserDef,
                          bool aIsStructSpecifier,
                          const TSourceLoc &aLine)
    {
        type              = EbtStruct;
        primarySize       = 1;
        secondarySize     = 1;
        userDef           = aUserDef;
        line              = aLine;
        isStructSpecifier = aIsStructSpecifier;
    }

    void setAggregate(unsigned char size) { primarySize = size; }

    void setMatrix(unsigned char columns, unsigned char rows)
    {
        ASSERT(columns > 1 && rows > 1 && columns <= 4 && rows <= 4);
        primarySize   = columns;
        secondarySize = rows;
    }

    bool isMatrix() const { return primarySize > 1 && secondarySize > 1; }

    bool isVector() const { return primarySize > 1 && secondarySize == 1; }
};

//
// This is a workaround for a problem with the yacc stack,  It can't have
// types that it thinks have non-trivial constructors.  It should
// just be used while recognizing the grammar, not anything else.  Pointers
// could be used, but also trying to avoid lots of memory management overhead.
//
// Not as bad as it looks, there is no actual assumption that the fields
// match up or are name the same or anything like that.
//
struct TPublicType
{
    // Must have a trivial default constructor since it is used in YYSTYPE.
    TPublicType() = default;

    void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q);
    void initializeBasicType(TBasicType basicType);

    TBasicType getBasicType() const { return typeSpecifierNonArray.type; }
    void setBasicType(TBasicType basicType) { typeSpecifierNonArray.type = basicType; }

    unsigned char getPrimarySize() const { return typeSpecifierNonArray.primarySize; }
    unsigned char getSecondarySize() const { return typeSpecifierNonArray.secondarySize; }

    const TStructure *getUserDef() const { return typeSpecifierNonArray.userDef; }
    const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }

    bool isStructSpecifier() const { return typeSpecifierNonArray.isStructSpecifier; }

    bool isStructureContainingArrays() const;
    bool isStructureContainingType(TBasicType t) const;
    void setArraySizes(TVector<unsigned int> *sizes);
    bool isArray() const;
    void clearArrayness();
    bool isAggregate() const;

    TTypeSpecifierNonArray typeSpecifierNonArray;
    TLayoutQualifier layoutQualifier;
    TMemoryQualifier memoryQualifier;
    TQualifier qualifier;
    bool invariant;
    TPrecision precision;

    // Either nullptr or empty in case the type is not an array. The last element is the outermost
    // array size. Note that due to bison restrictions, copies of the public type created by the
    // copy constructor share the same arraySizes pointer.
    const TVector<unsigned int> *arraySizes;
};

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_TYPES_H_
