// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef _SYMBOL_TABLE_INCLUDED_
#define _SYMBOL_TABLE_INCLUDED_

//
// Symbol table for parsing.  Has these design characteristics:
//
// * Same symbol table can be used to compile many shaders, to preserve
//   effort of creating and loading with the large numbers of built-in
//   symbols.
//
// * Name mangling will be used to give each function a unique name
//   so that symbol table lookups are never ambiguous.  This allows
//   a simpler symbol table structure.
//
// * Pushing and popping of scope, so symbol table will really be a stack
//   of symbol tables.  Searched from the top, with new inserts going into
//   the top.
//
// * Constants:  Compile time constant symbols will keep their values
//   in the symbol table.  The parser can substitute constants at parse
//   time, including doing constant folding and constant propagation.
//
// * No temporaries:  Temporaries made from operations (+, --, .xy, etc.)
//   are tracked in the intermediate representation, not the symbol table.
//

#if defined(__ANDROID__) && !defined(ANDROID_HOST_BUILD)
#include "../../Common/DebugAndroid.hpp"
#else
#include <assert.h>
#endif

#include "InfoSink.h"
#include "intermediate.h"
#include <set>

//
// Symbol base class.  (Can build functions or variables out of these...)
//
class TSymbol
{
public:
	POOL_ALLOCATOR_NEW_DELETE();
	TSymbol(const TString *n) :  name(n) { }
	virtual ~TSymbol() { /* don't delete name, it's from the pool */ }

	const TString& getName() const { return *name; }
	virtual const TString& getMangledName() const { return getName(); }
	virtual bool isFunction() const { return false; }
	virtual bool isVariable() const { return false; }
	void setUniqueId(int id) { uniqueId = id; }
	int getUniqueId() const { return uniqueId; }
	TSymbol(const TSymbol&);

protected:
	const TString *name;
	unsigned int uniqueId;      // For real comparing during code generation
};

//
// Variable class, meaning a symbol that's not a function.
//
// There could be a separate class heirarchy for Constant variables;
// Only one of int, bool, or float, (or none) is correct for
// any particular use, but it's easy to do this way, and doesn't
// seem worth having separate classes, and "getConst" can't simply return
// different values for different types polymorphically, so this is
// just simple and pragmatic.
//
class TVariable : public TSymbol
{
public:
	TVariable(const TString *name, const TType& t, bool uT = false ) : TSymbol(name), type(t), userType(uT), unionArray(0), arrayInformationType(0) { }
	virtual ~TVariable() { }
	virtual bool isVariable() const { return true; }
	TType& getType() { return type; }
	const TType& getType() const { return type; }
	bool isUserType() const { return userType; }
	void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
	void updateArrayInformationType(TType *t) { arrayInformationType = t; }
	TType* getArrayInformationType() { return arrayInformationType; }

	ConstantUnion* getConstPointer()
	{
		if (!unionArray)
			unionArray = new ConstantUnion[type.getObjectSize()];

		return unionArray;
	}

	ConstantUnion* getConstPointer() const { return unionArray; }
	bool isConstant() const { return unionArray != nullptr; }

	void shareConstPointer( ConstantUnion *constArray)
	{
		if (unionArray == constArray)
			return;

		delete[] unionArray;
		unionArray = constArray;
	}

protected:
	TType type;
	bool userType;
	// we are assuming that Pool Allocator will free the memory allocated to unionArray
	// when this object is destroyed
	ConstantUnion *unionArray;
	TType *arrayInformationType;  // this is used for updating maxArraySize in all the references to a given symbol
};

//
// The function sub-class of symbols and the parser will need to
// share this definition of a function parameter.
//
struct TParameter
{
	TString *name;
	TType *type;
};

//
// The function sub-class of a symbol.
//
class TFunction : public TSymbol
{
public:
	TFunction(TOperator o) :
		TSymbol(0),
		returnType(TType(EbtVoid, EbpUndefined)),
		op(o),
		defined(false),
		prototypeDeclaration(false) { }
	TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull, const char *ext = "") :
		TSymbol(name),
		returnType(retType),
		mangledName(TFunction::mangleName(*name)),
		op(tOp),
		extension(ext),
		defined(false),
		prototypeDeclaration(false) { }
	virtual ~TFunction();
	virtual bool isFunction() const { return true; }

	static TString mangleName(const TString& name) { return name + '('; }
	static TString unmangleName(const TString& mangledName)
	{
		return TString(mangledName.c_str(), mangledName.find_first_of('('));
	}

	void addParameter(TParameter& p)
	{
		parameters.push_back(p);
		mangledName = mangledName + p.type->getMangledName();
	}

	const TString& getMangledName() const { return mangledName; }
	const TType& getReturnType() const { return returnType; }

	TOperator getBuiltInOp() const { return op; }
	const TString& getExtension() const { return extension; }

	void setDefined() { defined = true; }
	bool isDefined() { return defined; }
	void setHasPrototypeDeclaration() { prototypeDeclaration = true; }
	bool hasPrototypeDeclaration() const { return prototypeDeclaration; }

	size_t getParamCount() const { return parameters.size(); }
	const TParameter& getParam(int i) const { return parameters[i]; }

