// 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_READER_WGSL_PARSER_IMPL_H_
#define SRC_READER_WGSL_PARSER_IMPL_H_

#include <cassert>
#include <deque>
#include <memory>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>

#include "src/ast/access_control.h"
#include "src/ast/array_decoration.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/break_statement.h"
#include "src/ast/builtin.h"
#include "src/ast/call_statement.h"
#include "src/ast/case_statement.h"
#include "src/ast/constructor_expression.h"
#include "src/ast/continue_statement.h"
#include "src/ast/else_statement.h"
#include "src/ast/function.h"
#include "src/ast/if_statement.h"
#include "src/ast/literal.h"
#include "src/ast/loop_statement.h"
#include "src/ast/module.h"
#include "src/ast/pipeline_stage.h"
#include "src/ast/return_statement.h"
#include "src/ast/statement.h"
#include "src/ast/storage_class.h"
#include "src/ast/struct.h"
#include "src/ast/struct_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_decoration.h"
#include "src/ast/switch_statement.h"
#include "src/ast/type/storage_texture_type.h"
#include "src/ast/type/struct_type.h"
#include "src/ast/type/texture_type.h"
#include "src/ast/type/type.h"
#include "src/ast/variable.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/variable_decoration.h"
#include "src/diagnostic/diagnostic.h"
#include "src/diagnostic/formatter.h"
#include "src/reader/wgsl/parser_impl_detail.h"
#include "src/reader/wgsl/token.h"

namespace tint {
namespace reader {
namespace wgsl {

class Lexer;

/// Struct holding information for a for loop
struct ForHeader {
  /// Constructor
  /// @param init the initializer statement
  /// @param cond the condition statement
  /// @param cont the continuing statement
  ForHeader(ast::Statement* init, ast::Expression* cond, ast::Statement* cont);

  ~ForHeader();

  /// The for loop initializer
  ast::Statement* initializer = nullptr;
  /// The for loop condition
  ast::Expression* condition = nullptr;
  /// The for loop continuing statement
  ast::Statement* continuing = nullptr;
};

/// ParserImpl for WGSL source data
class ParserImpl {
  /// Failure holds enumerator values used for the constructing an Expect and
  /// Match in an errored state.
  struct Failure {
    enum Errored { kErrored };
    enum NoMatch { kNoMatch };
  };

 public:
  /// Expect is the return type of the parser methods that are expected to
  /// return a parsed value of type T, unless there was an parse error.
  /// In the case of a parse error the called method will have called
  /// add_error() and #errored will be set to true.
  template <typename T>
  struct Expect {
    /// An alias to the templated type T.
    using type = T;

    /// Don't allow an Expect to take a nullptr.
    inline Expect(std::nullptr_t) = delete;  // NOLINT

    /// Constructor for a successful parse.
    /// @param val the result value of the parse
    /// @param s the optional source of the value
    template <typename U>
    inline Expect(U&& val, const Source& s = {})  // NOLINT
        : value(std::forward<U>(val)), source(s) {}

    /// Constructor for parse error.
    inline Expect(Failure::Errored) : errored(true) {}  // NOLINT

    /// Copy constructor
    inline Expect(const Expect&) = default;
    /// Move constructor
    inline Expect(Expect&&) = default;
    /// Assignment operator
    /// @return this Expect
    inline Expect& operator=(const Expect&) = default;
    /// Assignment move operator
    /// @return this Expect
    inline Expect& operator=(Expect&&) = default;

    /// @return a pointer to the returned value. If T is a pointer or
    /// std::unique_ptr, operator->() automatically dereferences so that the
    /// return type will always be a pointer to a non-pointer type. #errored
    /// must be false to call.
    inline typename detail::OperatorArrow<T>::type operator->() {
      assert(!errored);
      return detail::OperatorArrow<T>::ptr(value);
    }

    /// The expected value of a successful parse.
    /// Zero-initialized when there was a parse error.
    T value{};
    /// Optional source of the value.
    Source source;
    /// True if there was a error parsing.
    bool errored = false;
  };

