//
// 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"

namespace sh
{

struct TPublicType;
class TType;
class TSymbol;
class TIntermSymbol;

class TField : angle::NonCopyable
{
  public:
    POOL_ALLOCATOR_NEW_DELETE();
    TField(TType *type, TString *name, const TSourceLoc &line)
        : mType(type), mName(name), mLine(line)
    {
    }

    // TODO(alokp): We should only return const type.
    // Fix it by tweaking grammar.
    TType *type() { return mType; }
    const TType *type() const { return mType; }

    const TString &name() const { return *mName; }
    const TSourceLoc &line() const { return mLine; }

  private:
    TType *mType;
    TString *mName;
    TSourceLoc mLine;
};

typedef TVector<TField *> TFieldList;
inline TFieldList *NewPoolTFieldList()
{
    void *memory = GetGlobalPoolAllocator()->allocate(sizeof(TFieldList));
    return new (memory) TFieldList;
}

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

    size_t objectSize() const
    {
        if (mObjectSize == 0)
            mObjectSize = calculateObjectSize();
        return mObjectSize;
    }

    // How many locations the field list consumes as a uniform.
    int getLocationCount() const;

  protected:
    TFieldListCollection(const TString *name, TFieldList *fields)
        : mName(name), mFields(fields), mObjectSize(0)
    {
    }
    TString buildMangledName(const TString &mangledNamePrefix) const;
    size_t calculateObjectSize() const;

    const TString *mName;
    TFieldList *mFields;

    mutable TString mMangledName;
    mutable size_t mObjectSize;
};

// May also represent interface blocks
class TStructure : public TFieldListCollection
{
  public:
    POOL_ALLOCATOR_NEW_DELETE();
    TStructure(const TString *name, TFieldList *fields);

    int deepestNesting() const
    {
        if (mDeepestNesting == 0)
            mDeepestNesting = calculateDeepestNesting();
        return mDeepestNesting;
    }
    bool containsArrays() const;
    bool containsType(TBasicType t) const;
    bool containsSamplers() const;

    void createSamplerSymbols(const TString &structName,
                              const TString &structAPIName,
                              const unsigned int arrayOfStructsSize,
                              TVector<TIntermSymbol *> *outputSymbols,
                              TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const;

    bool equals(const TStructure &other) const;

    void setUniqueId(int uniqueId) { mUniqueId = uniqueId; }

    int uniqueId() const
    {
        ASSERT(mUniqueId != 0);
        return mUniqueId;
    }

    void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }

    bool atGlobalScope() const { return mAtGlobalScope; }

    const TString &mangledName() const
    {
        if (mMangledName.empty())
            mMangledName = buildMangledName("struct-");
        return mMangledName;
    }

  private:
    // TODO(zmo): Find a way to get rid of the const_cast in function
    // setName().  At the moment keep this function private so only
    // friend class RegenerateStructNames may call it.
    friend class RegenerateStructNames;
    void setName(const TString &name)
    {
        TString *mutableName = const_cast<TString *>(mName);
        *mutableName         = name;
    }

    int calculateDeepestNesting() const;

    mutable int mDeepestNesting;
    int mUniqueId;
    bool mAtGlobalScope;
};

class TInterfaceBlock : public TFieldListCollection
{
  public:
    POOL_ALLOCATOR_NEW_DELETE();
    TInterfaceBlock(const TString *name,
                    TFieldList *fields,
                    const TString *instanceName,
                    int arraySize,
                    const TLayoutQualifier &layoutQualifier)
        : TFieldListCollection(name, fields),
          mInstanceName(instanceName),
          mArraySize(arraySize),
          mBlockStorage(layoutQualifier.blockStorage),
          mMatrixPacking(layoutQualifier.matrixPacking)
    {
    }

    const TString &instanceName() const { return *mInstanceName; }
    bool hasInstanceName() const { return mInstanceName != nullptr; }
    bool isArray() const { return mArraySize > 0; }
    int arraySize() const { return mArraySize; }
    TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
    TLayoutMatrixPacking matrixPacking() const { return mMatrixPacking; }
    const TString &mangledName() const
    {
        if (mMangledName.empty())
            mMangledName = buildMangledName("iblock-");
        return mMangledName;
    }

  private:
    const TString *mInstanceName;  // for interface block instance names
    int mArraySize;                // 0 if not an array
    TLayoutBlockStorage mBlockStorage;
    TLayoutMatrixPacking mMatrixPacking;
};

