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

#ifndef SKSL_REHYDRATOR
#define SKSL_REHYDRATOR

#include "include/core/SkTypes.h"
#include "include/private/SkSLDefines.h"
#include "include/private/SkSLLayout.h"
#include "include/private/SkSLModifiers.h"
#include "src/sksl/SkSLContext.h"
#include "src/sksl/ir/SkSLSymbolTable.h"

#include <cstddef>
#include <cstdint>
#include <memory>
#include <string_view>
#include <string>
#include <vector>

namespace SkSL {

class Compiler;
class ErrorReporter;
class Expression;
class ModifiersPool;
class ProgramElement;
class Statement;
class Symbol;
class Type;
struct Program;

/**
 * Interprets a simple bytecode format that encodes the structure of an SkSL IR tree. This is used
 * to process the .sksl files representing SkSL's core include files, so that they can be quickly
 * reconstituted at runtime.
 */
class Rehydrator {
public:
    static constexpr uint16_t kVersion = 14;

    // see binary_format.md for a description of the command data
    enum Command {
        kArrayType_Command,
        kBinary_Command,
        kBlock_Command,
        kBoolLiteral_Command,
        kBreak_Command,
        kBuiltinLayout_Command,
        kConstructorArray_Command,
        kConstructorArrayCast_Command,
        kConstructorCompound_Command,
        kConstructorCompoundCast_Command,
        kConstructorDiagonalMatrix_Command,
        kConstructorMatrixResize_Command,
        kConstructorScalarCast_Command,
        kConstructorSplat_Command,
        kConstructorStruct_Command,
        kContinue_Command,
        kDefaultLayout_Command,
        kDefaultModifiers_Command,
        kDiscard_Command,
        kDo_Command,
        kElements_Command,
        kElementsComplete_Command,
        kExpressionStatement_Command,
        kField_Command,
        kFieldAccess_Command,
        kFloatLiteral_Command,
        kFor_Command,
        kFunctionCall_Command,
        kFunctionDeclaration_Command,
        kFunctionDefinition_Command,
        kFunctionPrototype_Command,
        kGlobalVar_Command,
        kIf_Command,
        kIndex_Command,
        kUnused_Command,  // was kInlineMarker_Command
        kInterfaceBlock_Command,
        kIntLiteral_Command,
        kLayout_Command,
        kModifiers8Bit_Command,
        kModifiers_Command,
        kNop_Command,
        kPostfix_Command,
        kPrefix_Command,
        kProgram_Command,
        kReturn_Command,
        kSetting_Command,
        kSharedFunction_Command,
        kStructDefinition_Command,
        kStructType_Command,
        kSwitch_Command,
        kSwizzle_Command,
        kSymbolRef_Command,
        kSymbolTable_Command,
        kTernary_Command,
        kVariable_Command,
        kVarDeclaration_Command,
        kVariableReference_Command,
        kVoid_Command,
    };

    // src must remain in memory as long as the objects created from it do
    Rehydrator(Compiler& compiler, const uint8_t* src, size_t length);

    Rehydrator(Compiler& compiler, const uint8_t* src, size_t length,
               std::shared_ptr<SymbolTable> base);

#ifdef SK_DEBUG
    ~Rehydrator();
#endif

    // Reads a symbol table and makes it current (inheriting from the previous current table)
    std::shared_ptr<SymbolTable> symbolTable();

    // Reads a collection of program elements and returns it
    std::vector<std::unique_ptr<ProgramElement>> elements();

    // Reads an entire program.
    //
    // NOTE: The program is initialized using a new ProgramConfig that may differ from the one that
    // was assigned to the context of the Compiler this Rehydrator was constructed with.
    std::unique_ptr<Program> program();

private:
    // If this ID appears in place of a symbol ID, it means the corresponding symbol isn't actually
    // present in the file as it's a builtin. The string name of the symbol follows.
    static constexpr uint16_t kBuiltin_Symbol = 65535;

    int8_t readS8() {
        SkASSERT(fIP < fEnd);
        return *(fIP++);
    }

    uint8_t readU8() {
        return this->readS8();
    }

    int16_t readS16() {
        uint8_t b1 = this->readU8();
        uint8_t b2 = this->readU8();
        return (b2 << 8) + b1;
    }

    uint16_t readU16() {
        return this->readS16();
    }

    int32_t readS32() {
        uint8_t b1 = this->readU8();
        uint8_t b2 = this->readU8();
        uint8_t b3 = this->readU8();
        uint8_t b4 = this->readU8();
        return (b4 << 24) + (b3 << 16) + (b2 << 8) + b1;
    }

    uint32_t readU32() {
        return this->readS32();
    }

    std::string_view readString() {
        uint16_t offset = this->readU16();
        uint8_t length = *(uint8_t*) (fStringStart + offset);
        const char* chars = (const char*) fStringStart + offset + 1;
        return std::string_view(chars, length);
    }

    void addSymbol(int id, Symbol* symbol) {
        while ((size_t) id >= fSymbols.size()) {
            fSymbols.push_back(nullptr);
        }
        fSymbols[id] = symbol;
    }

    template<typename T>
    T* symbolRef() {
        uint16_t result = this->readU16();
        SkASSERTF(result != kBuiltin_Symbol, "use possiblyBuiltinSymbolRef() instead");
        SkASSERT(fSymbols.size() > result);
        return static_cast<T*>(fSymbols[result]);
    }

    /**
     * Reads either a symbol belonging to this program, or a named reference to a builtin symbol.
     * This has to be a separate method from symbolRef() because builtin symbols can be const, and
     * thus this method must have a const return, but there is at least one case in which we
     * specifically require a non-const return value.
     */
    const Symbol* possiblyBuiltinSymbolRef() {
        uint16_t id = this->readU16();
        if (id == kBuiltin_Symbol) {
            std::string_view name = this->readString();
            const Symbol* result = (*fSymbolTable)[name];
            SkASSERTF(result, "symbol '%s' not found", std::string(name).c_str());
            return result;
        }
        SkASSERT(fSymbols.size() > id);
        return fSymbols[id];
    }

    Layout layout();

    Modifiers modifiers();

    Symbol* symbol();

    std::unique_ptr<ProgramElement> element();

    std::unique_ptr<Statement> statement();

    std::unique_ptr<Expression> expression();

    ExpressionArray expressionArray();

    const Type* type();

    Context& context() const;

    ErrorReporter* errorReporter() const { return this->context().fErrors; }

    ModifiersPool& modifiersPool() const { return *this->context().fModifiersPool; }

    Compiler& fCompiler;
    std::shared_ptr<SymbolTable> fSymbolTable;
    std::vector<Symbol*> fSymbols;

    const uint8_t* fStringStart;
    const uint8_t* fIP;
    SkDEBUGCODE(const uint8_t* fEnd;)

    friend class AutoRehydratorSymbolTable;
    friend class Dehydrator;
};

}  // namespace SkSL

#endif