  /// Maybe is the return type of the parser methods that attempts to match a
  /// grammar and return a parsed value of type T, or may parse part of the
  /// grammar and then hit a parse error.
  /// In the case of a successful grammar match, the Maybe will have #matched
  /// set to true.
  /// In the case of a parse error the called method will have called
  /// add_error() and the Maybe will have #errored set to true.
  template <typename T>
  struct Maybe {
    inline Maybe(std::nullptr_t) = delete;  // NOLINT

    /// Constructor for a successful parse.
    /// @param val the result value of the parse
    /// @param s the optional source of the value
    template <typename U>
    inline Maybe(U&& val, const Source& s = {})  // NOLINT
        : value(std::forward<U>(val)), source(s), matched(true) {}

    /// Constructor for parse error state.
    inline Maybe(Failure::Errored) : errored(true) {}  // NOLINT

    /// Constructor for the no-match state.
    inline Maybe(Failure::NoMatch) {}  // NOLINT

    /// Constructor from an Expect.
    /// @param e the Expect to copy this Maybe from
    template <typename U>
    inline Maybe(const Expect<U>& e)  // NOLINT
        : value(e.value),
          source(e.value),
          errored(e.errored),
          matched(!e.errored) {}

    /// Move from an Expect.
    /// @param e the Expect to move this Maybe from
    template <typename U>
    inline Maybe(Expect<U>&& e)  // NOLINT
        : value(std::move(e.value)),
          source(std::move(e.source)),
          errored(e.errored),
          matched(!e.errored) {}

    /// Copy constructor
    inline Maybe(const Maybe&) = default;
    /// Move constructor
    inline Maybe(Maybe&&) = default;
    /// Assignment operator
    /// @return this Maybe
    inline Maybe& operator=(const Maybe&) = default;
    /// Assignment move operator
    /// @return this Maybe
    inline Maybe& operator=(Maybe&&) = default;

    /// @return a pointer to the returned value. If T is a pointer or
    /// std::unique_ptr, operator->() automatically dereferences so that the
    /// return type will always be a pointer to a non-pointer type. #errored
    /// must be false to call.
    inline typename detail::OperatorArrow<T>::type operator->() {
      assert(!errored);
      return detail::OperatorArrow<T>::ptr(value);
    }

    /// The value of a successful parse.
    /// Zero-initialized when there was a parse error.
    T value{};
    /// Optional source of the value.
    Source source;
    /// True if there was a error parsing.
    bool errored = false;
    /// True if there was a error parsing.
    bool matched = false;
  };

  /// TypedIdentifier holds a parsed identifier and type. Returned by
  /// variable_ident_decl().
  struct TypedIdentifier {
    /// Parsed type.
    ast::type::Type* type = nullptr;
    /// Parsed identifier.
    std::string name;
    /// Source to the identifier.
    Source source;
  };

  /// FunctionHeader contains the parsed information for a function header.
  struct FunctionHeader {
    /// Constructor
    FunctionHeader();
    /// Copy constructor
    /// @param other the FunctionHeader to copy
    FunctionHeader(const FunctionHeader& other);
    /// Constructor
    /// @param src parsed header source
    /// @param n function name
    /// @param p function parameters
    /// @param ret_ty function return type
    FunctionHeader(Source src,
                   std::string n,
                   ast::VariableList p,
                   ast::type::Type* ret_ty);
    /// Destructor
    ~FunctionHeader();
    /// Assignment operator
    /// @param other the FunctionHeader to copy
    /// @returns this FunctionHeader
    FunctionHeader& operator=(const FunctionHeader& other);

    /// Parsed header source
    Source source;
    /// Function name
    std::string name;
    /// Function parameters
    ast::VariableList params;
    /// Function return type
    ast::type::Type* return_type;
  };

  /// VarDeclInfo contains the parsed information for variable declaration.
  struct VarDeclInfo {
    /// Variable declaration source
    Source source;
    /// Variable name
    std::string name;
    /// Variable storage class
    ast::StorageClass storage_class;
    /// Variable type
    ast::type::Type* type;
  };

