// Copyright 2020 The Tint Authors.
//
// 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 SRC_TINT_RESOLVER_VALIDATOR_H_
#define SRC_TINT_RESOLVER_VALIDATOR_H_

#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#include "src/tint/ast/pipeline_stage.h"
#include "src/tint/program_builder.h"
#include "src/tint/resolver/sem_helper.h"
#include "src/tint/source.h"

// Forward declarations
namespace tint::ast {
class IndexAccessorExpression;
class BinaryExpression;
class BitcastExpression;
class CallExpression;
class CallStatement;
class CaseStatement;
class ForLoopStatement;
class Function;
class IdentifierExpression;
class LoopStatement;
class MemberAccessorExpression;
class ReturnStatement;
class SwitchStatement;
class UnaryOpExpression;
class Variable;
class WhileStatement;
}  // namespace tint::ast
namespace tint::sem {
class Array;
class Atomic;
class BlockStatement;
class Builtin;
class CaseStatement;
class ForLoopStatement;
class IfStatement;
class LoopStatement;
class Materialize;
class Statement;
class SwitchStatement;
class TypeConstructor;
class WhileStatement;
}  // namespace tint::sem

namespace tint::resolver {

/// Validation logic for various ast nodes. The validations in general should
/// be shallow and depend on the resolver to call on children. The validations
/// also assume that sem changes have already been made. The validation checks
/// should not alter the AST or SEM trees.
class Validator {
  public:
    /// The valid type storage layouts typedef
    using ValidTypeStorageLayouts = std::set<std::pair<const sem::Type*, ast::StorageClass>>;

    /// Constructor
    /// @param builder the program builder
    /// @param helper the SEM helper to validate with
    Validator(ProgramBuilder* builder, SemHelper& helper);
    ~Validator();

    /// Adds the given error message to the diagnostics
    /// @param msg the error message
    /// @param source the error source
    void AddError(const std::string& msg, const Source& source) const;

    /// Adds the given warning message to the diagnostics
    /// @param msg the warning message
    /// @param source the warning source
    void AddWarning(const std::string& msg, const Source& source) const;

    /// Adds the given note message to the diagnostics
    /// @param msg the note message
    /// @param source the note source
    void AddNote(const std::string& msg, const Source& source) const;

    /// @param type the given type
    /// @returns true if the given type is a plain type
    bool IsPlain(const sem::Type* type) const;

    /// @param type the given type
    /// @returns true if the given type is a fixed-footprint type
    bool IsFixedFootprint(const sem::Type* type) const;

    /// @param type the given type
    /// @returns true if the given type is storable
    bool IsStorable(const sem::Type* type) const;

    /// @param type the given type
    /// @returns true if the given type is host-shareable
    bool IsHostShareable(const sem::Type* type) const;

    /// Validates pipeline stages
    /// @param entry_points the entry points to the module
    /// @returns true on success, false otherwise.
    bool PipelineStages(const std::vector<sem::Function*>& entry_points) const;

    /// Validates aliases
    /// @param alias the alias to validate
    /// @returns true on success, false otherwise.
    bool Alias(const ast::Alias* alias) const;

    /// Validates the array
    /// @param arr the array to validate
    /// @param source the source of the array
    /// @returns true on success, false otherwise.
    bool Array(const sem::Array* arr, const Source& source) const;

    /// Validates an array stride attribute
    /// @param attr the stride attribute to validate
    /// @param el_size the element size
    /// @param el_align the element alignment
    /// @param source the source of the attribute
    /// @returns true on success, false otherwise
    bool ArrayStrideAttribute(const ast::StrideAttribute* attr,
                              uint32_t el_size,
                              uint32_t el_align,
                              const Source& source) const;

    /// Validates an atomic
    /// @param a the atomic ast node to validate
    /// @param s the atomic sem node
    /// @returns true on success, false otherwise.
    bool Atomic(const ast::Atomic* a, const sem::Atomic* s) const;

    /// Validates an atoic variable
    /// @param var the variable to validate
    /// @param atomic_composite_info store atomic information
    /// @returns true on success, false otherwise.
    bool AtomicVariable(
        const sem::Variable* var,
        std::unordered_map<const sem::Type*, const Source&> atomic_composite_info) const;

    /// Validates an assignment
    /// @param a the assignment statement
    /// @param rhs_ty the type of the right hand side
    /// @returns true on success, false otherwise.
    bool Assignment(const ast::Statement* a, const sem::Type* rhs_ty) const;

    /// Validates a bitcase
    /// @param cast the bitcast expression
    /// @param to the destination type
    /// @returns true on success, false otherwise
    bool Bitcast(const ast::BitcastExpression* cast, const sem::Type* to) const;

    /// Validates a break statement
    /// @param stmt the break statement to validate
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise.
    bool BreakStatement(const sem::Statement* stmt, sem::Statement* current_statement) const;

    /// Validates a builtin attribute
    /// @param attr the attribute to validate
    /// @param storage_type the attribute storage type
    /// @param stage the current pipeline stage
    /// @param is_input true if this is an input attribute
    /// @returns true on success, false otherwise.
    bool BuiltinAttribute(const ast::BuiltinAttribute* attr,
                          const sem::Type* storage_type,
                          ast::PipelineStage stage,
                          const bool is_input) const;

