//
// Copyright 2002 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_COMPILER_H_
#define COMPILER_TRANSLATOR_COMPILER_H_

//
// Machine independent part of the compiler private objects
// sent as ShHandle to the driver.
//
// This should not be included by driver code.
//

#include <GLSLANG/ShaderVars.h>

#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/CallDAG.h"
#include "compiler/translator/Diagnostics.h"
#include "compiler/translator/ExtensionBehavior.h"
#include "compiler/translator/HashNames.h"
#include "compiler/translator/InfoSink.h"
#include "compiler/translator/Pragma.h"
#include "compiler/translator/SymbolTable.h"
#include "compiler/translator/ValidateAST.h"
#include "third_party/compiler/ArrayBoundsClamper.h"

namespace sh
{

class TCompiler;
class TParseContext;
#ifdef ANGLE_ENABLE_HLSL
class TranslatorHLSL;
#endif  // ANGLE_ENABLE_HLSL

//
// Helper function to check if the shader type is GLSL.
//
bool IsGLSL130OrNewer(ShShaderOutput output);
bool IsGLSL420OrNewer(ShShaderOutput output);
bool IsGLSL410OrOlder(ShShaderOutput output);

//
// Helper function to check if the invariant qualifier can be removed.
//
bool RemoveInvariant(sh::GLenum shaderType,
                     int shaderVersion,
                     ShShaderOutput outputType,
                     ShCompileOptions compileOptions);

//
// The base class used to back handles returned to the driver.
//
class TShHandleBase
{
  public:
    TShHandleBase();
    virtual ~TShHandleBase();
    virtual TCompiler *getAsCompiler() { return 0; }
#ifdef ANGLE_ENABLE_HLSL
    virtual TranslatorHLSL *getAsTranslatorHLSL() { return 0; }
#endif  // ANGLE_ENABLE_HLSL

  protected:
    // Memory allocator. Allocates and tracks memory required by the compiler.
    // Deallocates all memory when compiler is destructed.
    angle::PoolAllocator allocator;
};

//
// The base class for the machine dependent compiler to derive from
// for managing object code from the compile.
//
class TCompiler : public TShHandleBase
{
  public:
    TCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
    ~TCompiler() override;
    TCompiler *getAsCompiler() override { return this; }

    bool Init(const ShBuiltInResources &resources);

    // compileTreeForTesting should be used only when tests require access to
    // the AST. Users of this function need to manually manage the global pool
    // allocator. Returns nullptr whenever there are compilation errors.
    TIntermBlock *compileTreeForTesting(const char *const shaderStrings[],
                                        size_t numStrings,
                                        ShCompileOptions compileOptions);

    bool compile(const char *const shaderStrings[],
                 size_t numStrings,
                 ShCompileOptions compileOptions);

    // Get results of the last compilation.
    int getShaderVersion() const { return mShaderVersion; }
    TInfoSink &getInfoSink() { return mInfoSink; }

    bool isEarlyFragmentTestsSpecified() const { return mEarlyFragmentTestsSpecified; }

    bool isComputeShaderLocalSizeDeclared() const { return mComputeShaderLocalSizeDeclared; }
    const sh::WorkGroupSize &getComputeShaderLocalSize() const { return mComputeShaderLocalSize; }
    int getNumViews() const { return mNumViews; }

    // Clears the results from the previous compilation.
    void clearResults();

    const std::vector<sh::ShaderVariable> &getAttributes() const { return mAttributes; }
    const std::vector<sh::ShaderVariable> &getOutputVariables() const { return mOutputVariables; }
    const std::vector<sh::ShaderVariable> &getUniforms() const { return mUniforms; }
    const std::vector<sh::ShaderVariable> &getInputVaryings() const { return mInputVaryings; }
    const std::vector<sh::ShaderVariable> &getOutputVaryings() const { return mOutputVaryings; }
    const std::vector<sh::InterfaceBlock> &getInterfaceBlocks() const { return mInterfaceBlocks; }
    const std::vector<sh::InterfaceBlock> &getUniformBlocks() const { return mUniformBlocks; }
    const std::vector<sh::InterfaceBlock> &getShaderStorageBlocks() const
    {
        return mShaderStorageBlocks;
    }
    const std::vector<sh::InterfaceBlock> &getInBlocks() const { return mInBlocks; }