  /// Creates a new parser using the given file
  /// @param file the input source file to parse
  explicit ParserImpl(Source::File const* file);
  ~ParserImpl();

  /// Run the parser
  /// @returns true if the parse was successful, false otherwise.
  bool Parse();

  /// set_max_diagnostics sets the maximum number of reported errors before
  /// aborting parsing.
  /// @param limit the new maximum number of errors
  void set_max_errors(size_t limit) { max_errors_ = limit; }

  /// @return the number of maximum number of reported errors before aborting
  /// parsing.
  size_t get_max_errors() const { return max_errors_; }

  /// @returns true if an error was encountered.
  bool has_error() const { return diags_.contains_errors(); }

  /// @returns the parser error string
  std::string error() const {
    diag::Formatter formatter{{false, false, false, false}};
    return formatter.format(diags_);
  }

  /// @returns the diagnostic messages
  const diag::List& diagnostics() const { return diags_; }

  /// @returns the diagnostic messages
  diag::List& diagnostics() { return diags_; }

  /// @returns the module. The module in the parser will be reset after this.
  ast::Module module() { return std::move(module_); }

  /// @returns a pointer to the module, without resetting it.
  ast::Module& get_module() { return module_; }

  /// @returns the next token
  Token next();
  /// @returns the next token without advancing
  Token peek();
  /// Peeks ahead and returns the token at `idx` head of the current position
  /// @param idx the index of the token to return
  /// @returns the token `idx` positions ahead without advancing
  Token peek(size_t idx);
  /// Appends an error at `t` with the message `msg`
  /// @param t the token to associate the error with
  /// @param msg the error message
  /// @return `Failure::Errored::kError` so that you can combine an add_error()
  /// call and return on the same line.
  Failure::Errored add_error(const Token& t, const std::string& msg);
  /// Appends an error raised when parsing `use` at `t` with the message
  /// `msg`
  /// @param source the source to associate the error with
  /// @param msg the error message
  /// @param use a description of what was being parsed when the error was
  /// raised.
  /// @return `Failure::Errored::kError` so that you can combine an add_error()
  /// call and return on the same line.
  Failure::Errored add_error(const Source& source,
                             const std::string& msg,
                             const std::string& use);
  /// Appends an error at `source` with the message `msg`
  /// @param source the source to associate the error with
  /// @param msg the error message
  /// @return `Failure::Errored::kError` so that you can combine an add_error()
  /// call and return on the same line.
  Failure::Errored add_error(const Source& source, const std::string& msg);

  /// Registers a constructed type into the parser
  /// @param name the constructed name
  /// @param type the constructed type
  void register_constructed(const std::string& name, ast::type::Type* type);
  /// Retrieves a constructed type
  /// @param name The name to lookup
  /// @returns the constructed type for `name` or `nullptr` if not found
  ast::type::Type* get_constructed(const std::string& name);