    /// Validates a continue statement
    /// @param stmt the continue statement to validate
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool ContinueStatement(const sem::Statement* stmt, sem::Statement* current_statement) const;

    /// Validates a call
    /// @param call the call
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool Call(const sem::Call* call, sem::Statement* current_statement) const;

    /// Validates a discard statement
    /// @param stmt the statement to validate
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool DiscardStatement(const sem::Statement* stmt, sem::Statement* current_statement) const;

    /// Validates an entry point
    /// @param func the entry point function to validate
    /// @param stage the pipeline stage for the entry point
    /// @returns true on success, false otherwise
    bool EntryPoint(const sem::Function* func, ast::PipelineStage stage) const;

    /// Validates a for loop
    /// @param stmt the for loop statement to validate
    /// @returns true on success, false otherwise
    bool ForLoopStatement(const sem::ForLoopStatement* stmt) const;

    /// Validates a while loop
    /// @param stmt the while statement to validate
    /// @returns true on success, false otherwise
    bool WhileStatement(const sem::WhileStatement* stmt) const;

    /// Validates a fallthrough statement
    /// @param stmt the fallthrough to validate
    /// @returns true on success, false otherwise
    bool FallthroughStatement(const sem::Statement* stmt) const;

    /// Validates a function
    /// @param func the function to validate
    /// @param stage the current pipeline stage
    /// @returns true on success, false otherwise.
    bool Function(const sem::Function* func, ast::PipelineStage stage) const;

    /// Validates a function call
    /// @param call the function call to validate
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool FunctionCall(const sem::Call* call, sem::Statement* current_statement) const;

    /// Validates a global variable
    /// @param var the global variable to validate
    /// @param constant_ids the set of constant ids in the module
    /// @param atomic_composite_info atomic composite info in the module
    /// @returns true on success, false otherwise
    bool GlobalVariable(
        const sem::GlobalVariable* var,
        std::unordered_map<uint32_t, const sem::Variable*> constant_ids,
        std::unordered_map<const sem::Type*, const Source&> atomic_composite_info) const;

    /// Validates an if statement
    /// @param stmt the statement to validate
    /// @returns true on success, false otherwise
    bool IfStatement(const sem::IfStatement* stmt) const;

    /// Validates an increment or decrement statement
    /// @param stmt the statement to validate
    /// @returns true on success, false otherwise
    bool IncrementDecrementStatement(const ast::IncrementDecrementStatement* stmt) const;

    /// Validates an interpolate attribute
    /// @param attr the interpolation attribute to validate
    /// @param storage_type the storage type of the attached variable
    /// @returns true on succes, false otherwise
    bool InterpolateAttribute(const ast::InterpolateAttribute* attr,
                              const sem::Type* storage_type) const;

    /// Validates a builtin call
    /// @param call the builtin call to validate
    /// @returns true on success, false otherwise.
    bool BuiltinCall(const sem::Call* call) const;

    /// Validates a location attribute
    /// @param location the location attribute to validate
    /// @param type the variable type
    /// @param locations the set of locations in the module
    /// @param stage the current pipeline stage
    /// @param source the source of the attribute
    /// @param is_input true if this is an input variable
    /// @returns true on success, false otherwise.
    bool LocationAttribute(const ast::LocationAttribute* location,
                           const sem::Type* type,
                           std::unordered_set<uint32_t>& locations,
                           ast::PipelineStage stage,
                           const Source& source,
                           const bool is_input = false) const;

    /// Validates a loop statement
    /// @param stmt the loop statement
    /// @returns true on success, false otherwise.
    bool LoopStatement(const sem::LoopStatement* stmt) const;

    /// Validates a materialize of an abstract numeric value
    /// @param m the materialize to validate
    /// @returns true on success, false otherwise
    bool Materialize(const sem::Materialize* m) const;

    /// Validates a matrix
    /// @param ty the matrix to validate
    /// @param source the source of the matrix
    /// @returns true on success, false otherwise
    bool Matrix(const sem::Matrix* ty, const Source& source) const;

    /// Validates a function parameter
    /// @param func the function the variable is for
    /// @param var the variable to validate
    /// @returns true on success, false otherwise
    bool Parameter(const ast::Function* func, const sem::Variable* var) const;

    /// Validates a return
    /// @param ret the return statement to validate
    /// @param func_type the return type of the curreunt function
    /// @param ret_type the return type
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool Return(const ast::ReturnStatement* ret,
                const sem::Type* func_type,
                const sem::Type* ret_type,
                sem::Statement* current_statement) const;

    /// Validates a list of statements
    /// @param stmts the statements to validate
    /// @returns true on success, false otherwise
    bool Statements(const ast::StatementList& stmts) const;

    /// Validates a storage texture
    /// @param t the texture to validate
    /// @returns true on success, false otherwise
    bool StorageTexture(const ast::StorageTexture* t) const;