    ShHashFunction64 getHashFunction() const { return mResources.HashFunction; }
    NameMap &getNameMap() { return mNameMap; }
    TSymbolTable &getSymbolTable() { return mSymbolTable; }
    ShShaderSpec getShaderSpec() const { return mShaderSpec; }
    ShShaderOutput getOutputType() const { return mOutputType; }
    const std::string &getBuiltInResourcesString() const { return mBuiltInResourcesString; }

    bool shouldRunLoopAndIndexingValidation(ShCompileOptions compileOptions) const;

    // Get the resources set by InitBuiltInSymbolTable
    const ShBuiltInResources &getResources() const;

    int getGeometryShaderMaxVertices() const { return mGeometryShaderMaxVertices; }
    int getGeometryShaderInvocations() const { return mGeometryShaderInvocations; }
    TLayoutPrimitiveType getGeometryShaderInputPrimitiveType() const
    {
        return mGeometryShaderInputPrimitiveType;
    }
    TLayoutPrimitiveType getGeometryShaderOutputPrimitiveType() const
    {
        return mGeometryShaderOutputPrimitiveType;
    }

    unsigned int getStructSize(const ShaderVariable &var) const;
    unsigned int getSharedMemorySize() const;

    sh::GLenum getShaderType() const { return mShaderType; }

    bool validateAST(TIntermNode *root);

  protected:
    // Add emulated functions to the built-in function emulator.
    virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
                                             ShCompileOptions compileOptions)
    {}
    // Translate to object code. May generate performance warnings through the diagnostics.
    ANGLE_NO_DISCARD virtual bool translate(TIntermBlock *root,
                                            ShCompileOptions compileOptions,
                                            PerformanceDiagnostics *perfDiagnostics) = 0;
    // Get built-in extensions with default behavior.
    const TExtensionBehavior &getExtensionBehavior() const;
    const char *getSourcePath() const;
    const TPragma &getPragma() const { return mPragma; }
    void writePragma(ShCompileOptions compileOptions);
    // Relies on collectVariables having been called.
    bool isVaryingDefined(const char *varyingName);

    const ArrayBoundsClamper &getArrayBoundsClamper() const;
    ShArrayIndexClampingStrategy getArrayIndexClampingStrategy() const;
    const BuiltInFunctionEmulator &getBuiltInFunctionEmulator() const;

    virtual bool shouldFlattenPragmaStdglInvariantAll() = 0;
    virtual bool shouldCollectVariables(ShCompileOptions compileOptions);

    bool wereVariablesCollected() const;
    std::vector<sh::ShaderVariable> mAttributes;
    std::vector<sh::ShaderVariable> mOutputVariables;
    std::vector<sh::ShaderVariable> mUniforms;
    std::vector<sh::ShaderVariable> mInputVaryings;
    std::vector<sh::ShaderVariable> mOutputVaryings;
    std::vector<sh::ShaderVariable> mSharedVariables;
    std::vector<sh::InterfaceBlock> mInterfaceBlocks;
    std::vector<sh::InterfaceBlock> mUniformBlocks;
    std::vector<sh::InterfaceBlock> mShaderStorageBlocks;
    std::vector<sh::InterfaceBlock> mInBlocks;

  private:
    // Initialize symbol-table with built-in symbols.
    bool initBuiltInSymbolTable(const ShBuiltInResources &resources);
    // Compute the string representation of the built-in resources
    void setResourceString();
    // Return false if the call depth is exceeded.
    bool checkCallDepth();
    // Insert statements to reference all members in unused uniform blocks with standard and shared
    // layout. This is to work around a Mac driver that treats unused standard/shared
    // uniform blocks as inactive.
    ANGLE_NO_DISCARD bool useAllMembersInUnusedStandardAndSharedBlocks(TIntermBlock *root);
    // Insert statements to initialize output variables in the beginning of main().
    // This is to avoid undefined behaviors.
    ANGLE_NO_DISCARD bool initializeOutputVariables(TIntermBlock *root);
    // Insert gl_Position = vec4(0,0,0,0) to the beginning of main().
    // It is to work around a Linux driver bug where missing this causes compile failure
    // while spec says it is allowed.
    // This function should only be applied to vertex shaders.
    ANGLE_NO_DISCARD bool initializeGLPosition(TIntermBlock *root);
    // Return true if the maximum expression complexity is below the limit.
    bool limitExpressionComplexity(TIntermBlock *root);
    // Creates the function call DAG for further analysis, returning false if there is a recursion
    bool initCallDag(TIntermNode *root);
    // Return false if "main" doesn't exist
    bool tagUsedFunctions();
    void internalTagUsedFunction(size_t index);