  /// Parses the `translation_unit` grammar element
  void translation_unit();
  /// Parses the `global_decl` grammar element, erroring on parse failure.
  /// @return true on parse success, otherwise an error.
  Expect<bool> expect_global_decl();
  /// Parses a `global_variable_decl` grammar element with the initial
  /// `variable_decoration_list*` provided as `decos`
  /// @returns the variable parsed or nullptr
  /// @param decos the list of decorations for the variable declaration.
  Maybe<ast::Variable*> global_variable_decl(ast::DecorationList& decos);
  /// Parses a `global_constant_decl` grammar element
  /// @returns the const object or nullptr
  Maybe<ast::Variable*> global_constant_decl();
  /// Parses a `variable_decl` grammar element
  /// @returns the parsed variable declaration info
  Maybe<VarDeclInfo> variable_decl();
  /// Parses a `variable_ident_decl` grammar element, erroring on parse
  /// failure.
  /// @param use a description of what was being parsed if an error was raised.
  /// @returns the identifier and type parsed or empty otherwise
  Expect<TypedIdentifier> expect_variable_ident_decl(const std::string& use);
  /// Parses a `variable_storage_decoration` grammar element
  /// @returns the storage class or StorageClass::kNone if none matched
  Maybe<ast::StorageClass> variable_storage_decoration();
  /// Parses a `type_alias` grammar element
  /// @returns the type alias or nullptr on error
  Maybe<ast::type::Type*> type_alias();
  /// Parses a `type_decl` grammar element
  /// @returns the parsed Type or nullptr if none matched.
  Maybe<ast::type::Type*> type_decl();
  /// Parses a `type_decl` grammar element with the given pre-parsed
  /// decorations.
  /// @param decos the list of decorations for the type.
  /// @returns the parsed Type or nullptr if none matched.
  Maybe<ast::type::Type*> type_decl(ast::DecorationList& decos);
  /// Parses a `storage_class` grammar element, erroring on parse failure.
  /// @param use a description of what was being parsed if an error was raised.
  /// @returns the storage class or StorageClass::kNone if none matched
  Expect<ast::StorageClass> expect_storage_class(const std::string& use);
  /// Parses a `struct_decl` grammar element with the initial
  /// `struct_decoration_decl*` provided as `decos`.
  /// @returns the struct type or nullptr on error
  /// @param decos the list of decorations for the struct declaration.
  Maybe<std::unique_ptr<ast::type::Struct>> struct_decl(
      ast::DecorationList& decos);
  /// Parses a `struct_body_decl` grammar element, erroring on parse failure.
  /// @returns the struct members
  Expect<ast::StructMemberList> expect_struct_body_decl();
  /// Parses a `struct_member` grammar element with the initial
  /// `struct_member_decoration_decl+` provided as `decos`, erroring on parse
  /// failure.
  /// @param decos the list of decorations for the struct member.
  /// @returns the struct member or nullptr
  Expect<ast::StructMember*> expect_struct_member(ast::DecorationList& decos);
  /// Parses a `function_decl` grammar element with the initial
  /// `function_decoration_decl*` provided as `decos`.
  /// @param decos the list of decorations for the function declaration.
  /// @returns the parsed function, nullptr otherwise
  Maybe<ast::Function*> function_decl(ast::DecorationList& decos);
  /// Parses a `texture_sampler_types` grammar element
  /// @returns the parsed Type or nullptr if none matched.
  Maybe<ast::type::Type*> texture_sampler_types();
  /// Parses a `sampler_type` grammar element
  /// @returns the parsed Type or nullptr if none matched.
  Maybe<ast::type::Type*> sampler_type();
  /// Parses a `multisampled_texture_type` grammar element
  /// @returns returns the multisample texture dimension or kNone if none
  /// matched.
  Maybe<ast::type::TextureDimension> multisampled_texture_type();
  /// Parses a `sampled_texture_type` grammar element
  /// @returns returns the sample texture dimension or kNone if none matched.
  Maybe<ast::type::TextureDimension> sampled_texture_type();
  /// Parses a `storage_texture_type` grammar element
  /// @returns returns the storage texture dimension and the storage access.
  ///          Returns kNone and kRead if none matched.
  Maybe<std::pair<ast::type::TextureDimension, ast::AccessControl>>
  storage_texture_type();
  /// Parses a `depth_texture_type` grammar element
  /// @returns the parsed Type or nullptr if none matched.
  Maybe<ast::type::Type*> depth_texture_type();
  /// Parses a `image_storage_type` grammar element
  /// @param use a description of what was being parsed if an error was raised
  /// @returns returns the image format or kNone if none matched.
  Expect<ast::type::ImageFormat> expect_image_storage_type(
      const std::string& use);
  /// Parses a `function_type_decl` grammar element
  /// @returns the parsed type or nullptr otherwise
  Maybe<ast::type::Type*> function_type_decl();
  /// Parses a `function_header` grammar element
  /// @returns the parsed function header
  Maybe<FunctionHeader> function_header();
  /// Parses a `param_list` grammar element, erroring on parse failure.
  /// @returns the parsed variables
  Expect<ast::VariableList> expect_param_list();
  /// Parses a `pipeline_stage` grammar element, erroring if the next token does
  /// not match a stage name.
  /// @returns the pipeline stage.
  Expect<ast::PipelineStage> expect_pipeline_stage();
  /// Parses an access type identifier, erroring if the next token does not
  /// match a valid access type name.
  /// @returns the parsed access control.
  Expect<ast::AccessControl> expect_access_type();
  /// Parses a builtin identifier, erroring if the next token does not match a
  /// valid builtin name.
  /// @returns the parsed builtin.
  Expect<ast::Builtin> expect_builtin();
  /// Parses a `body_stmt` grammar element, erroring on parse failure.
  /// @returns the parsed statements
  Expect<ast::BlockStatement*> expect_body_stmt();
  /// Parses a `paren_rhs_stmt` grammar element, erroring on parse failure.
  /// @returns the parsed element or nullptr
  Expect<ast::Expression*> expect_paren_rhs_stmt();
  /// Parses a `statements` grammar element
  /// @returns the statements parsed
  Expect<ast::StatementList> expect_statements();
  /// Parses a `statement` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::Statement*> statement();
  /// Parses a `break_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::BreakStatement*> break_stmt();
  /// Parses a `return_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::ReturnStatement*> return_stmt();
  /// Parses a `continue_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::ContinueStatement*> continue_stmt();
  /// Parses a `variable_stmt` grammar element
  /// @returns the parsed variable or nullptr
  Maybe<ast::VariableDeclStatement*> variable_stmt();
  /// Parses a `if_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::IfStatement*> if_stmt();
  /// Parses a `elseif_stmt` grammar element
  /// @returns the parsed elements
  Maybe<ast::ElseStatementList> elseif_stmt();
  /// Parses a `else_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::ElseStatement*> else_stmt();
  /// Parses a `switch_stmt` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::SwitchStatement*> switch_stmt();
  /// Parses a `switch_body` grammar element
  /// @returns the parsed statement or nullptr
  Maybe<ast::CaseStatement*> switch_body();
  /// Parses a `case_selectors` grammar element
  /// @returns the list of literals
  Expect<ast::CaseSelectorList> expect_case_selectors();
  /// Parses a `case_body` grammar element
  /// @returns the parsed statements
  Maybe<ast::BlockStatement*> case_body();
  /// Parses a `func_call_stmt` grammar element
  /// @returns the parsed function call or nullptr
  Maybe<ast::CallStatement*> func_call_stmt();
  /// Parses a `loop_stmt` grammar element
  /// @returns the parsed loop or nullptr
  Maybe<ast::LoopStatement*> loop_stmt();
  /// Parses a `for_header` grammar element, erroring on parse failure.
  /// @returns the parsed for header or nullptr
  Expect<std::unique_ptr<ForHeader>> expect_for_header();
  /// Parses a `for_stmt` grammar element
  /// @returns the parsed for loop or nullptr
  Maybe<ast::Statement*> for_stmt();
  /// Parses a `continuing_stmt` grammar element
  /// @returns the parsed statements
  Maybe<ast::BlockStatement*> continuing_stmt();
  /// Parses a `const_literal` grammar element
  /// @returns the const literal parsed or nullptr if none found
  Maybe<ast::Literal*> const_literal();
  /// Parses a `const_expr` grammar element, erroring on parse failure.
  /// @returns the parsed constructor expression or nullptr on error
  Expect<ast::ConstructorExpression*> expect_const_expr();
  /// Parses a `primary_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> primary_expression();
  /// Parses a `argument_expression_list` grammar element, erroring on parse
  /// failure.
  /// @returns the list of arguments
  Expect<ast::ExpressionList> expect_argument_expression_list();
  /// Parses the recursive portion of the postfix_expression
  /// @param prefix the left side of the expression
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> postfix_expr(ast::Expression* prefix);
  /// Parses a `postfix_expression` grammar elment
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> postfix_expression();
  /// Parses a `unary_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> unary_expression();
  /// Parses the recursive part of the `multiplicative_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_multiplicative_expr(ast::Expression* lhs);
  /// Parses the `multiplicative_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> multiplicative_expression();
  /// Parses the recursive part of the `additive_expression`, erroring on parse
  /// failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_additive_expr(ast::Expression* lhs);
  /// Parses the `additive_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> additive_expression();
  /// Parses the recursive part of the `shift_expression`, erroring on parse
  /// failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_shift_expr(ast::Expression* lhs);
  /// Parses the `shift_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> shift_expression();
  /// Parses the recursive part of the `relational_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_relational_expr(ast::Expression* lhs);
  /// Parses the `relational_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> relational_expression();
  /// Parses the recursive part of the `equality_expression`, erroring on parse
  /// failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_equality_expr(ast::Expression* lhs);
  /// Parses the `equality_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> equality_expression();
  /// Parses the recursive part of the `and_expression`, erroring on parse
  /// failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_and_expr(ast::Expression* lhs);
  /// Parses the `and_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> and_expression();
  /// Parses the recursive part of the `exclusive_or_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_exclusive_or_expr(ast::Expression* lhs);
  /// Parses the `exclusive_or_expression` grammar elememnt
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> exclusive_or_expression();
  /// Parses the recursive part of the `inclusive_or_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_inclusive_or_expr(ast::Expression* lhs);
  /// Parses the `inclusive_or_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> inclusive_or_expression();
  /// Parses the recursive part of the `logical_and_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_logical_and_expr(ast::Expression* lhs);
  /// Parses a `logical_and_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> logical_and_expression();
  /// Parses the recursive part of the `logical_or_expression`, erroring on
  /// parse failure.
  /// @param lhs the left side of the expression
  /// @returns the parsed expression or nullptr
  Expect<ast::Expression*> expect_logical_or_expr(ast::Expression* lhs);
  /// Parses a `logical_or_expression` grammar element
  /// @returns the parsed expression or nullptr
  Maybe<ast::Expression*> logical_or_expression();
  /// Parses a `assignment_stmt` grammar element
  /// @returns the parsed assignment or nullptr
  Maybe<ast::AssignmentStatement*> assignment_stmt();
  /// Parses one or more bracketed decoration lists.
  /// @return the parsed decoration list, or an empty list on error.
  Maybe<ast::DecorationList> decoration_list();
  /// Parses a list of decorations between `ATTR_LEFT` and `ATTR_RIGHT`
  /// brackets.
  /// @param decos the list to append newly parsed decorations to.
  /// @return true if any decorations were be parsed, otherwise false.
  Maybe<bool> decoration_bracketed_list(ast::DecorationList& decos);
  /// Parses a single decoration of the following types:
  /// * `struct_decoration`
  /// * `struct_member_decoration`
  /// * `array_decoration`
  /// * `variable_decoration`
  /// * `global_const_decoration`
  /// * `function_decoration`
  /// @return the parsed decoration, or nullptr.
  Maybe<ast::Decoration*> decoration();
  /// Parses a single decoration, reporting an error if the next token does not
  /// represent a decoration.
  /// @see #decoration for the full list of decorations this method parses.
  /// @return the parsed decoration, or nullptr on error.
  Expect<ast::Decoration*> expect_decoration();