    /// Validates a sampled texture
    /// @param t the texture to validate
    /// @param source the source of the texture
    /// @returns true on success, false otherwise
    bool SampledTexture(const sem::SampledTexture* t, const Source& source) const;

    /// Validates a multisampled texture
    /// @param t the texture to validate
    /// @param source the source of the texture
    /// @returns true on success, false otherwise
    bool MultisampledTexture(const sem::MultisampledTexture* t, const Source& source) const;

    /// Validates a structure
    /// @param str the structure to validate
    /// @param stage the current pipeline stage
    /// @returns true on success, false otherwise.
    bool Structure(const sem::Struct* str, ast::PipelineStage stage) const;

    /// Validates a structure constructor
    /// @param ctor the call expression to validate
    /// @param struct_type the type of the structure
    /// @returns true on success, false otherwise
    bool StructureConstructor(const ast::CallExpression* ctor,
                              const sem::Struct* struct_type) const;

    /// Validates a switch statement
    /// @param s the switch to validate
    /// @returns true on success, false otherwise
    bool SwitchStatement(const ast::SwitchStatement* s);

    /// Validates a variable
    /// @param var the variable to validate
    /// @returns true on success, false otherwise.
    bool Variable(const sem::Variable* var) const;

    /// Validates a variable constructor or cast
    /// @param v the variable to validate
    /// @param storage_class the storage class of the variable
    /// @param storage_type the type of the storage
    /// @param rhs_type the right hand side of the expression
    /// @returns true on succes, false otherwise
    bool VariableConstructorOrCast(const ast::Variable* v,
                                   ast::StorageClass storage_class,
                                   const sem::Type* storage_type,
                                   const sem::Type* rhs_type) const;

    /// Validates a vector
    /// @param ty the vector to validate
    /// @param source the source of the vector
    /// @returns true on success, false otherwise
    bool Vector(const sem::Vector* ty, const Source& source) const;

    /// Validates an array constructor
    /// @param ctor the call expresion to validate
    /// @param arr_type the type of the array
    /// @returns true on success, false otherwise
    bool ArrayConstructor(const ast::CallExpression* ctor, const sem::Array* arr_type) const;

    /// Validates a texture builtin function
    /// @param call the builtin call to validate
    /// @returns true on success, false otherwise
    bool TextureBuiltinFunction(const sem::Call* call) const;

    /// Validates an optional builtin function and its required extension.
    /// @param call the builtin call to validate
    /// @param enabled_extensions all the extensions declared in current module
    /// @returns true on success, false otherwise
    bool RequiredExtensionForBuiltinFunction(const sem::Call* call,
                                             const ast::Extensions& enabled_extensions) const;

    /// Validates there are no duplicate attributes
    /// @param attributes the list of attributes to validate
    /// @returns true on success, false otherwise.
    bool NoDuplicateAttributes(const ast::AttributeList& attributes) const;

    /// Validates a storage class layout
    /// @param type the type to validate
    /// @param sc the storage class
    /// @param source the source of the type
    /// @param layouts previously validated storage layouts
    /// @returns true on success, false otherwise
    bool StorageClassLayout(const sem::Type* type,
                            ast::StorageClass sc,
                            Source source,
                            ValidTypeStorageLayouts& layouts) const;

    /// Validates a storage class layout
    /// @param var the variable to validate
    /// @param layouts previously validated storage layouts
    /// @returns true on success, false otherwise.
    bool StorageClassLayout(const sem::Variable* var, ValidTypeStorageLayouts& layouts) const;

    /// @returns true if the attribute list contains a
    /// ast::DisableValidationAttribute with the validation mode equal to
    /// `validation`
    /// @param attributes the attribute list to check
    /// @param validation the validation mode to check
    bool IsValidationDisabled(const ast::AttributeList& attributes,
                              ast::DisabledValidation validation) const;

    /// @returns true if the attribute list does not contains a
    /// ast::DisableValidationAttribute with the validation mode equal to
    /// `validation`
    /// @param attributes the attribute list to check
    /// @param validation the validation mode to check
    bool IsValidationEnabled(const ast::AttributeList& attributes,
                             ast::DisabledValidation validation) const;

  private:
    /// Searches the current statement and up through parents of the current
    /// statement looking for a loop or for-loop continuing statement.
    /// @returns the closest continuing statement to the current statement that
    /// (transitively) owns the current statement.
    /// @param stop_at_loop if true then the function will return nullptr if a
    /// loop or for-loop was found before the continuing.
    /// @param current_statement the current statement being resolved
    const ast::Statement* ClosestContinuing(bool stop_at_loop,
                                            sem::Statement* current_statement) const;

    /// Returns a human-readable string representation of the vector type name
    /// with the given parameters.
    /// @param size the vector dimension
    /// @param element_type scalar vector sub-element type
    /// @return pretty string representation
    std::string VectorPretty(uint32_t size, const sem::Type* element_type) const;

    SymbolTable& symbols_;
    diag::List& diagnostics_;
    SemHelper& sem_;
};

}  // namespace tint::resolver

#endif  // SRC_TINT_RESOLVER_VALIDATOR_H_