protected:
	typedef TVector<TParameter> TParamList;
	TParamList parameters;
	TType returnType;
	TString mangledName;
	TOperator op;
	TString extension;
	bool defined;
	bool prototypeDeclaration;
};


class TSymbolTableLevel
{
public:
	typedef TMap<TString, TSymbol*> tLevel;
	typedef tLevel::const_iterator const_iterator;
	typedef const tLevel::value_type tLevelPair;
	typedef std::pair<tLevel::iterator, bool> tInsertResult;

	POOL_ALLOCATOR_NEW_DELETE();
	TSymbolTableLevel() { }
	~TSymbolTableLevel();

	bool insert(TSymbol *symbol);

	// Insert a function using its unmangled name as the key.
	bool insertUnmangled(TFunction *function);

	TSymbol *find(const TString &name) const;

	static int nextUniqueId()
	{
		return ++uniqueId;
	}

protected:
	tLevel level;
	static int uniqueId;     // for unique identification in code generation
};

enum ESymbolLevel
{
	COMMON_BUILTINS,
	ESSL1_BUILTINS,
	ESSL3_BUILTINS,
	LAST_BUILTIN_LEVEL = ESSL3_BUILTINS,
	GLOBAL_LEVEL
};

inline bool IsGenType(const TType *type)
{
	if(type)
	{
		TBasicType basicType = type->getBasicType();
		return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
	}

	return false;
}

inline bool IsVecType(const TType *type)
{
	if(type)
	{
		TBasicType basicType = type->getBasicType();
		return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
	}

	return false;
}

inline TType *GenType(TType *type, int size)
{
	ASSERT(size >= 1 && size <= 4);

	if(!type)
	{
		return nullptr;
	}

	ASSERT(!IsVecType(type));

	switch(type->getBasicType())
	{
	case EbtGenType:  return new TType(EbtFloat, size);
	case EbtGenIType: return new TType(EbtInt, size);
	case EbtGenUType: return new TType(EbtUInt, size);
	case EbtGenBType: return new TType(EbtBool, size);
	default: return type;
	}
}

inline TType *VecType(TType *type, int size)
{
	ASSERT(size >= 2 && size <= 4);

	if(!type)
	{
		return nullptr;
	}

	ASSERT(!IsGenType(type));

	switch(type->getBasicType())
	{
	case EbtVec:  return new TType(EbtFloat, size);
	case EbtIVec: return new TType(EbtInt, size);
	case EbtUVec: return new TType(EbtUInt, size);
	case EbtBVec: return new TType(EbtBool, size);
	default: return type;
	}
}

class TSymbolTable
{
public:
	TSymbolTable()
		: mGlobalInvariant(false)
	{
		//
		// The symbol table cannot be used until push() is called, but
		// the lack of an initial call to push() can be used to detect
		// that the symbol table has not been preloaded with built-ins.
		//
	}

	~TSymbolTable()
	{
		while(currentLevel() > LAST_BUILTIN_LEVEL)
		{
			pop();
		}
	}

	bool isEmpty() { return table.empty(); }
	bool atBuiltInLevel() { return currentLevel() <= LAST_BUILTIN_LEVEL; }
	bool atGlobalLevel() { return currentLevel() <= GLOBAL_LEVEL; }
	void push()
	{
		table.push_back(new TSymbolTableLevel);
		precisionStack.push_back( PrecisionStackLevel() );
	}

	void pop()
	{
		delete table[currentLevel()];
		table.pop_back();
		precisionStack.pop_back();
	}

	bool declare(TSymbol *symbol)
	{
		return insert(currentLevel(), symbol);
	}

	bool insert(ESymbolLevel level, TSymbol *symbol)
	{
		return table[level]->insert(symbol);
	}