 private:
  /// ReturnType resolves to the return type for the function or lambda F.
  template <typename F>
  using ReturnType = typename std::result_of<F()>::type;

  /// ResultType resolves to `T` for a `RESULT` of type Expect<T>.
  template <typename RESULT>
  using ResultType = typename RESULT::type;

  /// @returns true and consumes the next token if it equals `tok`
  /// @param source if not nullptr, the next token's source is written to this
  /// pointer, regardless of success or error
  bool match(Token::Type tok, Source* source = nullptr);
  /// Errors if the next token is not equal to `tok`
  /// Consumes the next token on match.
  /// expect() also updates #synchronized_, setting it to `true` if the next
  /// token is equal to `tok`, otherwise `false`.
  /// @param use a description of what was being parsed if an error was raised.
  /// @param tok the token to test against
  /// @returns true if the next token equals `tok`
  bool expect(const std::string& use, Token::Type tok);
  /// Parses a signed integer from the next token in the stream, erroring if the
  /// next token is not a signed integer.
  /// Consumes the next token on match.
  /// @param use a description of what was being parsed if an error was raised
  /// @returns the parsed integer.
  Expect<int32_t> expect_sint(const std::string& use);
  /// Parses a signed integer from the next token in the stream, erroring if
  /// the next token is not a signed integer or is negative.
  /// Consumes the next token if it is a signed integer (not necessarily
  /// negative).
  /// @param use a description of what was being parsed if an error was raised
  /// @returns the parsed integer.
  Expect<uint32_t> expect_positive_sint(const std::string& use);
  /// Parses a non-zero signed integer from the next token in the stream,
  /// erroring if the next token is not a signed integer or is less than 1.
  /// Consumes the next token if it is a signed integer (not necessarily
  /// >= 1).
  /// @param use a description of what was being parsed if an error was raised
  /// @returns the parsed integer.
  Expect<uint32_t> expect_nonzero_positive_sint(const std::string& use);
  /// Errors if the next token is not an identifier.
  /// Consumes the next token on match.
  /// @param use a description of what was being parsed if an error was raised
  /// @returns the parsed identifier.
  Expect<std::string> expect_ident(const std::string& use);
  /// Parses a lexical block starting with the token `start` and ending with
  /// the token `end`. `body` is called to parse the lexical block body
  /// between the `start` and `end` tokens. If the `start` or `end` tokens
  /// are not matched then an error is generated and a zero-initialized `T` is
  /// returned. If `body` raises an error while parsing then a zero-initialized
  /// `T` is returned.
  /// @param start the token that begins the lexical block
  /// @param end the token that ends the lexical block
  /// @param use a description of what was being parsed if an error was raised
  /// @param body a function or lambda that is called to parse the lexical block
  /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
  /// @return the value returned by `body` if no errors are raised, otherwise
  /// an Expect with error state.
  template <typename F, typename T = ReturnType<F>>
  T expect_block(Token::Type start,
                 Token::Type end,
                 const std::string& use,
                 F&& body);
  /// A convenience function that calls expect_block() passing
  /// `Token::Type::kParenLeft` and `Token::Type::kParenRight` for the `start`
  /// and `end` arguments, respectively.
  /// @param use a description of what was being parsed if an error was raised
  /// @param body a function or lambda that is called to parse the lexical block
  /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
  /// @return the value returned by `body` if no errors are raised, otherwise
  /// an Expect with error state.
  template <typename F, typename T = ReturnType<F>>
  T expect_paren_block(const std::string& use, F&& body);
  /// A convenience function that calls `expect_block` passing
  /// `Token::Type::kBraceLeft` and `Token::Type::kBraceRight` for the `start`
  /// and `end` arguments, respectively.
  /// @param use a description of what was being parsed if an error was raised
  /// @param body a function or lambda that is called to parse the lexical block
  /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
  /// @return the value returned by `body` if no errors are raised, otherwise
  /// an Expect with error state.
  template <typename F, typename T = ReturnType<F>>
  T expect_brace_block(const std::string& use, F&& body);
  /// A convenience function that calls `expect_block` passing
  /// `Token::Type::kLessThan` and `Token::Type::kGreaterThan` for the `start`
  /// and `end` arguments, respectively.
  /// @param use a description of what was being parsed if an error was raised
  /// @param body a function or lambda that is called to parse the lexical block
  /// body, with the signature: `Expect<Result>()` or `Maybe<Result>()`.
  /// @return the value returned by `body` if no errors are raised, otherwise
  /// an Expect with error state.
  template <typename F, typename T = ReturnType<F>>
  T expect_lt_gt_block(const std::string& use, F&& body);