//
// Base class for things that have a type.
//
class TType
{
  public:
    POOL_ALLOCATOR_NEW_DELETE();
    TType()
        : type(EbtVoid),
          precision(EbpUndefined),
          qualifier(EvqGlobal),
          invariant(false),
          memoryQualifier(TMemoryQualifier::create()),
          layoutQualifier(TLayoutQualifier::create()),
          primarySize(0),
          secondarySize(0),
          array(false),
          arraySize(0),
          interfaceBlock(nullptr),
          structure(nullptr)
    {
    }
    explicit TType(TBasicType t, unsigned char ps = 1, unsigned char ss = 1)
        : type(t),
          precision(EbpUndefined),
          qualifier(EvqGlobal),
          invariant(false),
          memoryQualifier(TMemoryQualifier::create()),
          layoutQualifier(TLayoutQualifier::create()),
          primarySize(ps),
          secondarySize(ss),
          array(false),
          arraySize(0),
          interfaceBlock(0),
          structure(0)
    {
    }
    TType(TBasicType t,
          TPrecision p,
          TQualifier q     = EvqTemporary,
          unsigned char ps = 1,
          unsigned char ss = 1,
          bool a           = false)
        : type(t),
          precision(p),
          qualifier(q),
          invariant(false),
          memoryQualifier(TMemoryQualifier::create()),
          layoutQualifier(TLayoutQualifier::create()),
          primarySize(ps),
          secondarySize(ss),
          array(a),
          arraySize(0),
          interfaceBlock(0),
          structure(0)
    {
    }
    explicit TType(const TPublicType &p);
    explicit TType(TStructure *userDef, TPrecision p = EbpUndefined)
        : type(EbtStruct),
          precision(p),
          qualifier(EvqTemporary),
          invariant(false),
          memoryQualifier(TMemoryQualifier::create()),
          layoutQualifier(TLayoutQualifier::create()),
          primarySize(1),
          secondarySize(1),
          array(false),
          arraySize(0),
          interfaceBlock(0),
          structure(userDef)
    {
    }
    TType(TInterfaceBlock *interfaceBlockIn,
          TQualifier qualifierIn,
          TLayoutQualifier layoutQualifierIn,
          int arraySizeIn)
        : type(EbtInterfaceBlock),
          precision(EbpUndefined),
          qualifier(qualifierIn),
          invariant(false),
          memoryQualifier(TMemoryQualifier::create()),
          layoutQualifier(layoutQualifierIn),
          primarySize(1),
          secondarySize(1),
          array(arraySizeIn > 0),
          arraySize(arraySizeIn),
          interfaceBlock(interfaceBlockIn),
          structure(0)
    {
    }

    TType(const TType &) = default;
    TType &operator=(const TType &) = default;

