// 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 <utility>

#include "src/tint/ast/pipeline_stage.h"
#include "src/tint/program_builder.h"
#include "src/tint/resolver/sem_helper.h"
#include "src/tint/sem/evaluation_stage.h"
#include "src/tint/source.h"
#include "src/tint/utils/hash.h"
#include "src/tint/utils/hashmap.h"
#include "src/tint/utils/vector.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 BlockStatement;
class BreakIfStatement;
class Builtin;
class Call;
class CaseStatement;
class ForLoopStatement;
class IfStatement;
class LoopStatement;
class Materialize;
class Statement;
class SwitchStatement;
class TypeInitializer;
class WhileStatement;
}  // namespace tint::sem
namespace tint::type {
class Atomic;
}  // namespace tint::type

namespace tint::resolver {

/// TypeAndAddressSpace is a pair of type and address space
struct TypeAndAddressSpace {
    /// The type
    const type::Type* type;
    /// The address space
    ast::AddressSpace address_space;

    /// Equality operator
    /// @param other the other TypeAndAddressSpace to compare this TypeAndAddressSpace to
    /// @returns true if the type and address space of this TypeAndAddressSpace is equal to @p other
    bool operator==(const TypeAndAddressSpace& other) const {
        return type == other.type && address_space == other.address_space;
    }
};

/// 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:
    /// Constructor
    /// @param builder the program builder
    /// @param helper the SEM helper to validate with
    /// @param enabled_extensions all the extensions declared in current module
    /// @param atomic_composite_info atomic composite info of the module
    /// @param valid_type_storage_layouts a set of validated type layouts by address space
    Validator(ProgramBuilder* builder,
              SemHelper& helper,
              const ast::Extensions& enabled_extensions,
              const utils::Hashmap<const type::Type*, const Source*, 8>& atomic_composite_info,
              utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts);
    ~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 type::Type* type) const;

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

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

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

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

    /// Validates push_constant variables
    /// @param entry_points the entry points to the module
    /// @returns true on success, false otherwise.
    bool PushConstants(utils::VectorRef<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 el_source the source of the array element, or the array if the array does not have a
    ///        locally-declared element AST node.
    /// @returns true on success, false otherwise.
    bool Array(const type::Array* arr, const Source& el_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
    /// @returns true on success, false otherwise
    bool ArrayStrideAttribute(const ast::StrideAttribute* attr,
                              uint32_t el_size,
                              uint32_t el_align) const;

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

    /// Validates a pointer type
    /// @param a the pointer ast node
    /// @param s the pointer sem node
    /// @returns true on success, false otherwise.
    bool Pointer(const ast::Pointer* a, const type::Pointer* s) 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 type::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 type::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 type::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 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 that the expression must not be evaluated any later than @p latest_stage
    /// @param expr the expression to check
    /// @param latest_stage the latest evaluation stage that the expression can be evaluated
    /// @param constraint the 'thing' that is imposing the contraint. e.g. "var declaration"
    /// @returns true if @p expr is evaluated in or before @p latest_stage, false otherwise
    bool EvaluationStage(const sem::Expression* expr,
                         sem::EvaluationStage latest_stage,
                         std::string_view constraint) 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 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 override_id the set of override ids in the module
    /// @returns true on success, false otherwise
    bool GlobalVariable(
        const sem::GlobalVariable* var,
        const utils::Hashmap<OverrideId, const sem::Variable*, 8>& override_id) const;

    /// Validates a break-if statement
    /// @param stmt the statement to validate
    /// @param current_statement the current statement being resolved
    /// @returns true on success, false otherwise
    bool BreakIfStatement(const sem::BreakIfStatement* stmt,
                          sem::Statement* current_statement) 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 type::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 local variable
    /// @param v the variable to validate
    /// @returns true on success, false otherwise.
    bool LocalVariable(const sem::Variable* v) const;

    /// Validates a location attribute
    /// @param loc_attr the location attribute to validate
    /// @param location the location value
    /// @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* loc_attr,
                           uint32_t location,
                           const type::Type* type,
                           utils::Hashset<uint32_t, 8>& 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 from the type `from` to the type `to`.
    /// @param to the target type
    /// @param from the abstract numeric type
    /// @param source the source of the materialization
    /// @returns true on success, false otherwise
    bool Materialize(const type::Type* to, const type::Type* from, const Source& source) 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 type::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 type::Type* func_type,
                const type::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(utils::VectorRef<const ast::Statement*> 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 type::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 type::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 initializer
    /// @param ctor the call expression to validate
    /// @param struct_type the type of the structure
    /// @returns true on success, false otherwise
    bool StructureInitializer(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 'var' variable declaration
    /// @param v the variable to validate
    /// @returns true on success, false otherwise.
    bool Var(const sem::Variable* v) const;

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

    /// Validates a 'override' variable declaration
    /// @param v the variable to validate
    /// @param override_id the set of override ids in the module
    /// @returns true on success, false otherwise.
    bool Override(const sem::GlobalVariable* v,
                  const utils::Hashmap<OverrideId, const sem::Variable*, 8>& override_id) const;

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

    /// Validates a variable initializer
    /// @param v the variable to validate
    /// @param address_space the address space of the variable
    /// @param storage_type the type of the storage
    /// @param initializer the RHS initializer expression
    /// @returns true on succes, false otherwise
    bool VariableInitializer(const ast::Variable* v,
                             ast::AddressSpace address_space,
                             const type::Type* storage_type,
                             const sem::Expression* initializer) 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 type::Vector* ty, const Source& source) const;

    /// Validates an array initializer
    /// @param ctor the call expresion to validate
    /// @param arr_type the type of the array
    /// @returns true on success, false otherwise
    bool ArrayInitializer(const ast::CallExpression* ctor, const type::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
    /// @returns true on success, false otherwise
    bool RequiredExtensionForBuiltinFunction(const sem::Call* call) const;

    /// Validates there are no duplicate attributes
    /// @param attributes the list of attributes to validate
    /// @returns true on success, false otherwise.
    bool NoDuplicateAttributes(utils::VectorRef<const ast::Attribute*> attributes) const;

    /// Validates a address space layout
    /// @param type the type to validate
    /// @param sc the address space
    /// @param source the source of the type
    /// @returns true on success, false otherwise
    bool AddressSpaceLayout(const type::Type* type, ast::AddressSpace sc, Source source) 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(utils::VectorRef<const ast::Attribute*> 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(utils::VectorRef<const ast::Attribute*> attributes,
                             ast::DisabledValidation validation) const;

  private:
    /// @param ty the type to check
    /// @returns true if @p ty is an array with an `override` expression element count, otherwise
    ///          false.
    bool IsArrayWithOverrideCount(const type::Type* ty) const;

    /// Raises an error about an array type using an `override` expression element count, outside
    /// the single allowed use of a `var<workgroup>`.
    /// @param source the source for the error
    void RaiseArrayWithOverrideCountError(const Source& source) const;

    /// 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 type::Type* element_type) const;

    /// Raises an error if combination of @p store_ty, @p access and @p address_space are not valid
    /// for a `var` or `ptr` declaration.
    /// @param store_ty the store type of the var or pointer
    /// @param access the var or pointer access
    /// @param address_space the var or pointer address space
    /// @param source the source for the error
    /// @returns true on success, false if an error was raised.
    bool CheckTypeAccessAddressSpace(const type::Type* store_ty,
                                     ast::Access access,
                                     ast::AddressSpace address_space,
                                     utils::VectorRef<const tint::ast::Attribute*> attributes,
                                     const Source& source) const;
    SymbolTable& symbols_;
    diag::List& diagnostics_;
    SemHelper& sem_;
    const ast::Extensions& enabled_extensions_;
    const utils::Hashmap<const type::Type*, const Source*, 8>& atomic_composite_info_;
    utils::Hashset<TypeAndAddressSpace, 8>& valid_type_storage_layouts_;
};

}  // namespace tint::resolver

namespace std {

/// Custom std::hash specialization for tint::resolver::TypeAndAddressSpace.
template <>
class hash<tint::resolver::TypeAndAddressSpace> {
  public:
    /// @param tas the TypeAndAddressSpace
    /// @return the hash value
    inline std::size_t operator()(const tint::resolver::TypeAndAddressSpace& tas) const {
        return tint::utils::Hash(tas.type, tas.address_space);
    }
};

}  // namespace std

#endif  // SRC_TINT_RESOLVER_VALIDATOR_H_