  /// sync() calls the function `func`, and attempts to resynchronize the
  /// parser to the next found resynchronization token if `func` fails. If the
  /// next found resynchronization token is `tok`, then sync will also consume
  /// `tok`.
  ///
  /// sync() will transiently add `tok` to the parser's stack of
  /// synchronization tokens for the duration of the call to `func`. Once @p
  /// func returns,
  /// `tok` is removed from the stack of resynchronization tokens. sync calls
  /// may be nested, and so the number of resynchronization tokens is equal to
  /// the number of sync() calls in the current stack frame.
  ///
  /// sync() updates #synchronized_, setting it to `true` if the next
  /// resynchronization token found was `tok`, otherwise `false`.
  ///
  /// @param tok the token to attempt to synchronize the parser to if `func`
  /// fails.
  /// @param func a function or lambda with the signature: `Expect<Result>()` or
  /// `Maybe<Result>()`.
  /// @return the value returned by `func`
  template <typename F, typename T = ReturnType<F>>
  T sync(Token::Type tok, F&& func);
  /// sync_to() attempts to resynchronize the parser to the next found
  /// resynchronization token or `tok` (whichever comes first).
  ///
  /// Synchronization tokens are transiently defined by calls to sync().
  ///
  /// sync_to() updates #synchronized_, setting it to `true` if a
  /// resynchronization token was found and it was `tok`, otherwise `false`.
  ///
  /// @param tok the token to attempt to synchronize the parser to.
  /// @param consume if true and the next found resynchronization token is
  /// `tok` then sync_to() will also consume `tok`.
  /// @return the state of #synchronized_.
  /// @see sync().
  bool sync_to(Token::Type tok, bool consume);
  /// @return true if `t` is in the stack of resynchronization tokens.
  /// @see sync().
  bool is_sync_token(const Token& t) const;