    TBasicType getBasicType() const { return type; }
    void setBasicType(TBasicType t)
    {
        if (type != t)
        {
            type = t;
            invalidateMangledName();
        }
    }

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

    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)
    {
        if (primarySize != ps)
        {
            ASSERT(ps <= 4);
            primarySize = ps;
            invalidateMangledName();
        }
    }
    void setSecondarySize(unsigned char ss)
    {
        if (secondarySize != ss)
        {
            ASSERT(ss <= 4);
            secondarySize = ss;
            invalidateMangledName();
        }
    }

    // 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 array; }
    bool isUnsizedArray() const { return array && arraySize == 0u; }
    unsigned int getArraySize() const { return arraySize; }
    void setArraySize(unsigned int s)
    {
        if (!array || arraySize != s)
        {
            array     = true;
            arraySize = s;
            invalidateMangledName();
        }
    }
    void clearArrayness()
    {
        if (array)
        {
            array     = false;
            arraySize = 0u;
            invalidateMangledName();
        }
    }

    TInterfaceBlock *getInterfaceBlock() const { return interfaceBlock; }
    void setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
    {
        if (interfaceBlock != interfaceBlockIn)
        {
            interfaceBlock = interfaceBlockIn;
            invalidateMangledName();
        }
    }
    bool isInterfaceBlock() const { return type == EbtInterfaceBlock; }

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

    bool canBeConstructed() const;

    TStructure *getStruct() const { return structure; }
    void setStruct(TStructure *s)
    {
        if (structure != s)
        {
            structure = s;
            invalidateMangledName();
        }
    }

    const TString &getMangledName() const
    {
        if (mangled.empty())
        {
            mangled = buildMangledName();
            mangled += ';';
        }

        return mangled;
    }

    bool sameElementType(const TType &right) const
    {
        return type == right.type && primarySize == right.primarySize &&
               secondarySize == right.secondarySize && structure == right.structure;
    }
    bool operator==(const TType &right) const
    {
        return type == right.type && primarySize == right.primarySize &&
               secondarySize == right.secondarySize && array == right.array &&
               (!array || arraySize == right.arraySize) && structure == right.structure;
        // 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;
        if (array != right.array)
            return array < right.array;
        if (arraySize != right.arraySize)
            return arraySize < right.arraySize;
        if (structure != right.structure)
            return structure < right.structure;

        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;

    TString getCompleteString() 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 { return structure ? structure->deepestNesting() : 0; }

    bool isStructureContainingArrays() const
    {
        return structure ? structure->containsArrays() : false;
    }

    bool isStructureContainingType(TBasicType t) const
    {
        return structure ? structure->containsType(t) : false;
    }

    bool isStructureContainingSamplers() const
    {
        return structure ? structure->containsSamplers() : false;
    }

    void createSamplerSymbols(const TString &structName,
                              const TString &structAPIName,
                              const unsigned int arrayOfStructsSize,
                              TVector<TIntermSymbol *> *outputSymbols,
                              TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const
    {
        ASSERT(structure != nullptr && structure->containsSamplers());
        structure->createSamplerSymbols(structName, structAPIName, arrayOfStructsSize,
                                        outputSymbols, outputSymbolsToAPINames);
    }

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

  private:
    void invalidateMangledName() { mangled = ""; }
    TString 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
    bool array;
    unsigned int arraySize;

    // 0 unless this is an interface block, or interface block member variable
    TInterfaceBlock *interfaceBlock;

    // 0 unless this is a struct
    TStructure *structure;

    mutable TString mangled;
};

// 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
    TType *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 bt, const TSourceLoc &ln)
    {
        type              = bt;
        primarySize       = 1;
        secondarySize     = 1;
        userDef           = nullptr;
        line              = ln;
        isStructSpecifier = false;
    }

    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
{
    TTypeSpecifierNonArray typeSpecifierNonArray;
    TLayoutQualifier layoutQualifier;
    TMemoryQualifier memoryQualifier;
    TQualifier qualifier;
    bool invariant;
    TPrecision precision;
    bool array;
    int arraySize;

    void initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
    {
        typeSpecifierNonArray = typeSpecifier;
        layoutQualifier       = TLayoutQualifier::create();
        memoryQualifier       = TMemoryQualifier::create();
        qualifier             = q;
        invariant             = false;
        precision             = EbpUndefined;
        array                 = false;
        arraySize             = 0;
    }

    void initializeBasicType(TBasicType basicType)
    {
        typeSpecifierNonArray.type          = basicType;
        typeSpecifierNonArray.primarySize   = 1;
        typeSpecifierNonArray.secondarySize = 1;
        layoutQualifier                     = TLayoutQualifier::create();
        memoryQualifier                     = TMemoryQualifier::create();
        qualifier                           = EvqTemporary;
        invariant                           = false;
        precision                           = EbpUndefined;
        array                               = false;
        arraySize                           = 0;
    }

    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 TType *getUserDef() const { return typeSpecifierNonArray.userDef; }
    const TSourceLoc &getLine() const { return typeSpecifierNonArray.line; }

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

    bool isStructureContainingArrays() const
    {
        if (!typeSpecifierNonArray.userDef)
        {
            return false;
        }

        return typeSpecifierNonArray.userDef->isStructureContainingArrays();
    }

    bool isStructureContainingType(TBasicType t) const
    {
        if (!typeSpecifierNonArray.userDef)
        {
            return false;
        }

        return typeSpecifierNonArray.userDef->isStructureContainingType(t);
    }

    bool isUnsizedArray() const { return array && arraySize == 0; }
    void setArraySize(int s)
    {
        array     = true;
        arraySize = s;
    }
    void clearArrayness()
    {
        array     = false;
        arraySize = 0;
    }

    bool isAggregate() const
    {
        return array || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
    }
};

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_TYPES_H_