	bool insertConstInt(ESymbolLevel level, const char *name, int value)
	{
		TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConstExpr, 1));
		constant->getConstPointer()->setIConst(value);
		return insert(level, constant);
	}

	void insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
	{
		if(ptype1->getBasicType() == EbtGSampler2D)
		{
			insertUnmangledBuiltIn(name);
			bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
			insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
		}
		else if(ptype1->getBasicType() == EbtGSampler3D)
		{
			insertUnmangledBuiltIn(name);
			bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
			insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
		}
		else if(ptype1->getBasicType() == EbtGSamplerCube)
		{
			insertUnmangledBuiltIn(name);
			bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
			insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
		}
		else if(ptype1->getBasicType() == EbtGSampler2DArray)
		{
			insertUnmangledBuiltIn(name);
			bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
			insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
			insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
		}
		else if(IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
		{
			ASSERT(!ptype4);
			insertUnmangledBuiltIn(name);
			insertBuiltIn(level, op, ext, GenType(rvalue, 1), name, GenType(ptype1, 1), GenType(ptype2, 1), GenType(ptype3, 1));
			insertBuiltIn(level, op, ext, GenType(rvalue, 2), name, GenType(ptype1, 2), GenType(ptype2, 2), GenType(ptype3, 2));
			insertBuiltIn(level, op, ext, GenType(rvalue, 3), name, GenType(ptype1, 3), GenType(ptype2, 3), GenType(ptype3, 3));
			insertBuiltIn(level, op, ext, GenType(rvalue, 4), name, GenType(ptype1, 4), GenType(ptype2, 4), GenType(ptype3, 4));
		}
		else if(IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
		{
			ASSERT(!ptype4);
			insertUnmangledBuiltIn(name);
			insertBuiltIn(level, op, ext, VecType(rvalue, 2), name, VecType(ptype1, 2), VecType(ptype2, 2), VecType(ptype3, 2));
			insertBuiltIn(level, op, ext, VecType(rvalue, 3), name, VecType(ptype1, 3), VecType(ptype2, 3), VecType(ptype3, 3));
			insertBuiltIn(level, op, ext, VecType(rvalue, 4), name, VecType(ptype1, 4), VecType(ptype2, 4), VecType(ptype3, 4));
		}
		else
		{
			TFunction *function = new TFunction(NewPoolTString(name), *rvalue, op, ext);

			TParameter param1 = {0, ptype1};
			function->addParameter(param1);

			if(ptype2)
			{
				TParameter param2 = {0, ptype2};
				function->addParameter(param2);
			}

			if(ptype3)
			{
				TParameter param3 = {0, ptype3};
				function->addParameter(param3);
			}

			if(ptype4)
			{
				TParameter param4 = {0, ptype4};
				function->addParameter(param4);
			}

			if(ptype5)
			{
				TParameter param5 = {0, ptype5};
				function->addParameter(param5);
			}

			ASSERT(hasUnmangledBuiltIn(name));
			insert(level, function);
		}
	}

	void insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
	{
		insertUnmangledBuiltIn(name);
		insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
	}

	void insertBuiltIn(ESymbolLevel level, TType *rvalue, const char *name, TType *ptype1, TType *ptype2 = 0, TType *ptype3 = 0, TType *ptype4 = 0, TType *ptype5 = 0)
	{
		insertUnmangledBuiltIn(name);
		insertBuiltIn(level, EOpNull, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
	}

	TSymbol *find(const TString &name, int shaderVersion, bool *builtIn = nullptr, bool *sameScope = nullptr) const;
	TSymbol *findBuiltIn(const TString &name, int shaderVersion) const;

	TSymbolTableLevel *getOuterLevel() const
	{
		assert(currentLevel() >= 1);
		return table[currentLevel() - 1];
	}

	bool setDefaultPrecision(const TPublicType &type, TPrecision prec)
	{
		if (IsSampler(type.type))
			return true;  // Skip sampler types for the time being
		if (type.type != EbtFloat && type.type != EbtInt)
			return false; // Only set default precision for int/float
		if (type.primarySize > 1 || type.secondarySize > 1 || type.array)
			return false; // Not allowed to set for aggregate types
		int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1;
		precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value
		return true;
	}

	// Searches down the precisionStack for a precision qualifier for the specified TBasicType
	TPrecision getDefaultPrecision( TBasicType type)
	{
		// unsigned integers use the same precision as signed
		if (type == EbtUInt) type = EbtInt;

		if( type != EbtFloat && type != EbtInt ) return EbpUndefined;
		int level = static_cast<int>(precisionStack.size()) - 1;
		assert( level >= 0); // Just to be safe. Should not happen.
		PrecisionStackLevel::iterator it;
		TPrecision prec = EbpUndefined; // If we dont find anything we return this. Should we error check this?
		while( level >= 0 ){
			it = precisionStack[level].find( type );
			if( it != precisionStack[level].end() ){
				prec = (*it).second;
				break;
			}
			level--;
		}
		return prec;
	}

	// This records invariant varyings declared through
	// "invariant varying_name;".
	void addInvariantVarying(const std::string &originalName)
	{
		mInvariantVaryings.insert(originalName);
	}
	// If this returns false, the varying could still be invariant
	// if it is set as invariant during the varying variable
	// declaration - this piece of information is stored in the
	// variable's type, not here.
	bool isVaryingInvariant(const std::string &originalName) const
	{
		return (mGlobalInvariant ||
			mInvariantVaryings.count(originalName) > 0);
	}

	void setGlobalInvariant() { mGlobalInvariant = true; }
	bool getGlobalInvariant() const { return mGlobalInvariant; }

	bool hasUnmangledBuiltIn(const char *name) { return mUnmangledBuiltinNames.count(std::string(name)) > 0; }

private:
	// Used to insert unmangled functions to check redeclaration of built-ins in ESSL 3.00.
	void insertUnmangledBuiltIn(const char *name) { mUnmangledBuiltinNames.insert(std::string(name)); }

protected:
	ESymbolLevel currentLevel() const { return static_cast<ESymbolLevel>(table.size() - 1); }

	std::vector<TSymbolTableLevel*> table;
	typedef std::map< TBasicType, TPrecision > PrecisionStackLevel;
	std::vector< PrecisionStackLevel > precisionStack;

	std::set<std::string> mUnmangledBuiltinNames;

	std::set<std::string> mInvariantVaryings;
	bool mGlobalInvariant;
};

#endif // _SYMBOL_TABLE_INCLUDED_
