/*
 * Copyright 2021 Google LLC.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SKSL_DSLPARSER
#define SKSL_DSLPARSER

#include "include/core/SkTypes.h"
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLProgramKind.h"
#include "include/private/SkTArray.h"
#include "include/private/SkTHash.h"
#include "include/sksl/DSLCore.h"
#include "include/sksl/DSLExpression.h"
#include "include/sksl/DSLLayout.h"
#include "include/sksl/DSLModifiers.h"
#include "include/sksl/DSLStatement.h"
#include "include/sksl/DSLType.h"
#include "include/sksl/SkSLErrorReporter.h"
#include "include/sksl/SkSLOperator.h"
#include "include/sksl/SkSLPosition.h"
#include "src/sksl/SkSLCompiler.h"
#include "src/sksl/SkSLLexer.h"
#include "src/sksl/SkSLProgramSettings.h"

#include <memory>
#include <optional>
#include <string>
#include <string_view>

namespace SkSL {

struct ParsedModule;
struct Program;

namespace dsl {
class DSLBlock;
class DSLCase;
class DSLGlobalVar;
class DSLParameter;
template <typename T> class DSLWrapper;

}

class AutoDSLDepth;

/**
 * Consumes .sksl text and invokes DSL functions to instantiate the program.
 */
class DSLParser {
public:
    enum class LayoutToken {
        LOCATION,
        OFFSET,
        BINDING,
        INDEX,
        SET,
        BUILTIN,
        INPUT_ATTACHMENT_INDEX,
        ORIGIN_UPPER_LEFT,
        BLEND_SUPPORT_ALL_EQUATIONS,
        PUSH_CONSTANT,
        COLOR,
    };

    DSLParser(Compiler* compiler, const ProgramSettings& settings, ProgramKind kind,
              std::string text);

    std::unique_ptr<Program> program();

    SkSL::LoadedModule moduleInheritingFrom(SkSL::ParsedModule baseModule);

    std::string_view text(Token token);

    Position position(Token token);

private:
    static void InitLayoutMap();

    /**
     * Return the next token, including whitespace tokens, from the parse stream.
     */
    Token nextRawToken();

    /**
     * Return the next non-whitespace token from the parse stream.
     */
    Token nextToken();

    /**
     * Push a token back onto the parse stream, so that it is the next one read. Only a single level
     * of pushback is supported (that is, it is an error to call pushback() twice in a row without
     * an intervening nextToken()).
     */
    void pushback(Token t);

    /**
     * Returns the next non-whitespace token without consuming it from the stream.
     */
    Token peek();

    /**
     * Checks to see if the next token is of the specified type. If so, stores it in result (if
     * result is non-null) and returns true. Otherwise, pushes it back and returns false.
     */
    bool checkNext(Token::Kind kind, Token* result = nullptr);

    /**
     * Behaves like checkNext(TK_IDENTIFIER), but also verifies that identifier is not a builtin
     * type. If the token was actually a builtin type, false is returned (the next token is not
     * considered to be an identifier).
     */
    bool checkIdentifier(Token* result = nullptr);

    /**
     * Reads the next non-whitespace token and generates an error if it is not the expected type.
     * The 'expected' string is part of the error message, which reads:
     *
     * "expected <expected>, but found '<actual text>'"
     *
     * If 'result' is non-null, it is set to point to the token that was read.
     * Returns true if the read token was as expected, false otherwise.
     */
    bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
    bool expect(Token::Kind kind, std::string expected, Token* result = nullptr);

    /**
     * Behaves like expect(TK_IDENTIFIER), but also verifies that identifier is not a type.
     * If the token was actually a type, generates an error message of the form:
     *
     * "expected an identifier, but found type 'float2'"
     */
    bool expectIdentifier(Token* result);

    void error(Token token, std::string msg);
    void error(Position position, std::string msg);

    // Returns the range from `start` to the current parse position.
    Position rangeFrom(Position start);
    Position rangeFrom(Token start);

    // these functions parse individual grammar rules from the current parse position; you probably
    // don't need to call any of these outside of the parser. The function declarations in the .cpp
    // file have comments describing the grammar rules.

    void declarations();

    /**
     * Parses an expression representing an array size. Reports errors if the array size is not
     * valid (out of bounds, not a literal integer). Returns true if an expression was
     * successfully parsed, even if that array size is not actually valid. In the event of a true
     * return, outResult always contains a valid array size (even if the parsed array size was not
     * actually valid; invalid array sizes result in a 1 to avoid additional errors downstream).
     */
    bool arraySize(SKSL_INT* outResult);

    void directive();

    bool declaration();

    bool functionDeclarationEnd(Position start,
                                const dsl::DSLModifiers& modifiers,
                                dsl::DSLType type,
                                const Token& name);

    struct VarDeclarationsPrefix {
        Position fPosition;
        dsl::DSLModifiers fModifiers;
        dsl::DSLType fType = dsl::DSLType(dsl::kVoid_Type);
        Token fName;
    };

    bool varDeclarationsPrefix(VarDeclarationsPrefix* prefixData);

    dsl::DSLStatement varDeclarationsOrExpressionStatement();

    dsl::DSLStatement varDeclarations();

    std::optional<dsl::DSLType> structDeclaration();

    SkTArray<dsl::DSLGlobalVar> structVarDeclaration(Position start,
                                                     const dsl::DSLModifiers& modifiers);

    bool parseArrayDimensions(Position pos, dsl::DSLType* type);

    bool parseInitializer(Position pos, dsl::DSLExpression* initializer);

    void globalVarDeclarationEnd(Position position, const dsl::DSLModifiers& mods,
            dsl::DSLType baseType, Token name);