    void collectInterfaceBlocks();

    bool mVariablesCollected;

    bool mGLPositionInitialized;

    // Removes unused function declarations and prototypes from the AST
    class UnusedPredicate;
    void pruneUnusedFunctions(TIntermBlock *root);

    TIntermBlock *compileTreeImpl(const char *const shaderStrings[],
                                  size_t numStrings,
                                  const ShCompileOptions compileOptions);

    // Fetches and stores shader metadata that is not stored within the AST itself, such as shader
    // version.
    void setASTMetadata(const TParseContext &parseContext);

    // Check if shader version meets the requirement.
    bool checkShaderVersion(TParseContext *parseContext);

    // Does checks that need to be run after parsing is complete and returns true if they pass.
    bool checkAndSimplifyAST(TIntermBlock *root,
                             const TParseContext &parseContext,
                             ShCompileOptions compileOptions);

    sh::GLenum mShaderType;
    ShShaderSpec mShaderSpec;
    ShShaderOutput mOutputType;

    struct FunctionMetadata
    {
        FunctionMetadata() : used(false) {}
        bool used;
    };

    CallDAG mCallDag;
    std::vector<FunctionMetadata> mFunctionMetadata;

    ShBuiltInResources mResources;
    std::string mBuiltInResourcesString;

    // Built-in symbol table for the given language, spec, and resources.
    // It is preserved from compile-to-compile.
    TSymbolTable mSymbolTable;
    // Built-in extensions with default behavior.
    TExtensionBehavior mExtensionBehavior;

    ArrayBoundsClamper mArrayBoundsClamper;
    BuiltInFunctionEmulator mBuiltInFunctionEmulator;

    // Results of compilation.
    int mShaderVersion;
    TInfoSink mInfoSink;  // Output sink.
    TDiagnostics mDiagnostics;
    const char *mSourcePath;  // Path of source file or NULL

    // fragment shader early fragment tests
    bool mEarlyFragmentTestsSpecified;

    // compute shader local group size
    bool mComputeShaderLocalSizeDeclared;
    sh::WorkGroupSize mComputeShaderLocalSize;

    // GL_OVR_multiview num_views.
    int mNumViews;

    // geometry shader parameters.
    int mGeometryShaderMaxVertices;
    int mGeometryShaderInvocations;
    TLayoutPrimitiveType mGeometryShaderInputPrimitiveType;
    TLayoutPrimitiveType mGeometryShaderOutputPrimitiveType;

    // name hashing.
    NameMap mNameMap;

    TPragma mPragma;

    // Track what should be validated given passes currently applied.
    ValidateASTOptions mValidateASTOptions;

    ShCompileOptions mCompileOptions;
};

//
// This is the interface between the machine independent code
// and the machine dependent code.
//
// The machine dependent code should derive from the classes
// above. Then Construct*() and Delete*() will create and
// destroy the machine dependent objects, which contain the
// above machine independent information.
//
TCompiler *ConstructCompiler(sh::GLenum type, ShShaderSpec spec, ShShaderOutput output);
void DeleteCompiler(TCompiler *);

void EmitEarlyFragmentTestsGLSL(const TCompiler &, TInfoSinkBase &sink);
void EmitWorkGroupSizeGLSL(const TCompiler &, TInfoSinkBase &sink);
void EmitMultiviewGLSL(const TCompiler &,
                       const ShCompileOptions &,
                       const TExtension,
                       const TBehavior,
                       TInfoSinkBase &sink);

}  // namespace sh

#endif  // COMPILER_TRANSLATOR_COMPILER_H_