  /// without_error() calls the function `func` muting any grammatical errors
  /// found while executing the function. This can be used as a best-effort to
  /// produce a meaningful error message when the parser is out of sync.
  /// @param func a function or lambda with the signature: `Expect<Result>()` or
  /// `Maybe<Result>()`.
  /// @return the value returned by `func`
  template <typename F, typename T = ReturnType<F>>
  T without_error(F&& func);

  /// Returns all the decorations taken from `list` that matches the type `T`.
  /// Those that do not match are kept in `list`.
  template <typename T>
  std::vector<T*> take_decorations(ast::DecorationList& list);

  /// Downcasts all the decorations in `list` to the type `T`, raising a parser
  /// error if any of the decorations aren't of the type `T`.
  template <typename T>
  Expect<std::vector<T*>> cast_decorations(ast::DecorationList& list);

  /// Reports an error if the decoration list `list` is not empty.
  /// Used to ensure that all decorations are consumed.
  bool expect_decorations_consumed(const ast::DecorationList& list);

  Expect<ast::type::Type*> expect_type_decl_pointer();
  Expect<ast::type::Type*> expect_type_decl_vector(Token t);
  Expect<ast::type::Type*> expect_type_decl_array(
      ast::ArrayDecorationList decos);
  Expect<ast::type::Type*> expect_type_decl_matrix(Token t);

  Expect<ast::ConstructorExpression*> expect_const_expr_internal(
      uint32_t depth);

  Expect<ast::type::Type*> expect_type(const std::string& use);

  Maybe<ast::Statement*> non_block_statement();
  Maybe<ast::Statement*> for_header_initializer();
  Maybe<ast::Statement*> for_header_continuing();

  /// Creates a new `ast::Node` owned by the Module. When the Module is
  /// destructed, the `ast::Node` will also be destructed.
  /// @param args the arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename... ARGS>
  T* create(ARGS&&... args) {
    return module_.create<T>(std::forward<ARGS>(args)...);
  }

  diag::List diags_;
  std::unique_ptr<Lexer> lexer_;
  std::deque<Token> token_queue_;
  bool synchronized_ = true;
  std::vector<Token::Type> sync_tokens_;
  int silence_errors_ = 0;
  std::unordered_map<std::string, ast::type::Type*> registered_constructs_;
  ast::Module module_;
  size_t max_errors_ = 25;
};

}  // namespace wgsl
}  // namespace reader
}  // namespace tint

#endif  // SRC_READER_WGSL_PARSER_IMPL_H_