    dsl::DSLStatement localVarDeclarationEnd(Position position, const dsl::DSLModifiers& mods,
            dsl::DSLType baseType, Token name);

    std::optional<dsl::DSLWrapper<dsl::DSLParameter>> parameter(size_t paramIndex);

    int layoutInt();

    std::string_view layoutIdentifier();

    dsl::DSLLayout layout();

    dsl::DSLModifiers modifiers();

    dsl::DSLStatement statement();

    std::optional<dsl::DSLType> type(dsl::DSLModifiers* modifiers);

    bool interfaceBlock(const dsl::DSLModifiers& mods);

    dsl::DSLStatement ifStatement();

    dsl::DSLStatement doStatement();

    dsl::DSLStatement whileStatement();

    dsl::DSLStatement forStatement();

    std::optional<dsl::DSLCase> switchCase();

    dsl::DSLStatement switchStatement();

    dsl::DSLStatement returnStatement();

    dsl::DSLStatement breakStatement();

    dsl::DSLStatement continueStatement();

    dsl::DSLStatement discardStatement();

    std::optional<dsl::DSLBlock> block();

    dsl::DSLStatement expressionStatement();

    using BinaryParseFn = dsl::DSLExpression (DSLParser::*)();
    bool SK_WARN_UNUSED_RESULT operatorRight(AutoDSLDepth& depth, Operator::Kind op,
            BinaryParseFn rightFn, dsl::DSLExpression& result);

    dsl::DSLExpression expression();

    dsl::DSLExpression assignmentExpression();

    dsl::DSLExpression ternaryExpression();

    dsl::DSLExpression logicalOrExpression();

    dsl::DSLExpression logicalXorExpression();

    dsl::DSLExpression logicalAndExpression();

    dsl::DSLExpression bitwiseOrExpression();

    dsl::DSLExpression bitwiseXorExpression();

    dsl::DSLExpression bitwiseAndExpression();

    dsl::DSLExpression equalityExpression();

    dsl::DSLExpression relationalExpression();

    dsl::DSLExpression shiftExpression();

    dsl::DSLExpression additiveExpression();

    dsl::DSLExpression multiplicativeExpression();

    dsl::DSLExpression unaryExpression();

    dsl::DSLExpression postfixExpression();

    dsl::DSLExpression swizzle(Position pos, dsl::DSLExpression base,
            std::string_view swizzleMask, Position maskPos);

    dsl::DSLExpression call(Position pos, dsl::DSLExpression base, ExpressionArray args);

    dsl::DSLExpression suffix(dsl::DSLExpression base);

    dsl::DSLExpression term();

    bool intLiteral(SKSL_INT* dest);

    bool floatLiteral(SKSL_FLOAT* dest);

    bool boolLiteral(bool* dest);

    bool identifier(std::string_view* dest);

    class Checkpoint {
    public:
        Checkpoint(DSLParser* p) : fParser(p) {
            fPushbackCheckpoint = fParser->fPushback;
            fLexerCheckpoint = fParser->fLexer.getCheckpoint();
            fOldErrorReporter = &dsl::GetErrorReporter();
            fOldEncounteredFatalError = fParser->fEncounteredFatalError;
            SkASSERT(fOldErrorReporter);
            dsl::SetErrorReporter(&fErrorReporter);
        }

        ~Checkpoint() {
            SkASSERTF(!fOldErrorReporter,
                      "Checkpoint was not accepted or rewound before destruction");
        }

        void accept() {
            this->restoreErrorReporter();
            // Parser errors should have been fatal, but we can encounter other errors like type
            // mismatches despite accepting the parse. Forward those messages to the actual error
            // handler now.
            fErrorReporter.forwardErrors();
        }

        void rewind() {
            this->restoreErrorReporter();
            fParser->fPushback = fPushbackCheckpoint;
            fParser->fLexer.rewindToCheckpoint(fLexerCheckpoint);
            fParser->fEncounteredFatalError = fOldEncounteredFatalError;
        }

    private:
        class ForwardingErrorReporter : public ErrorReporter {
        public:
            void handleError(std::string_view msg, Position pos) override {
                fErrors.push_back({std::string(msg), pos});
            }

            void forwardErrors() {
                for (Error& error : fErrors) {
                    dsl::GetErrorReporter().error(error.fMsg.c_str(), error.fPos);
                }
            }

        private:
            struct Error {
                std::string fMsg;
                Position fPos;
            };

            SkTArray<Error> fErrors;
        };

        void restoreErrorReporter() {
            SkASSERT(fOldErrorReporter);
            fErrorReporter.reportPendingErrors(Position());
            dsl::SetErrorReporter(fOldErrorReporter);
            fOldErrorReporter = nullptr;
        }

        DSLParser* fParser;
        Token fPushbackCheckpoint;
        SkSL::Lexer::Checkpoint fLexerCheckpoint;
        ForwardingErrorReporter fErrorReporter;
        ErrorReporter* fOldErrorReporter;
        bool fOldEncounteredFatalError;
    };

    static SkTHashMap<std::string_view, LayoutToken>* sLayoutTokens;

    Compiler& fCompiler;
    ProgramSettings fSettings;
    ErrorReporter* fErrorReporter;
    bool fEncounteredFatalError;
    ProgramKind fKind;
    std::unique_ptr<std::string> fText;
    Lexer fLexer;
    // current parse depth, used to enforce a recursion limit to try to keep us from overflowing the
    // stack on pathological inputs
    int fDepth = 0;
    Token fPushback;

    friend class AutoDSLDepth;
    friend class HCodeGenerator;
};

}  // namespace SkSL

#endif
