// Copyright 2021 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_PROGRAM_BUILDER_H_
#define SRC_PROGRAM_BUILDER_H_

#include <string>
#include <unordered_set>
#include <utility>

#include "src/ast/alias.h"
#include "src/ast/array.h"
#include "src/ast/array_accessor_expression.h"
#include "src/ast/assignment_statement.h"
#include "src/ast/atomic.h"
#include "src/ast/binary_expression.h"
#include "src/ast/binding_decoration.h"
#include "src/ast/bitcast_expression.h"
#include "src/ast/bool.h"
#include "src/ast/bool_literal.h"
#include "src/ast/break_statement.h"
#include "src/ast/call_expression.h"
#include "src/ast/call_statement.h"
#include "src/ast/case_statement.h"
#include "src/ast/depth_multisampled_texture.h"
#include "src/ast/depth_texture.h"
#include "src/ast/disable_validation_decoration.h"
#include "src/ast/external_texture.h"
#include "src/ast/f32.h"
#include "src/ast/float_literal.h"
#include "src/ast/for_loop_statement.h"
#include "src/ast/i32.h"
#include "src/ast/if_statement.h"
#include "src/ast/interpolate_decoration.h"
#include "src/ast/invariant_decoration.h"
#include "src/ast/loop_statement.h"
#include "src/ast/matrix.h"
#include "src/ast/member_accessor_expression.h"
#include "src/ast/module.h"
#include "src/ast/multisampled_texture.h"
#include "src/ast/override_decoration.h"
#include "src/ast/phony_expression.h"
#include "src/ast/pointer.h"
#include "src/ast/return_statement.h"
#include "src/ast/sampled_texture.h"
#include "src/ast/sampler.h"
#include "src/ast/sint_literal.h"
#include "src/ast/stage_decoration.h"
#include "src/ast/storage_texture.h"
#include "src/ast/stride_decoration.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/struct_member_align_decoration.h"
#include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/struct_member_size_decoration.h"
#include "src/ast/switch_statement.h"
#include "src/ast/type_constructor_expression.h"
#include "src/ast/type_name.h"
#include "src/ast/u32.h"
#include "src/ast/uint_literal.h"
#include "src/ast/unary_op_expression.h"
#include "src/ast/variable_decl_statement.h"
#include "src/ast/vector.h"
#include "src/ast/void.h"
#include "src/ast/workgroup_decoration.h"
#include "src/program.h"
#include "src/program_id.h"
#include "src/sem/array.h"
#include "src/sem/bool_type.h"
#include "src/sem/depth_texture_type.h"
#include "src/sem/external_texture_type.h"
#include "src/sem/f32_type.h"
#include "src/sem/i32_type.h"
#include "src/sem/matrix_type.h"
#include "src/sem/multisampled_texture_type.h"
#include "src/sem/pointer_type.h"
#include "src/sem/sampled_texture_type.h"
#include "src/sem/storage_texture_type.h"
#include "src/sem/struct.h"
#include "src/sem/u32_type.h"
#include "src/sem/vector_type.h"
#include "src/sem/void_type.h"

#ifdef INCLUDE_TINT_TINT_H_
#error "internal tint header being #included from tint.h"
#endif

// Forward declarations
namespace tint {
namespace ast {
class VariableDeclStatement;
}  // namespace ast
}  // namespace tint

namespace tint {
class CloneContext;

/// ProgramBuilder is a mutable builder for a Program.
/// To construct a Program, populate the builder and then `std::move` it to a
/// Program.
class ProgramBuilder {
  /// A helper used to disable overloads if the first type in `TYPES` is a
  /// Source. Used to avoid ambiguities in overloads that take a Source as the
  /// first parameter and those that perfectly-forward the first argument.
  template <typename... TYPES>
  using DisableIfSource = traits::EnableIfIsNotType<
      traits::Decay<traits::NthTypeOf<0, TYPES..., void>>,
      Source>;

  /// VarOptionals is a helper for accepting a number of optional, extra
  /// arguments for Var() and Global().
  struct VarOptionals {
    template <typename... ARGS>
    explicit VarOptionals(ARGS&&... args) {
      Apply(std::forward<ARGS>(args)...);
    }
    ~VarOptionals();

    ast::StorageClass storage = ast::StorageClass::kNone;
    ast::Access access = ast::Access::kUndefined;
    const ast::Expression* constructor = nullptr;
    ast::DecorationList decorations = {};

   private:
    void Set(ast::StorageClass sc) { storage = sc; }
    void Set(ast::Access ac) { access = ac; }
    void Set(const ast::Expression* c) { constructor = c; }
    void Set(const ast::DecorationList& l) { decorations = l; }

    template <typename FIRST, typename... ARGS>
    void Apply(FIRST&& first, ARGS&&... args) {
      Set(std::forward<FIRST>(first));
      Apply(std::forward<ARGS>(args)...);
    }
    void Apply() {}
  };

 public:
  /// ASTNodeAllocator is an alias to BlockAllocator<ast::Node>
  using ASTNodeAllocator = BlockAllocator<ast::Node>;

  /// SemNodeAllocator is an alias to BlockAllocator<sem::Node>
  using SemNodeAllocator = BlockAllocator<sem::Node>;

  /// `i32` is a type alias to `int`.
  /// Useful for passing to template methods such as `vec2<i32>()` to imitate
  /// WGSL syntax.
  /// Note: this is intentionally not aliased to uint32_t as we want integer
  /// literals passed to the builder to match WGSL's integer literal types.
  using i32 = decltype(1);
  /// `u32` is a type alias to `unsigned int`.
  /// Useful for passing to template methods such as `vec2<u32>()` to imitate
  /// WGSL syntax.
  /// Note: this is intentionally not aliased to uint32_t as we want integer
  /// literals passed to the builder to match WGSL's integer literal types.
  using u32 = decltype(1u);
  /// `f32` is a type alias to `float`
  /// Useful for passing to template methods such as `vec2<f32>()` to imitate
  /// WGSL syntax.
  using f32 = float;

  /// Constructor
  ProgramBuilder();

  /// Move constructor
  /// @param rhs the builder to move
  ProgramBuilder(ProgramBuilder&& rhs);

  /// Destructor
  virtual ~ProgramBuilder();

  /// Move assignment operator
  /// @param rhs the builder to move
  /// @return this builder
  ProgramBuilder& operator=(ProgramBuilder&& rhs);

  /// Wrap returns a new ProgramBuilder wrapping the Program `program` without
  /// making a deep clone of the Program contents.
  /// ProgramBuilder returned by Wrap() is intended to temporarily extend an
  /// existing immutable program.
  /// As the returned ProgramBuilder wraps `program`, `program` must not be
  /// destructed or assigned while using the returned ProgramBuilder.
  /// TODO(bclayton) - Evaluate whether there are safer alternatives to this
  /// function. See crbug.com/tint/460.
  /// @param program the immutable Program to wrap
  /// @return the ProgramBuilder that wraps `program`
  static ProgramBuilder Wrap(const Program* program);

  /// @returns the unique identifier for this program
  ProgramID ID() const { return id_; }

  /// @returns a reference to the program's types
  sem::Manager& Types() {
    AssertNotMoved();
    return types_;
  }

  /// @returns a reference to the program's types
  const sem::Manager& Types() const {
    AssertNotMoved();
    return types_;
  }

  /// @returns a reference to the program's AST nodes storage
  ASTNodeAllocator& ASTNodes() {
    AssertNotMoved();
    return ast_nodes_;
  }

  /// @returns a reference to the program's AST nodes storage
  const ASTNodeAllocator& ASTNodes() const {
    AssertNotMoved();
    return ast_nodes_;
  }

  /// @returns a reference to the program's semantic nodes storage
  SemNodeAllocator& SemNodes() {
    AssertNotMoved();
    return sem_nodes_;
  }

  /// @returns a reference to the program's semantic nodes storage
  const SemNodeAllocator& SemNodes() const {
    AssertNotMoved();
    return sem_nodes_;
  }

  /// @returns a reference to the program's AST root Module
  ast::Module& AST() {
    AssertNotMoved();
    return *ast_;
  }

  /// @returns a reference to the program's AST root Module
  const ast::Module& AST() const {
    AssertNotMoved();
    return *ast_;
  }

  /// @returns a reference to the program's semantic info
  sem::Info& Sem() {
    AssertNotMoved();
    return sem_;
  }

  /// @returns a reference to the program's semantic info
  const sem::Info& Sem() const {
    AssertNotMoved();
    return sem_;
  }

  /// @returns a reference to the program's SymbolTable
  SymbolTable& Symbols() {
    AssertNotMoved();
    return symbols_;
  }

  /// @returns a reference to the program's SymbolTable
  const SymbolTable& Symbols() const {
    AssertNotMoved();
    return symbols_;
  }

  /// @returns a reference to the program's diagnostics
  diag::List& Diagnostics() {
    AssertNotMoved();
    return diagnostics_;
  }

  /// @returns a reference to the program's diagnostics
  const diag::List& Diagnostics() const {
    AssertNotMoved();
    return diagnostics_;
  }

  /// Controls whether the Resolver will be run on the program when it is built.
  /// @param enable the new flag value (defaults to true)
  void SetResolveOnBuild(bool enable) { resolve_on_build_ = enable; }

  /// @return true if the Resolver will be run on the program when it is
  /// built.
  bool ResolveOnBuild() const { return resolve_on_build_; }

  /// @returns true if the program has no error diagnostics and is not missing
  /// information
  bool IsValid() const;

  /// Creates a new ast::Node owned by the ProgramBuilder. When the
  /// ProgramBuilder is destructed, the ast::Node will also be destructed.
  /// @param source the Source of the node
  /// @param args the arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename... ARGS>
  traits::EnableIfIsType<T, ast::Node>* create(const Source& source,
                                               ARGS&&... args) {
    AssertNotMoved();
    return ast_nodes_.Create<T>(id_, source, std::forward<ARGS>(args)...);
  }

  /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
  /// Source as set by the last call to SetSource() as the only argument to the
  /// constructor.
  /// When the ProgramBuilder is destructed, the ast::Node will also be
  /// destructed.
  /// @returns the node pointer
  template <typename T>
  traits::EnableIfIsType<T, ast::Node>* create() {
    AssertNotMoved();
    return ast_nodes_.Create<T>(id_, source_);
  }

  /// Creates a new ast::Node owned by the ProgramBuilder, injecting the current
  /// Source as set by the last call to SetSource() as the first argument to the
  /// constructor.
  /// When the ProgramBuilder is destructed, the ast::Node will also be
  /// destructed.
  /// @param arg0 the first arguments to pass to the type constructor
  /// @param args the remaining arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename ARG0, typename... ARGS>
  traits::EnableIf</* T is ast::Node and ARG0 is not Source */
                   traits::IsTypeOrDerived<T, ast::Node>::value &&
                       !traits::IsTypeOrDerived<ARG0, Source>::value,
                   T>*
  create(ARG0&& arg0, ARGS&&... args) {
    AssertNotMoved();
    return ast_nodes_.Create<T>(id_, source_, std::forward<ARG0>(arg0),
                                std::forward<ARGS>(args)...);
  }

  /// Creates a new sem::Node owned by the ProgramBuilder.
  /// When the ProgramBuilder is destructed, the sem::Node will also be
  /// destructed.
  /// @param args the arguments to pass to the type constructor
  /// @returns the node pointer
  template <typename T, typename... ARGS>
  traits::EnableIf<traits::IsTypeOrDerived<T, sem::Node>::value &&
                       !traits::IsTypeOrDerived<T, sem::Type>::value,
                   T>*
  create(ARGS&&... args) {
    AssertNotMoved();
    return sem_nodes_.Create<T>(std::forward<ARGS>(args)...);
  }

  /// Creates a new sem::Type owned by the ProgramBuilder.
  /// When the ProgramBuilder is destructed, owned ProgramBuilder and the
  /// returned`Type` will also be destructed.
  /// Types are unique (de-aliased), and so calling create() for the same `T`
  /// and arguments will return the same pointer.
  /// @warning Use this method to acquire a type only if all of its type
  /// information is provided in the constructor arguments `args`.<br>
  /// If the type requires additional configuration after construction that
  /// affect its fundamental type, build the type with `std::make_unique`, make
  /// any necessary alterations and then call unique_type() instead.
  /// @param args the arguments to pass to the type constructor
  /// @returns the de-aliased type pointer
  template <typename T, typename... ARGS>
  traits::EnableIfIsType<T, sem::Type>* create(ARGS&&... args) {
    static_assert(std::is_base_of<sem::Type, T>::value,
                  "T does not derive from sem::Type");
    AssertNotMoved();
    return types_.Get<T>(std::forward<ARGS>(args)...);
  }

  /// Marks this builder as moved, preventing any further use of the builder.
  void MarkAsMoved();

  //////////////////////////////////////////////////////////////////////////////
  // TypesBuilder
  //////////////////////////////////////////////////////////////////////////////

  /// TypesBuilder holds basic `tint` types and methods for constructing
  /// complex types.
  class TypesBuilder {
   public:
    /// Constructor
    /// @param builder the program builder
    explicit TypesBuilder(ProgramBuilder* builder);

    /// @return the tint AST type for the C type `T`.
    template <typename T>
    const ast::Type* Of() const {
      return CToAST<T>::get(this);
    }

    /// @returns a boolean type
    const ast::Bool* bool_() const { return builder->create<ast::Bool>(); }

    /// @param source the Source of the node
    /// @returns a boolean type
    const ast::Bool* bool_(const Source& source) const {
      return builder->create<ast::Bool>(source);
    }

    /// @returns a f32 type
    const ast::F32* f32() const { return builder->create<ast::F32>(); }

    /// @param source the Source of the node
    /// @returns a f32 type
    const ast::F32* f32(const Source& source) const {
      return builder->create<ast::F32>(source);
    }

    /// @returns a i32 type
    const ast::I32* i32() const { return builder->create<ast::I32>(); }

    /// @param source the Source of the node
    /// @returns a i32 type
    const ast::I32* i32(const Source& source) const {
      return builder->create<ast::I32>(source);
    }

    /// @returns a u32 type
    const ast::U32* u32() const { return builder->create<ast::U32>(); }

    /// @param source the Source of the node
    /// @returns a u32 type
    const ast::U32* u32(const Source& source) const {
      return builder->create<ast::U32>(source);
    }

    /// @returns a void type
    const ast::Void* void_() const { return builder->create<ast::Void>(); }

    /// @param source the Source of the node
    /// @returns a void type
    const ast::Void* void_(const Source& source) const {
      return builder->create<ast::Void>(source);
    }

    /// @param type vector subtype
    /// @param n vector width in elements
    /// @return the tint AST type for a `n`-element vector of `type`.
    const ast::Vector* vec(const ast::Type* type, uint32_t n) const {
      return builder->create<ast::Vector>(type, n);
    }

    /// @param source the Source of the node
    /// @param type vector subtype
    /// @param n vector width in elements
    /// @return the tint AST type for a `n`-element vector of `type`.
    const ast::Vector* vec(const Source& source,
                           const ast::Type* type,
                           uint32_t n) const {
      return builder->create<ast::Vector>(source, type, n);
    }

    /// @param type vector subtype
    /// @return the tint AST type for a 2-element vector of `type`.
    const ast::Vector* vec2(const ast::Type* type) const {
      return vec(type, 2u);
    }

    /// @param type vector subtype
    /// @return the tint AST type for a 3-element vector of `type`.
    const ast::Vector* vec3(const ast::Type* type) const {
      return vec(type, 3u);
    }

    /// @param type vector subtype
    /// @return the tint AST type for a 4-element vector of `type`.
    const ast::Vector* vec4(const ast::Type* type) const {
      return vec(type, 4u);
    }

    /// @param n vector width in elements
    /// @return the tint AST type for a `n`-element vector of `type`.
    template <typename T>
    const ast::Vector* vec(uint32_t n) const {
      return vec(Of<T>(), n);
    }

    /// @return the tint AST type for a 2-element vector of the C type `T`.
    template <typename T>
    const ast::Vector* vec2() const {
      return vec2(Of<T>());
    }

    /// @return the tint AST type for a 3-element vector of the C type `T`.
    template <typename T>
    const ast::Vector* vec3() const {
      return vec3(Of<T>());
    }

    /// @return the tint AST type for a 4-element vector of the C type `T`.
    template <typename T>
    const ast::Vector* vec4() const {
      return vec4(Of<T>());
    }

    /// @param type matrix subtype
    /// @param columns number of columns for the matrix
    /// @param rows number of rows for the matrix
    /// @return the tint AST type for a matrix of `type`
    const ast::Matrix* mat(const ast::Type* type,
                           uint32_t columns,
                           uint32_t rows) const {
      return builder->create<ast::Matrix>(type, rows, columns);
    }

    /// @param source the Source of the node
    /// @param type matrix subtype
    /// @param columns number of columns for the matrix
    /// @param rows number of rows for the matrix
    /// @return the tint AST type for a matrix of `type`
    const ast::Matrix* mat(const Source& source,
                           const ast::Type* type,
                           uint32_t columns,
                           uint32_t rows) const {
      return builder->create<ast::Matrix>(source, type, rows, columns);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 2x3 matrix of `type`.
    const ast::Matrix* mat2x2(const ast::Type* type) const {
      return mat(type, 2u, 2u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 2x3 matrix of `type`.
    const ast::Matrix* mat2x3(const ast::Type* type) const {
      return mat(type, 2u, 3u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 2x4 matrix of `type`.
    const ast::Matrix* mat2x4(const ast::Type* type) const {
      return mat(type, 2u, 4u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 3x2 matrix of `type`.
    const ast::Matrix* mat3x2(const ast::Type* type) const {
      return mat(type, 3u, 2u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 3x3 matrix of `type`.
    const ast::Matrix* mat3x3(const ast::Type* type) const {
      return mat(type, 3u, 3u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 3x4 matrix of `type`.
    const ast::Matrix* mat3x4(const ast::Type* type) const {
      return mat(type, 3u, 4u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 4x2 matrix of `type`.
    const ast::Matrix* mat4x2(const ast::Type* type) const {
      return mat(type, 4u, 2u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 4x3 matrix of `type`.
    const ast::Matrix* mat4x3(const ast::Type* type) const {
      return mat(type, 4u, 3u);
    }

    /// @param type matrix subtype
    /// @return the tint AST type for a 4x4 matrix of `type`.
    const ast::Matrix* mat4x4(const ast::Type* type) const {
      return mat(type, 4u, 4u);
    }

    /// @param columns number of columns for the matrix
    /// @param rows number of rows for the matrix
    /// @return the tint AST type for a matrix of `type`
    template <typename T>
    const ast::Matrix* mat(uint32_t columns, uint32_t rows) const {
      return mat(Of<T>(), columns, rows);
    }

    /// @return the tint AST type for a 2x3 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat2x2() const {
      return mat2x2(Of<T>());
    }

    /// @return the tint AST type for a 2x3 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat2x3() const {
      return mat2x3(Of<T>());
    }

    /// @return the tint AST type for a 2x4 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat2x4() const {
      return mat2x4(Of<T>());
    }

    /// @return the tint AST type for a 3x2 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat3x2() const {
      return mat3x2(Of<T>());
    }

    /// @return the tint AST type for a 3x3 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat3x3() const {
      return mat3x3(Of<T>());
    }

    /// @return the tint AST type for a 3x4 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat3x4() const {
      return mat3x4(Of<T>());
    }

    /// @return the tint AST type for a 4x2 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat4x2() const {
      return mat4x2(Of<T>());
    }

    /// @return the tint AST type for a 4x3 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat4x3() const {
      return mat4x3(Of<T>());
    }

    /// @return the tint AST type for a 4x4 matrix of the C type `T`.
    template <typename T>
    const ast::Matrix* mat4x4() const {
      return mat4x4(Of<T>());
    }

    /// @param subtype the array element type
    /// @param n the array size. nullptr represents a runtime-array
    /// @param decos the optional decorations for the array
    /// @return the tint AST type for a array of size `n` of type `T`
    template <typename EXPR = ast::Expression*>
    const ast::Array* array(const ast::Type* subtype,
                            EXPR&& n = nullptr,
                            ast::DecorationList decos = {}) const {
      return builder->create<ast::Array>(
          subtype, builder->Expr(std::forward<EXPR>(n)), decos);
    }

    /// @param source the Source of the node
    /// @param subtype the array element type
    /// @param n the array size. nullptr represents a runtime-array
    /// @param decos the optional decorations for the array
    /// @return the tint AST type for a array of size `n` of type `T`
    template <typename EXPR = ast::Expression*>
    const ast::Array* array(const Source& source,
                            const ast::Type* subtype,
                            EXPR&& n = nullptr,
                            ast::DecorationList decos = {}) const {
      return builder->create<ast::Array>(
          source, subtype, builder->Expr(std::forward<EXPR>(n)), decos);
    }

    /// @param subtype the array element type
    /// @param n the array size. nullptr represents a runtime-array
    /// @param stride the array stride. 0 represents implicit stride
    /// @return the tint AST type for a array of size `n` of type `T`
    template <typename EXPR>
    const ast::Array* array(const ast::Type* subtype,
                            EXPR&& n,
                            uint32_t stride) const {
      ast::DecorationList decos;
      if (stride) {
        decos.emplace_back(builder->create<ast::StrideDecoration>(stride));
      }
      return array(subtype, std::forward<EXPR>(n), std::move(decos));
    }

    /// @param source the Source of the node
    /// @param subtype the array element type
    /// @param n the array size. nullptr represents a runtime-array
    /// @param stride the array stride. 0 represents implicit stride
    /// @return the tint AST type for a array of size `n` of type `T`
    template <typename EXPR>
    const ast::Array* array(const Source& source,
                            const ast::Type* subtype,
                            EXPR&& n,
                            uint32_t stride) const {
      ast::DecorationList decos;
      if (stride) {
        decos.emplace_back(builder->create<ast::StrideDecoration>(stride));
      }
      return array(source, subtype, std::forward<EXPR>(n), std::move(decos));
    }

    /// @return the tint AST type for a runtime-sized array of type `T`
    template <typename T>
    const ast::Array* array() const {
      return array(Of<T>(), nullptr);
    }

    /// @return the tint AST type for an array of size `N` of type `T`
    template <typename T, int N>
    const ast::Array* array() const {
      return array(Of<T>(), builder->Expr(N));
    }

    /// @param stride the array stride
    /// @return the tint AST type for a runtime-sized array of type `T`
    template <typename T>
    const ast::Array* array(uint32_t stride) const {
      return array(Of<T>(), nullptr, stride);
    }

    /// @param stride the array stride
    /// @return the tint AST type for an array of size `N` of type `T`
    template <typename T, int N>
    const ast::Array* array(uint32_t stride) const {
      return array(Of<T>(), builder->Expr(N), stride);
    }

    /// Creates a type name
    /// @param name the name
    /// @returns the type name
    template <typename NAME>
    const ast::TypeName* type_name(NAME&& name) const {
      return builder->create<ast::TypeName>(
          builder->Sym(std::forward<NAME>(name)));
    }

    /// Creates a type name
    /// @param source the Source of the node
    /// @param name the name
    /// @returns the type name
    template <typename NAME>
    const ast::TypeName* type_name(const Source& source, NAME&& name) const {
      return builder->create<ast::TypeName>(
          source, builder->Sym(std::forward<NAME>(name)));
    }

    /// Creates an alias type
    /// @param name the alias name
    /// @param type the alias type
    /// @returns the alias pointer
    template <typename NAME>
    const ast::Alias* alias(NAME&& name, const ast::Type* type) const {
      auto sym = builder->Sym(std::forward<NAME>(name));
      return builder->create<ast::Alias>(sym, type);
    }

    /// Creates an alias type
    /// @param source the Source of the node
    /// @param name the alias name
    /// @param type the alias type
    /// @returns the alias pointer
    template <typename NAME>
    const ast::Alias* alias(const Source& source,
                            NAME&& name,
                            const ast::Type* type) const {
      auto sym = builder->Sym(std::forward<NAME>(name));
      return builder->create<ast::Alias>(source, sym, type);
    }

    /// @param type the type of the pointer
    /// @param storage_class the storage class of the pointer
    /// @param access the optional access control of the pointer
    /// @return the pointer to `type` with the given ast::StorageClass
    const ast::Pointer* pointer(
        const ast::Type* type,
        ast::StorageClass storage_class,
        ast::Access access = ast::Access::kUndefined) const {
      return builder->create<ast::Pointer>(type, storage_class, access);
    }

    /// @param source the Source of the node
    /// @param type the type of the pointer
    /// @param storage_class the storage class of the pointer
    /// @param access the optional access control of the pointer
    /// @return the pointer to `type` with the given ast::StorageClass
    const ast::Pointer* pointer(
        const Source& source,
        const ast::Type* type,
        ast::StorageClass storage_class,
        ast::Access access = ast::Access::kUndefined) const {
      return builder->create<ast::Pointer>(source, type, storage_class, access);
    }

    /// @param storage_class the storage class of the pointer
    /// @param access the optional access control of the pointer
    /// @return the pointer to type `T` with the given ast::StorageClass.
    template <typename T>
    const ast::Pointer* pointer(
        ast::StorageClass storage_class,
        ast::Access access = ast::Access::kUndefined) const {
      return pointer(Of<T>(), storage_class, access);
    }

    /// @param source the Source of the node
    /// @param type the type of the atomic
    /// @return the atomic to `type`
    const ast::Atomic* atomic(const Source& source,
                              const ast::Type* type) const {
      return builder->create<ast::Atomic>(source, type);
    }

    /// @param type the type of the atomic
    /// @return the atomic to `type`
    const ast::Atomic* atomic(const ast::Type* type) const {
      return builder->create<ast::Atomic>(type);
    }

    /// @return the atomic to type `T`
    template <typename T>
    const ast::Atomic* atomic() const {
      return atomic(Of<T>());
    }

    /// @param kind the kind of sampler
    /// @returns the sampler
    const ast::Sampler* sampler(ast::SamplerKind kind) const {
      return builder->create<ast::Sampler>(kind);
    }

    /// @param source the Source of the node
    /// @param kind the kind of sampler
    /// @returns the sampler
    const ast::Sampler* sampler(const Source& source,
                                ast::SamplerKind kind) const {
      return builder->create<ast::Sampler>(source, kind);
    }

    /// @param dims the dimensionality of the texture
    /// @returns the depth texture
    const ast::DepthTexture* depth_texture(ast::TextureDimension dims) const {
      return builder->create<ast::DepthTexture>(dims);
    }

    /// @param source the Source of the node
    /// @param dims the dimensionality of the texture
    /// @returns the depth texture
    const ast::DepthTexture* depth_texture(const Source& source,
                                           ast::TextureDimension dims) const {
      return builder->create<ast::DepthTexture>(source, dims);
    }

    /// @param dims the dimensionality of the texture
    /// @returns the multisampled depth texture
    const ast::DepthMultisampledTexture* depth_multisampled_texture(
        ast::TextureDimension dims) const {
      return builder->create<ast::DepthMultisampledTexture>(dims);
    }

    /// @param source the Source of the node
    /// @param dims the dimensionality of the texture
    /// @returns the multisampled depth texture
    const ast::DepthMultisampledTexture* depth_multisampled_texture(
        const Source& source,
        ast::TextureDimension dims) const {
      return builder->create<ast::DepthMultisampledTexture>(source, dims);
    }

    /// @param dims the dimensionality of the texture
    /// @param subtype the texture subtype.
    /// @returns the sampled texture
    const ast::SampledTexture* sampled_texture(ast::TextureDimension dims,
                                               const ast::Type* subtype) const {
      return builder->create<ast::SampledTexture>(dims, subtype);
    }

    /// @param source the Source of the node
    /// @param dims the dimensionality of the texture
    /// @param subtype the texture subtype.
    /// @returns the sampled texture
    const ast::SampledTexture* sampled_texture(const Source& source,
                                               ast::TextureDimension dims,
                                               const ast::Type* subtype) const {
      return builder->create<ast::SampledTexture>(source, dims, subtype);
    }

    /// @param dims the dimensionality of the texture
    /// @param subtype the texture subtype.
    /// @returns the multisampled texture
    const ast::MultisampledTexture* multisampled_texture(
        ast::TextureDimension dims,
        const ast::Type* subtype) const {
      return builder->create<ast::MultisampledTexture>(dims, subtype);
    }

    /// @param source the Source of the node
    /// @param dims the dimensionality of the texture
    /// @param subtype the texture subtype.
    /// @returns the multisampled texture
    const ast::MultisampledTexture* multisampled_texture(
        const Source& source,
        ast::TextureDimension dims,
        const ast::Type* subtype) const {
      return builder->create<ast::MultisampledTexture>(source, dims, subtype);
    }

    /// @param dims the dimensionality of the texture
    /// @param format the image format of the texture
    /// @param access the access control of the texture
    /// @returns the storage texture
    const ast::StorageTexture* storage_texture(ast::TextureDimension dims,
                                               ast::ImageFormat format,
                                               ast::Access access) const {
      auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
      return builder->create<ast::StorageTexture>(dims, format, subtype,
                                                  access);
    }

    /// @param source the Source of the node
    /// @param dims the dimensionality of the texture
    /// @param format the image format of the texture
    /// @param access the access control of the texture
    /// @returns the storage texture
    const ast::StorageTexture* storage_texture(const Source& source,
                                               ast::TextureDimension dims,
                                               ast::ImageFormat format,
                                               ast::Access access) const {
      auto* subtype = ast::StorageTexture::SubtypeFor(format, *builder);
      return builder->create<ast::StorageTexture>(source, dims, format, subtype,
                                                  access);
    }

    /// @returns the external texture
    const ast::ExternalTexture* external_texture() const {
      return builder->create<ast::ExternalTexture>();
    }

    /// @param source the Source of the node
    /// @returns the external texture
    const ast::ExternalTexture* external_texture(const Source& source) const {
      return builder->create<ast::ExternalTexture>(source);
    }

    /// Constructs a TypeName for the type declaration.
    /// @param type the type
    /// @return either type or a pointer to a new ast::TypeName
    const ast::TypeName* Of(const ast::TypeDecl* type) const;

    /// The ProgramBuilder
    ProgramBuilder* const builder;

   private:
    /// CToAST<T> is specialized for various `T` types and each specialization
    /// contains a single static `get()` method for obtaining the corresponding
    /// AST type for the C type `T`.
    /// `get()` has the signature:
    ///    `static const ast::Type* get(Types* t)`
    template <typename T>
    struct CToAST {};
  };

  //////////////////////////////////////////////////////////////////////////////
  // AST helper methods
  //////////////////////////////////////////////////////////////////////////////

  /// @return a new unnamed symbol
  Symbol Sym() { return Symbols().New(); }

  /// @param name the symbol string
  /// @return a Symbol with the given name
  Symbol Sym(const std::string& name) { return Symbols().Register(name); }

  /// @param sym the symbol
  /// @return `sym`
  Symbol Sym(Symbol sym) { return sym; }

  /// @param expr the expression
  /// @return expr
  template <typename T>
  traits::EnableIfIsType<T, ast::Expression>* Expr(T* expr) {
    return expr;
  }

  /// Passthrough for nullptr
  /// @return nullptr
  const ast::IdentifierExpression* Expr(std::nullptr_t) { return nullptr; }

  /// @param source the source information
  /// @param symbol the identifier symbol
  /// @return an ast::IdentifierExpression with the given symbol
  const ast::IdentifierExpression* Expr(const Source& source, Symbol symbol) {
    return create<ast::IdentifierExpression>(source, symbol);
  }

  /// @param symbol the identifier symbol
  /// @return an ast::IdentifierExpression with the given symbol
  const ast::IdentifierExpression* Expr(Symbol symbol) {
    return create<ast::IdentifierExpression>(symbol);
  }

  /// @param source the source information
  /// @param variable the AST variable
  /// @return an ast::IdentifierExpression with the variable's symbol
  const ast::IdentifierExpression* Expr(const Source& source,
                                        const ast::Variable* variable) {
    return create<ast::IdentifierExpression>(source, variable->symbol);
  }

  /// @param variable the AST variable
  /// @return an ast::IdentifierExpression with the variable's symbol
  const ast::IdentifierExpression* Expr(const ast::Variable* variable) {
    return create<ast::IdentifierExpression>(variable->symbol);
  }

  /// @param source the source information
  /// @param name the identifier name
  /// @return an ast::IdentifierExpression with the given name
  const ast::IdentifierExpression* Expr(const Source& source,
                                        const char* name) {
    return create<ast::IdentifierExpression>(source, Symbols().Register(name));
  }

  /// @param name the identifier name
  /// @return an ast::IdentifierExpression with the given name
  const ast::IdentifierExpression* Expr(const char* name) {
    return create<ast::IdentifierExpression>(Symbols().Register(name));
  }

  /// @param source the source information
  /// @param name the identifier name
  /// @return an ast::IdentifierExpression with the given name
  const ast::IdentifierExpression* Expr(const Source& source,
                                        const std::string& name) {
    return create<ast::IdentifierExpression>(source, Symbols().Register(name));
  }

  /// @param name the identifier name
  /// @return an ast::IdentifierExpression with the given name
  const ast::IdentifierExpression* Expr(const std::string& name) {
    return create<ast::IdentifierExpression>(Symbols().Register(name));
  }

  /// @param source the source information
  /// @param value the boolean value
  /// @return a Scalar constructor for the given value
  const ast::Literal* Expr(const Source& source, bool value) {
    return create<ast::BoolLiteral>(source, value);
  }

  /// @param value the boolean value
  /// @return a Scalar constructor for the given value
  const ast::BoolLiteral* Expr(bool value) {
    return create<ast::BoolLiteral>(value);
  }

  /// @param source the source information
  /// @param value the float value
  /// @return a Scalar constructor for the given value
  const ast::FloatLiteral* Expr(const Source& source, f32 value) {
    return create<ast::FloatLiteral>(source, value);
  }

  /// @param value the float value
  /// @return a Scalar constructor for the given value
  const ast::FloatLiteral* Expr(f32 value) {
    return create<ast::FloatLiteral>(value);
  }

  /// @param source the source information
  /// @param value the integer value
  /// @return a Scalar constructor for the given value
  const ast::Literal* Expr(const Source& source, i32 value) {
    return create<ast::SintLiteral>(source, value);
  }

  /// @param value the integer value
  /// @return a Scalar constructor for the given value
  const ast::SintLiteral* Expr(i32 value) {
    return create<ast::SintLiteral>(value);
  }

  /// @param source the source information
  /// @param value the unsigned int value
  /// @return a Scalar constructor for the given value
  const ast::UintLiteral* Expr(const Source& source, u32 value) {
    return create<ast::UintLiteral>(source, value);
  }

  /// @param value the unsigned int value
  /// @return a Scalar constructor for the given value
  const ast::UintLiteral* Expr(u32 value) {
    return create<ast::UintLiteral>(value);
  }

  /// Converts `arg` to an `ast::Expression` using `Expr()`, then appends it to
  /// `list`.
  /// @param list the list to append too
  /// @param arg the arg to create
  template <typename ARG>
  void Append(ast::ExpressionList& list, ARG&& arg) {
    list.emplace_back(Expr(std::forward<ARG>(arg)));
  }

  /// Converts `arg0` and `args` to `ast::Expression`s using `Expr()`,
  /// then appends them to `list`.
  /// @param list the list to append too
  /// @param arg0 the first argument
  /// @param args the rest of the arguments
  template <typename ARG0, typename... ARGS>
  void Append(ast::ExpressionList& list, ARG0&& arg0, ARGS&&... args) {
    Append(list, std::forward<ARG0>(arg0));
    Append(list, std::forward<ARGS>(args)...);
  }

  /// @return an empty list of expressions
  ast::ExpressionList ExprList() { return {}; }

  /// @param args the list of expressions
  /// @return the list of expressions converted to `ast::Expression`s using
  /// `Expr()`,
  template <typename... ARGS>
  ast::ExpressionList ExprList(ARGS&&... args) {
    ast::ExpressionList list;
    list.reserve(sizeof...(args));
    Append(list, std::forward<ARGS>(args)...);
    return list;
  }

  /// @param list the list of expressions
  /// @return `list`
  ast::ExpressionList ExprList(ast::ExpressionList list) { return list; }

  /// @param source the source location for the literal
  /// @param val the boolan value
  /// @return a boolean literal with the given value
  const ast::BoolLiteral* Literal(const Source& source, bool val) {
    return create<ast::BoolLiteral>(source, val);
  }

  /// @param val the boolan value
  /// @return a boolean literal with the given value
  const ast::BoolLiteral* Literal(bool val) {
    return create<ast::BoolLiteral>(val);
  }

  /// @param source the source location for the literal
  /// @param val the float value
  /// @return a float literal with the given value
  const ast::FloatLiteral* Literal(const Source& source, f32 val) {
    return create<ast::FloatLiteral>(source, val);
  }

  /// @param val the float value
  /// @return a float literal with the given value
  const ast::FloatLiteral* Literal(f32 val) {
    return create<ast::FloatLiteral>(val);
  }

  /// @param source the source location for the literal
  /// @param val the unsigned int value
  /// @return a ast::UintLiteral with the given value
  const ast::UintLiteral* Literal(const Source& source, u32 val) {
    return create<ast::UintLiteral>(source, val);
  }

  /// @param val the unsigned int value
  /// @return a ast::UintLiteral with the given value
  const ast::UintLiteral* Literal(u32 val) {
    return create<ast::UintLiteral>(val);
  }

  /// @param source the source location for the literal
  /// @param val the integer value
  /// @return the ast::SintLiteral with the given value
  const ast::SintLiteral* Literal(const Source& source, i32 val) {
    return create<ast::SintLiteral>(source, val);
  }

  /// @param val the integer value
  /// @return the ast::SintLiteral with the given value
  const ast::SintLiteral* Literal(i32 val) {
    return create<ast::SintLiteral>(val);
  }

  /// @param args the arguments for the type constructor
  /// @return an `ast::TypeConstructorExpression` of type `ty`, with the values
  /// of `args` converted to `ast::Expression`s using `Expr()`
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* Construct(ARGS&&... args) {
    return Construct(ty.Of<T>(), std::forward<ARGS>(args)...);
  }

  /// @param type the type to construct
  /// @param args the arguments for the constructor
  /// @return an `ast::TypeConstructorExpression` of `type` constructed with the
  /// values `args`.
  template <typename... ARGS>
  const ast::TypeConstructorExpression* Construct(const ast::Type* type,
                                                  ARGS&&... args) {
    return create<ast::TypeConstructorExpression>(
        type, ExprList(std::forward<ARGS>(args)...));
  }

  /// @param source the source information
  /// @param type the type to construct
  /// @param args the arguments for the constructor
  /// @return an `ast::TypeConstructorExpression` of `type` constructed with the
  /// values `args`.
  template <typename... ARGS>
  const ast::TypeConstructorExpression* Construct(const Source& source,
                                                  const ast::Type* type,
                                                  ARGS&&... args) {
    return create<ast::TypeConstructorExpression>(
        source, type, ExprList(std::forward<ARGS>(args)...));
  }

  /// @param expr the expression for the bitcast
  /// @return an `ast::BitcastExpression` of type `ty`, with the values of
  /// `expr` converted to `ast::Expression`s using `Expr()`
  template <typename T, typename EXPR>
  const ast::BitcastExpression* Bitcast(EXPR&& expr) {
    return Bitcast(ty.Of<T>(), std::forward<EXPR>(expr));
  }

  /// @param type the type to cast to
  /// @param expr the expression for the bitcast
  /// @return an `ast::BitcastExpression` of `type` constructed with the values
  /// `expr`.
  template <typename EXPR>
  const ast::BitcastExpression* Bitcast(const ast::Type* type, EXPR&& expr) {
    return create<ast::BitcastExpression>(type, Expr(std::forward<EXPR>(expr)));
  }

  /// @param source the source information
  /// @param type the type to cast to
  /// @param expr the expression for the bitcast
  /// @return an `ast::BitcastExpression` of `type` constructed with the values
  /// `expr`.
  template <typename EXPR>
  const ast::BitcastExpression* Bitcast(const Source& source,
                                        const ast::Type* type,
                                        EXPR&& expr) {
    return create<ast::BitcastExpression>(source, type,
                                          Expr(std::forward<EXPR>(expr)));
  }

  /// @param args the arguments for the vector constructor
  /// @param type the vector type
  /// @param size the vector size
  /// @return an `ast::TypeConstructorExpression` of a `size`-element vector of
  /// type `type`, constructed with the values `args`.
  template <typename... ARGS>
  const ast::TypeConstructorExpression* vec(const ast::Type* type,
                                            uint32_t size,
                                            ARGS&&... args) {
    return Construct(ty.vec(type, size), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the vector constructor
  /// @return an `ast::TypeConstructorExpression` of a 2-element vector of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* vec2(ARGS&&... args) {
    return Construct(ty.vec2<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the vector constructor
  /// @return an `ast::TypeConstructorExpression` of a 3-element vector of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* vec3(ARGS&&... args) {
    return Construct(ty.vec3<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the vector constructor
  /// @return an `ast::TypeConstructorExpression` of a 4-element vector of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* vec4(ARGS&&... args) {
    return Construct(ty.vec4<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 2x2 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat2x2(ARGS&&... args) {
    return Construct(ty.mat2x2<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 2x3 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat2x3(ARGS&&... args) {
    return Construct(ty.mat2x3<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 2x4 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat2x4(ARGS&&... args) {
    return Construct(ty.mat2x4<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 3x2 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat3x2(ARGS&&... args) {
    return Construct(ty.mat3x2<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 3x3 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat3x3(ARGS&&... args) {
    return Construct(ty.mat3x3<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 3x4 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat3x4(ARGS&&... args) {
    return Construct(ty.mat3x4<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 4x2 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat4x2(ARGS&&... args) {
    return Construct(ty.mat4x2<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 4x3 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat4x3(ARGS&&... args) {
    return Construct(ty.mat4x3<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the matrix constructor
  /// @return an `ast::TypeConstructorExpression` of a 4x4 matrix of type
  /// `T`, constructed with the values `args`.
  template <typename T, typename... ARGS>
  const ast::TypeConstructorExpression* mat4x4(ARGS&&... args) {
    return Construct(ty.mat4x4<T>(), std::forward<ARGS>(args)...);
  }

  /// @param args the arguments for the array constructor
  /// @return an `ast::TypeConstructorExpression` of an array with element type
  /// `T` and size `N`, constructed with the values `args`.
  template <typename T, int N, typename... ARGS>
  const ast::TypeConstructorExpression* array(ARGS&&... args) {
    return Construct(ty.array<T, N>(), std::forward<ARGS>(args)...);
  }

  /// @param subtype the array element type
  /// @param n the array size. nullptr represents a runtime-array.
  /// @param args the arguments for the array constructor
  /// @return an `ast::TypeConstructorExpression` of an array with element type
  /// `subtype`, constructed with the values `args`.
  template <typename EXPR, typename... ARGS>
  const ast::TypeConstructorExpression* array(const ast::Type* subtype,
                                              EXPR&& n,
                                              ARGS&&... args) {
    return Construct(ty.array(subtype, std::forward<EXPR>(n)),
                     std::forward<ARGS>(args)...);
  }

  /// @param name the variable name
  /// @param type the variable type
  /// @param optional the optional variable settings.
  /// Can be any of the following, in any order:
  ///   * ast::StorageClass   - specifies the variable storage class
  ///   * ast::Access         - specifies the variable's access control
  ///   * ast::Expression*    - specifies the variable's initializer expression
  ///   * ast::DecorationList - specifies the variable's decorations
  /// Note that repeated arguments of the same type will use the last argument's
  /// value.
  /// @returns a `ast::Variable` with the given name, type and additional
  /// options
  template <typename NAME, typename... OPTIONAL>
  const ast::Variable* Var(NAME&& name,
                           const ast::Type* type,
                           OPTIONAL&&... optional) {
    VarOptionals opts(std::forward<OPTIONAL>(optional)...);
    return create<ast::Variable>(Sym(std::forward<NAME>(name)), opts.storage,
                                 opts.access, type, false, opts.constructor,
                                 std::move(opts.decorations));
  }

  /// @param source the variable source
  /// @param name the variable name
  /// @param type the variable type
  /// @param optional the optional variable settings.
  /// Can be any of the following, in any order:
  ///   * ast::StorageClass   - specifies the variable storage class
  ///   * ast::Access         - specifies the variable's access control
  ///   * ast::Expression*    - specifies the variable's initializer expression
  ///   * ast::DecorationList - specifies the variable's decorations
  /// Note that repeated arguments of the same type will use the last argument's
  /// value.
  /// @returns a `ast::Variable` with the given name, storage and type
  template <typename NAME, typename... OPTIONAL>
  const ast::Variable* Var(const Source& source,
                           NAME&& name,
                           const ast::Type* type,
                           OPTIONAL&&... optional) {
    VarOptionals opts(std::forward<OPTIONAL>(optional)...);
    return create<ast::Variable>(source, Sym(std::forward<NAME>(name)),
                                 opts.storage, opts.access, type, false,
                                 opts.constructor, std::move(opts.decorations));
  }

  /// @param name the variable name
  /// @param type the variable type
  /// @param constructor constructor expression
  /// @param decorations optional variable decorations
  /// @returns a constant `ast::Variable` with the given name and type
  template <typename NAME>
  const ast::Variable* Const(NAME&& name,
                             const ast::Type* type,
                             const ast::Expression* constructor,
                             ast::DecorationList decorations = {}) {
    return create<ast::Variable>(
        Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
        ast::Access::kUndefined, type, true, constructor, decorations);
  }

  /// @param source the variable source
  /// @param name the variable name
  /// @param type the variable type
  /// @param constructor constructor expression
  /// @param decorations optional variable decorations
  /// @returns a constant `ast::Variable` with the given name and type
  template <typename NAME>
  const ast::Variable* Const(const Source& source,
                             NAME&& name,
                             const ast::Type* type,
                             const ast::Expression* constructor,
                             ast::DecorationList decorations = {}) {
    return create<ast::Variable>(
        source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
        ast::Access::kUndefined, type, true, constructor, decorations);
  }

  /// @param name the parameter name
  /// @param type the parameter type
  /// @param decorations optional parameter decorations
  /// @returns a constant `ast::Variable` with the given name and type
  template <typename NAME>
  const ast::Variable* Param(NAME&& name,
                             const ast::Type* type,
                             ast::DecorationList decorations = {}) {
    return create<ast::Variable>(
        Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
        ast::Access::kUndefined, type, true, nullptr, decorations);
  }

  /// @param source the parameter source
  /// @param name the parameter name
  /// @param type the parameter type
  /// @param decorations optional parameter decorations
  /// @returns a constant `ast::Variable` with the given name and type
  template <typename NAME>
  const ast::Variable* Param(const Source& source,
                             NAME&& name,
                             const ast::Type* type,
                             ast::DecorationList decorations = {}) {
    return create<ast::Variable>(
        source, Sym(std::forward<NAME>(name)), ast::StorageClass::kNone,
        ast::Access::kUndefined, type, true, nullptr, decorations);
  }

  /// @param name the variable name
  /// @param type the variable type
  /// @param optional the optional variable settings.
  /// Can be any of the following, in any order:
  ///   * ast::StorageClass   - specifies the variable storage class
  ///   * ast::Access         - specifies the variable's access control
  ///   * ast::Expression*    - specifies the variable's initializer expression
  ///   * ast::DecorationList - specifies the variable's decorations
  /// Note that repeated arguments of the same type will use the last argument's
  /// value.
  /// @returns a new `ast::Variable`, which is automatically registered as a
  /// global variable with the ast::Module.
  template <typename NAME,
            typename... OPTIONAL,
            typename = DisableIfSource<NAME>>
  const ast::Variable* Global(NAME&& name,
                              const ast::Type* type,
                              OPTIONAL&&... optional) {
    auto* var = Var(std::forward<NAME>(name), type,
                    std::forward<OPTIONAL>(optional)...);
    AST().AddGlobalVariable(var);
    return var;
  }

  /// @param source the variable source
  /// @param name the variable name
  /// @param type the variable type
  /// @param optional the optional variable settings.
  /// Can be any of the following, in any order:
  ///   * ast::StorageClass   - specifies the variable storage class
  ///   * ast::Access         - specifies the variable's access control
  ///   * ast::Expression*    - specifies the variable's initializer expression
  ///   * ast::DecorationList - specifies the variable's decorations
  /// Note that repeated arguments of the same type will use the last argument's
  /// value.
  /// @returns a new `ast::Variable`, which is automatically registered as a
  /// global variable with the ast::Module.
  template <typename NAME, typename... OPTIONAL>
  const ast::Variable* Global(const Source& source,
                              NAME&& name,
                              const ast::Type* type,
                              OPTIONAL&&... optional) {
    auto* var = Var(source, std::forward<NAME>(name), type,
                    std::forward<OPTIONAL>(optional)...);
    AST().AddGlobalVariable(var);
    return var;
  }

  /// @param name the variable name
  /// @param type the variable type
  /// @param constructor constructor expression
  /// @param decorations optional variable decorations
  /// @returns a const `ast::Variable` constructed by calling Var() with the
  /// arguments of `args`, which is automatically registered as a global
  /// variable with the ast::Module.
  template <typename NAME>
  const ast::Variable* GlobalConst(NAME&& name,
                                   const ast::Type* type,
                                   const ast::Expression* constructor,
                                   ast::DecorationList decorations = {}) {
    auto* var = Const(std::forward<NAME>(name), type, constructor,
                      std::move(decorations));
    AST().AddGlobalVariable(var);
    return var;
  }

  /// @param source the variable source
  /// @param name the variable name
  /// @param type the variable type
  /// @param constructor constructor expression
  /// @param decorations optional variable decorations
  /// @returns a const `ast::Variable` constructed by calling Var() with the
  /// arguments of `args`, which is automatically registered as a global
  /// variable with the ast::Module.
  template <typename NAME>
  const ast::Variable* GlobalConst(const Source& source,
                                   NAME&& name,
                                   const ast::Type* type,
                                   const ast::Expression* constructor,
                                   ast::DecorationList decorations = {}) {
    auto* var = Const(source, std::forward<NAME>(name), type, constructor,
                      std::move(decorations));
    AST().AddGlobalVariable(var);
    return var;
  }

  /// @param source the source information
  /// @param expr the expression to take the address of
  /// @return an ast::UnaryOpExpression that takes the address of `expr`
  template <typename EXPR>
  const ast::UnaryOpExpression* AddressOf(const Source& source, EXPR&& expr) {
    return create<ast::UnaryOpExpression>(source, ast::UnaryOp::kAddressOf,
                                          Expr(std::forward<EXPR>(expr)));
  }

  /// @param expr the expression to take the address of
  /// @return an ast::UnaryOpExpression that takes the address of `expr`
  template <typename EXPR>
  const ast::UnaryOpExpression* AddressOf(EXPR&& expr) {
    return create<ast::UnaryOpExpression>(ast::UnaryOp::kAddressOf,
                                          Expr(std::forward<EXPR>(expr)));
  }

  /// @param source the source information
  /// @param expr the expression to perform an indirection on
  /// @return an ast::UnaryOpExpression that dereferences the pointer `expr`
  template <typename EXPR>
  const ast::UnaryOpExpression* Deref(const Source& source, EXPR&& expr) {
    return create<ast::UnaryOpExpression>(source, ast::UnaryOp::kIndirection,
                                          Expr(std::forward<EXPR>(expr)));
  }

  /// @param expr the expression to perform an indirection on
  /// @return an ast::UnaryOpExpression that dereferences the pointer `expr`
  template <typename EXPR>
  const ast::UnaryOpExpression* Deref(EXPR&& expr) {
    return create<ast::UnaryOpExpression>(ast::UnaryOp::kIndirection,
                                          Expr(std::forward<EXPR>(expr)));
  }

  /// @param source the source information
  /// @param func the function name
  /// @param args the function call arguments
  /// @returns a `ast::CallExpression` to the function `func`, with the
  /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
  template <typename NAME, typename... ARGS>
  const ast::CallExpression* Call(const Source& source,
                                  NAME&& func,
                                  ARGS&&... args) {
    return create<ast::CallExpression>(source, Expr(func),
                                       ExprList(std::forward<ARGS>(args)...));
  }

  /// @param func the function name
  /// @param args the function call arguments
  /// @returns a `ast::CallExpression` to the function `func`, with the
  /// arguments of `args` converted to `ast::Expression`s using `Expr()`.
  template <typename NAME, typename... ARGS, typename = DisableIfSource<NAME>>
  const ast::CallExpression* Call(NAME&& func, ARGS&&... args) {
    return create<ast::CallExpression>(Expr(func),
                                       ExprList(std::forward<ARGS>(args)...));
  }

  /// @param source the source information
  /// @param call the call expression to wrap in a call statement
  /// @returns a `ast::CallStatement` for the given call expression
  const ast::CallStatement* CallStmt(const Source& source,
                                     const ast::CallExpression* call) {
    return create<ast::CallStatement>(source, call);
  }

  /// @param call the call expression to wrap in a call statement
  /// @returns a `ast::CallStatement` for the given call expression
  const ast::CallStatement* CallStmt(const ast::CallExpression* call) {
    return create<ast::CallStatement>(call);
  }

  /// @param source the source information
  /// @returns a `ast::PhonyExpression`
  const ast::PhonyExpression* Phony(const Source& source) {
    return create<ast::PhonyExpression>(source);
  }

  /// @returns a `ast::PhonyExpression`
  const ast::PhonyExpression* Phony() { return create<ast::PhonyExpression>(); }

  /// @param expr the expression to ignore
  /// @returns a `ast::AssignmentStatement` that assigns 'expr' to the phony
  /// (underscore) variable.
  template <typename EXPR>
  const ast::AssignmentStatement* Ignore(EXPR&& expr) {
    return create<ast::AssignmentStatement>(Phony(), Expr(expr));
  }

  /// @param lhs the left hand argument to the addition operation
  /// @param rhs the right hand argument to the addition operation
  /// @returns a `ast::BinaryExpression` summing the arguments `lhs` and `rhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Add(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kAdd,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the and operation
  /// @param rhs the right hand argument to the and operation
  /// @returns a `ast::BinaryExpression` bitwise anding `lhs` and `rhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* And(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kAnd,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the or operation
  /// @param rhs the right hand argument to the or operation
  /// @returns a `ast::BinaryExpression` bitwise or-ing `lhs` and `rhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Or(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kOr,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the subtraction operation
  /// @param rhs the right hand argument to the subtraction operation
  /// @returns a `ast::BinaryExpression` subtracting `rhs` from `lhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Sub(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kSubtract,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the multiplication operation
  /// @param rhs the right hand argument to the multiplication operation
  /// @returns a `ast::BinaryExpression` multiplying `rhs` from `lhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Mul(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kMultiply,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param source the source information
  /// @param lhs the left hand argument to the multiplication operation
  /// @param rhs the right hand argument to the multiplication operation
  /// @returns a `ast::BinaryExpression` multiplying `rhs` from `lhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Mul(const Source& source, LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(source, ast::BinaryOp::kMultiply,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the division operation
  /// @param rhs the right hand argument to the division operation
  /// @returns a `ast::BinaryExpression` dividing `lhs` by `rhs`
  template <typename LHS, typename RHS>
  const ast::Expression* Div(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kDivide,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the bit shift right operation
  /// @param rhs the right hand argument to the bit shift right operation
  /// @returns a `ast::BinaryExpression` bit shifting right `lhs` by `rhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Shr(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kShiftRight,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param lhs the left hand argument to the bit shift left operation
  /// @param rhs the right hand argument to the bit shift left operation
  /// @returns a `ast::BinaryExpression` bit shifting left `lhs` by `rhs`
  template <typename LHS, typename RHS>
  const ast::BinaryExpression* Shl(LHS&& lhs, RHS&& rhs) {
    return create<ast::BinaryExpression>(ast::BinaryOp::kShiftLeft,
                                         Expr(std::forward<LHS>(lhs)),
                                         Expr(std::forward<RHS>(rhs)));
  }

  /// @param source the source information
  /// @param arr the array argument for the array accessor expression
  /// @param idx the index argument for the array accessor expression
  /// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
  template <typename ARR, typename IDX>
  const ast::ArrayAccessorExpression* IndexAccessor(const Source& source,
                                                    ARR&& arr,
                                                    IDX&& idx) {
    return create<ast::ArrayAccessorExpression>(
        source, Expr(std::forward<ARR>(arr)), Expr(std::forward<IDX>(idx)));
  }

  /// @param arr the array argument for the array accessor expression
  /// @param idx the index argument for the array accessor expression
  /// @returns a `ast::ArrayAccessorExpression` that indexes `arr` with `idx`
  template <typename ARR, typename IDX>
  const ast::ArrayAccessorExpression* IndexAccessor(ARR&& arr, IDX&& idx) {
    return create<ast::ArrayAccessorExpression>(Expr(std::forward<ARR>(arr)),
                                                Expr(std::forward<IDX>(idx)));
  }

  /// @param source the source information
  /// @param obj the object for the member accessor expression
  /// @param idx the index argument for the array accessor expression
  /// @returns a `ast::MemberAccessorExpression` that indexes `obj` with `idx`
  template <typename OBJ, typename IDX>
  const ast::MemberAccessorExpression* MemberAccessor(const Source& source,
                                                      OBJ&& obj,
                                                      IDX&& idx) {
    return create<ast::MemberAccessorExpression>(
        source, Expr(std::forward<OBJ>(obj)), Expr(std::forward<IDX>(idx)));
  }

  /// @param obj the object for the member accessor expression
  /// @param idx the index argument for the array accessor expression
  /// @returns a `ast::MemberAccessorExpression` that indexes `obj` with `idx`
  template <typename OBJ, typename IDX>
  const ast::MemberAccessorExpression* MemberAccessor(OBJ&& obj, IDX&& idx) {
    return create<ast::MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
                                                 Expr(std::forward<IDX>(idx)));
  }

  /// Creates a ast::StructMemberOffsetDecoration
  /// @param val the offset value
  /// @returns the offset decoration pointer
  const ast::StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
    return create<ast::StructMemberOffsetDecoration>(source_, val);
  }

  /// Creates a ast::StructMemberSizeDecoration
  /// @param source the source information
  /// @param val the size value
  /// @returns the size decoration pointer
  const ast::StructMemberSizeDecoration* MemberSize(const Source& source,
                                                    uint32_t val) {
    return create<ast::StructMemberSizeDecoration>(source, val);
  }

  /// Creates a ast::StructMemberSizeDecoration
  /// @param val the size value
  /// @returns the size decoration pointer
  const ast::StructMemberSizeDecoration* MemberSize(uint32_t val) {
    return create<ast::StructMemberSizeDecoration>(source_, val);
  }

  /// Creates a ast::StructMemberAlignDecoration
  /// @param source the source information
  /// @param val the align value
  /// @returns the align decoration pointer
  const ast::StructMemberAlignDecoration* MemberAlign(const Source& source,
                                                      uint32_t val) {
    return create<ast::StructMemberAlignDecoration>(source, val);
  }

  /// Creates a ast::StructMemberAlignDecoration
  /// @param val the align value
  /// @returns the align decoration pointer
  const ast::StructMemberAlignDecoration* MemberAlign(uint32_t val) {
    return create<ast::StructMemberAlignDecoration>(source_, val);
  }

  /// Creates a ast::StructBlockDecoration
  /// @returns the struct block decoration pointer
  const ast::StructBlockDecoration* StructBlock() {
    return create<ast::StructBlockDecoration>();
  }

  /// Creates the ast::GroupDecoration
  /// @param value group decoration index
  /// @returns the group decoration pointer
  const ast::GroupDecoration* Group(uint32_t value) {
    return create<ast::GroupDecoration>(value);
  }

  /// Creates the ast::BindingDecoration
  /// @param value the binding index
  /// @returns the binding deocration pointer
  const ast::BindingDecoration* Binding(uint32_t value) {
    return create<ast::BindingDecoration>(value);
  }

  /// Convenience function to create both a ast::GroupDecoration and
  /// ast::BindingDecoration
  /// @param group the group index
  /// @param binding the binding index
  /// @returns a decoration list with both the group and binding decorations
  ast::DecorationList GroupAndBinding(uint32_t group, uint32_t binding) {
    return {Group(group), Binding(binding)};
  }

  /// Creates an ast::Function and registers it with the ast::Module.
  /// @param source the source information
  /// @param name the function name
  /// @param params the function parameters
  /// @param type the function return type
  /// @param body the function body
  /// @param decorations the optional function decorations
  /// @param return_type_decorations the optional function return type
  /// decorations
  /// @returns the function pointer
  template <typename NAME>
  const ast::Function* Func(const Source& source,
                            NAME&& name,
                            ast::VariableList params,
                            const ast::Type* type,
                            ast::StatementList body,
                            ast::DecorationList decorations = {},
                            ast::DecorationList return_type_decorations = {}) {
    auto* func =
        create<ast::Function>(source, Sym(std::forward<NAME>(name)), params,
                              type, create<ast::BlockStatement>(body),
                              decorations, return_type_decorations);
    AST().AddFunction(func);
    return func;
  }

  /// Creates an ast::Function and registers it with the ast::Module.
  /// @param name the function name
  /// @param params the function parameters
  /// @param type the function return type
  /// @param body the function body
  /// @param decorations the optional function decorations
  /// @param return_type_decorations the optional function return type
  /// decorations
  /// @returns the function pointer
  template <typename NAME>
  const ast::Function* Func(NAME&& name,
                            ast::VariableList params,
                            const ast::Type* type,
                            ast::StatementList body,
                            ast::DecorationList decorations = {},
                            ast::DecorationList return_type_decorations = {}) {
    auto* func = create<ast::Function>(Sym(std::forward<NAME>(name)), params,
                                       type, create<ast::BlockStatement>(body),
                                       decorations, return_type_decorations);
    AST().AddFunction(func);
    return func;
  }

  /// Creates an ast::BreakStatement
  /// @param source the source information
  /// @returns the break statement pointer
  const ast::BreakStatement* Break(const Source& source) {
    return create<ast::BreakStatement>(source);
  }

  /// Creates an ast::BreakStatement
  /// @returns the break statement pointer
  const ast::BreakStatement* Break() { return create<ast::BreakStatement>(); }

  /// Creates an ast::ReturnStatement with no return value
  /// @param source the source information
  /// @returns the return statement pointer
  const ast::ReturnStatement* Return(const Source& source) {
    return create<ast::ReturnStatement>(source);
  }

  /// Creates an ast::ReturnStatement with no return value
  /// @returns the return statement pointer
  const ast::ReturnStatement* Return() {
    return create<ast::ReturnStatement>();
  }

  /// Creates an ast::ReturnStatement with the given return value
  /// @param source the source information
  /// @param val the return value
  /// @returns the return statement pointer
  template <typename EXPR>
  const ast::ReturnStatement* Return(const Source& source, EXPR&& val) {
    return create<ast::ReturnStatement>(source, Expr(std::forward<EXPR>(val)));
  }

  /// Creates an ast::ReturnStatement with the given return value
  /// @param val the return value
  /// @returns the return statement pointer
  template <typename EXPR, typename = DisableIfSource<EXPR>>
  const ast::ReturnStatement* Return(EXPR&& val) {
    return create<ast::ReturnStatement>(Expr(std::forward<EXPR>(val)));
  }

  /// Creates a ast::Alias registering it with the AST().TypeDecls().
  /// @param source the source information
  /// @param name the alias name
  /// @param type the alias target type
  /// @returns the alias type
  template <typename NAME>
  const ast::Alias* Alias(const Source& source,
                          NAME&& name,
                          const ast::Type* type) {
    auto* out = ty.alias(source, std::forward<NAME>(name), type);
    AST().AddTypeDecl(out);
    return out;
  }

  /// Creates a ast::Alias registering it with the AST().TypeDecls().
  /// @param name the alias name
  /// @param type the alias target type
  /// @returns the alias type
  template <typename NAME>
  const ast::Alias* Alias(NAME&& name, const ast::Type* type) {
    auto* out = ty.alias(std::forward<NAME>(name), type);
    AST().AddTypeDecl(out);
    return out;
  }

  /// Creates a ast::Struct registering it with the AST().TypeDecls().
  /// @param source the source information
  /// @param name the struct name
  /// @param members the struct members
  /// @param decorations the optional struct decorations
  /// @returns the struct type
  template <typename NAME>
  const ast::Struct* Structure(const Source& source,
                               NAME&& name,
                               ast::StructMemberList members,
                               ast::DecorationList decorations = {}) {
    auto sym = Sym(std::forward<NAME>(name));
    auto* type = create<ast::Struct>(source, sym, std::move(members),
                                     std::move(decorations));
    AST().AddTypeDecl(type);
    return type;
  }

  /// Creates a ast::Struct registering it with the AST().TypeDecls().
  /// @param name the struct name
  /// @param members the struct members
  /// @param decorations the optional struct decorations
  /// @returns the struct type
  template <typename NAME>
  const ast::Struct* Structure(NAME&& name,
                               ast::StructMemberList members,
                               ast::DecorationList decorations = {}) {
    auto sym = Sym(std::forward<NAME>(name));
    auto* type =
        create<ast::Struct>(sym, std::move(members), std::move(decorations));
    AST().AddTypeDecl(type);
    return type;
  }

  /// Creates a ast::StructMember
  /// @param source the source information
  /// @param name the struct member name
  /// @param type the struct member type
  /// @param decorations the optional struct member decorations
  /// @returns the struct member pointer
  template <typename NAME>
  const ast::StructMember* Member(const Source& source,
                                  NAME&& name,
                                  const ast::Type* type,
                                  ast::DecorationList decorations = {}) {
    return create<ast::StructMember>(source, Sym(std::forward<NAME>(name)),
                                     type, std::move(decorations));
  }

  /// Creates a ast::StructMember
  /// @param name the struct member name
  /// @param type the struct member type
  /// @param decorations the optional struct member decorations
  /// @returns the struct member pointer
  template <typename NAME>
  const ast::StructMember* Member(NAME&& name,
                                  const ast::Type* type,
                                  ast::DecorationList decorations = {}) {
    return create<ast::StructMember>(source_, Sym(std::forward<NAME>(name)),
                                     type, std::move(decorations));
  }

  /// Creates a ast::StructMember with the given byte offset
  /// @param offset the offset to use in the StructMemberOffsetDecoration
  /// @param name the struct member name
  /// @param type the struct member type
  /// @returns the struct member pointer
  template <typename NAME>
  const ast::StructMember* Member(uint32_t offset,
                                  NAME&& name,
                                  const ast::Type* type) {
    return create<ast::StructMember>(
        source_, Sym(std::forward<NAME>(name)), type,
        ast::DecorationList{
            create<ast::StructMemberOffsetDecoration>(offset),
        });
  }

  /// Creates a ast::BlockStatement with input statements
  /// @param source the source information for the block
  /// @param statements statements of block
  /// @returns the block statement pointer
  template <typename... Statements>
  const ast::BlockStatement* Block(const Source& source,
                                   Statements&&... statements) {
    return create<ast::BlockStatement>(
        source, ast::StatementList{std::forward<Statements>(statements)...});
  }

  /// Creates a ast::BlockStatement with input statements
  /// @param statements statements of block
  /// @returns the block statement pointer
  template <typename... STATEMENTS, typename = DisableIfSource<STATEMENTS...>>
  const ast::BlockStatement* Block(STATEMENTS&&... statements) {
    return create<ast::BlockStatement>(
        ast::StatementList{std::forward<STATEMENTS>(statements)...});
  }

  /// Creates a ast::ElseStatement with input condition and body
  /// @param condition the else condition expression
  /// @param body the else body
  /// @returns the else statement pointer
  template <typename CONDITION>
  const ast::ElseStatement* Else(CONDITION&& condition,
                                 const ast::BlockStatement* body) {
    return create<ast::ElseStatement>(Expr(std::forward<CONDITION>(condition)),
                                      body);
  }

  /// Creates a ast::IfStatement with input condition, body, and optional
  /// variadic else statements
  /// @param condition the if statement condition expression
  /// @param body the if statement body
  /// @param elseStatements optional variadic else statements
  /// @returns the if statement pointer
  template <typename CONDITION, typename... ELSE_STATEMENTS>
  const ast::IfStatement* If(CONDITION&& condition,
                             const ast::BlockStatement* body,
                             ELSE_STATEMENTS&&... elseStatements) {
    return create<ast::IfStatement>(
        Expr(std::forward<CONDITION>(condition)), body,
        ast::ElseStatementList{
            std::forward<ELSE_STATEMENTS>(elseStatements)...});
  }

  /// Creates a ast::AssignmentStatement with input lhs and rhs expressions
  /// @param source the source information
  /// @param lhs the left hand side expression initializer
  /// @param rhs the right hand side expression initializer
  /// @returns the assignment statement pointer
  template <typename LhsExpressionInit, typename RhsExpressionInit>
  const ast::AssignmentStatement* Assign(const Source& source,
                                         LhsExpressionInit&& lhs,
                                         RhsExpressionInit&& rhs) {
    return create<ast::AssignmentStatement>(
        source, Expr(std::forward<LhsExpressionInit>(lhs)),
        Expr(std::forward<RhsExpressionInit>(rhs)));
  }

  /// Creates a ast::AssignmentStatement with input lhs and rhs expressions
  /// @param lhs the left hand side expression initializer
  /// @param rhs the right hand side expression initializer
  /// @returns the assignment statement pointer
  template <typename LhsExpressionInit, typename RhsExpressionInit>
  const ast::AssignmentStatement* Assign(LhsExpressionInit&& lhs,
                                         RhsExpressionInit&& rhs) {
    return create<ast::AssignmentStatement>(
        Expr(std::forward<LhsExpressionInit>(lhs)),
        Expr(std::forward<RhsExpressionInit>(rhs)));
  }

  /// Creates a ast::LoopStatement with input body and optional continuing
  /// @param body the loop body
  /// @param continuing the optional continuing block
  /// @returns the loop statement pointer
  const ast::LoopStatement* Loop(
      const ast::BlockStatement* body,
      const ast::BlockStatement* continuing = nullptr) {
    return create<ast::LoopStatement>(body, continuing);
  }

  /// Creates a ast::ForLoopStatement with input body and optional initializer,
  /// condition and continuing.
  /// @param source the source information
  /// @param init the optional loop initializer
  /// @param cond the optional loop condition
  /// @param cont the optional loop continuing
  /// @param body the loop body
  /// @returns the for loop statement pointer
  template <typename COND>
  const ast::ForLoopStatement* For(const Source& source,
                                   const ast::Statement* init,
                                   COND&& cond,
                                   const ast::Statement* cont,
                                   const ast::BlockStatement* body) {
    return create<ast::ForLoopStatement>(
        source, init, Expr(std::forward<COND>(cond)), cont, body);
  }

  /// Creates a ast::ForLoopStatement with input body and optional initializer,
  /// condition and continuing.
  /// @param init the optional loop initializer
  /// @param cond the optional loop condition
  /// @param cont the optional loop continuing
  /// @param body the loop body
  /// @returns the for loop statement pointer
  template <typename COND>
  const ast::ForLoopStatement* For(const ast::Statement* init,
                                   COND&& cond,
                                   const ast::Statement* cont,
                                   const ast::BlockStatement* body) {
    return create<ast::ForLoopStatement>(init, Expr(std::forward<COND>(cond)),
                                         cont, body);
  }

  /// Creates a ast::VariableDeclStatement for the input variable
  /// @param source the source information
  /// @param var the variable to wrap in a decl statement
  /// @returns the variable decl statement pointer
  const ast::VariableDeclStatement* Decl(const Source& source,
                                         const ast::Variable* var) {
    return create<ast::VariableDeclStatement>(source, var);
  }

  /// Creates a ast::VariableDeclStatement for the input variable
  /// @param var the variable to wrap in a decl statement
  /// @returns the variable decl statement pointer
  const ast::VariableDeclStatement* Decl(const ast::Variable* var) {
    return create<ast::VariableDeclStatement>(var);
  }

  /// Creates a ast::SwitchStatement with input expression and cases
  /// @param source the source information
  /// @param condition the condition expression initializer
  /// @param cases case statements
  /// @returns the switch statement pointer
  template <typename ExpressionInit, typename... Cases>
  const ast::SwitchStatement* Switch(const Source& source,
                                     ExpressionInit&& condition,
                                     Cases&&... cases) {
    return create<ast::SwitchStatement>(
        source, Expr(std::forward<ExpressionInit>(condition)),
        ast::CaseStatementList{std::forward<Cases>(cases)...});
  }

  /// Creates a ast::SwitchStatement with input expression and cases
  /// @param condition the condition expression initializer
  /// @param cases case statements
  /// @returns the switch statement pointer
  template <typename ExpressionInit,
            typename... Cases,
            typename = DisableIfSource<ExpressionInit>>
  const ast::SwitchStatement* Switch(ExpressionInit&& condition,
                                     Cases&&... cases) {
    return create<ast::SwitchStatement>(
        Expr(std::forward<ExpressionInit>(condition)),
        ast::CaseStatementList{std::forward<Cases>(cases)...});
  }

  /// Creates a ast::CaseStatement with input list of selectors, and body
  /// @param source the source information
  /// @param selectors list of selectors
  /// @param body the case body
  /// @returns the case statement pointer
  const ast::CaseStatement* Case(const Source& source,
                                 ast::CaseSelectorList selectors,
                                 const ast::BlockStatement* body = nullptr) {
    return create<ast::CaseStatement>(source, std::move(selectors),
                                      body ? body : Block());
  }

  /// Creates a ast::CaseStatement with input list of selectors, and body
  /// @param selectors list of selectors
  /// @param body the case body
  /// @returns the case statement pointer
  const ast::CaseStatement* Case(ast::CaseSelectorList selectors,
                                 const ast::BlockStatement* body = nullptr) {
    return create<ast::CaseStatement>(std::move(selectors),
                                      body ? body : Block());
  }

  /// Convenient overload that takes a single selector
  /// @param selector a single case selector
  /// @param body the case body
  /// @returns the case statement pointer
  const ast::CaseStatement* Case(const ast::IntLiteral* selector,
                                 const ast::BlockStatement* body = nullptr) {
    return Case(ast::CaseSelectorList{selector}, body);
  }

  /// Convenience function that creates a 'default' ast::CaseStatement
  /// @param source the source information
  /// @param body the case body
  /// @returns the case statement pointer
  const ast::CaseStatement* DefaultCase(
      const Source& source,
      const ast::BlockStatement* body = nullptr) {
    return Case(source, ast::CaseSelectorList{}, body);
  }

  /// Convenience function that creates a 'default' ast::CaseStatement
  /// @param body the case body
  /// @returns the case statement pointer
  const ast::CaseStatement* DefaultCase(
      const ast::BlockStatement* body = nullptr) {
    return Case(ast::CaseSelectorList{}, body);
  }

  /// Creates an ast::BuiltinDecoration
  /// @param source the source information
  /// @param builtin the builtin value
  /// @returns the builtin decoration pointer
  const ast::BuiltinDecoration* Builtin(const Source& source,
                                        ast::Builtin builtin) {
    return create<ast::BuiltinDecoration>(source, builtin);
  }

  /// Creates an ast::BuiltinDecoration
  /// @param builtin the builtin value
  /// @returns the builtin decoration pointer
  const ast::BuiltinDecoration* Builtin(ast::Builtin builtin) {
    return create<ast::BuiltinDecoration>(source_, builtin);
  }

  /// Creates an ast::InterpolateDecoration
  /// @param source the source information
  /// @param type the interpolation type
  /// @param sampling the interpolation sampling
  /// @returns the interpolate decoration pointer
  const ast::InterpolateDecoration* Interpolate(
      const Source& source,
      ast::InterpolationType type,
      ast::InterpolationSampling sampling) {
    return create<ast::InterpolateDecoration>(source, type, sampling);
  }

  /// Creates an ast::InterpolateDecoration
  /// @param type the interpolation type
  /// @param sampling the interpolation sampling
  /// @returns the interpolate decoration pointer
  const ast::InterpolateDecoration* Interpolate(
      ast::InterpolationType type,
      ast::InterpolationSampling sampling) {
    return create<ast::InterpolateDecoration>(source_, type, sampling);
  }

  /// Creates an ast::InvariantDecoration
  /// @param source the source information
  /// @returns the invariant decoration pointer
  const ast::InvariantDecoration* Invariant(const Source& source) {
    return create<ast::InvariantDecoration>(source);
  }

  /// Creates an ast::InvariantDecoration
  /// @returns the invariant decoration pointer
  const ast::InvariantDecoration* Invariant() {
    return create<ast::InvariantDecoration>(source_);
  }

  /// Creates an ast::LocationDecoration
  /// @param source the source information
  /// @param location the location value
  /// @returns the location decoration pointer
  const ast::LocationDecoration* Location(const Source& source,
                                          uint32_t location) {
    return create<ast::LocationDecoration>(source, location);
  }

  /// Creates an ast::LocationDecoration
  /// @param location the location value
  /// @returns the location decoration pointer
  const ast::LocationDecoration* Location(uint32_t location) {
    return create<ast::LocationDecoration>(source_, location);
  }

  /// Creates an ast::OverrideDecoration with a specific constant ID
  /// @param source the source information
  /// @param id the id value
  /// @returns the override decoration pointer
  const ast::OverrideDecoration* Override(const Source& source, uint32_t id) {
    return create<ast::OverrideDecoration>(source, id);
  }

  /// Creates an ast::OverrideDecoration with a specific constant ID
  /// @param id the optional id value
  /// @returns the override decoration pointer
  const ast::OverrideDecoration* Override(uint32_t id) {
    return Override(source_, id);
  }

  /// Creates an ast::OverrideDecoration without a constant ID
  /// @param source the source information
  /// @returns the override decoration pointer
  const ast::OverrideDecoration* Override(const Source& source) {
    return create<ast::OverrideDecoration>(source);
  }

  /// Creates an ast::OverrideDecoration without a constant ID
  /// @returns the override decoration pointer
  const ast::OverrideDecoration* Override() { return Override(source_); }

  /// Creates an ast::StageDecoration
  /// @param source the source information
  /// @param stage the pipeline stage
  /// @returns the stage decoration pointer
  const ast::StageDecoration* Stage(const Source& source,
                                    ast::PipelineStage stage) {
    return create<ast::StageDecoration>(source, stage);
  }

  /// Creates an ast::StageDecoration
  /// @param stage the pipeline stage
  /// @returns the stage decoration pointer
  const ast::StageDecoration* Stage(ast::PipelineStage stage) {
    return create<ast::StageDecoration>(source_, stage);
  }

  /// Creates an ast::WorkgroupDecoration
  /// @param x the x dimension expression
  /// @returns the workgroup decoration pointer
  template <typename EXPR_X>
  const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x) {
    return WorkgroupSize(std::forward<EXPR_X>(x), nullptr, nullptr);
  }

  /// Creates an ast::WorkgroupDecoration
  /// @param x the x dimension expression
  /// @param y the y dimension expression
  /// @returns the workgroup decoration pointer
  template <typename EXPR_X, typename EXPR_Y>
  const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x, EXPR_Y&& y) {
    return WorkgroupSize(std::forward<EXPR_X>(x), std::forward<EXPR_Y>(y),
                         nullptr);
  }

  /// Creates an ast::WorkgroupDecoration
  /// @param source the source information
  /// @param x the x dimension expression
  /// @param y the y dimension expression
  /// @param z the z dimension expression
  /// @returns the workgroup decoration pointer
  template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
  const ast::WorkgroupDecoration* WorkgroupSize(const Source& source,
                                                EXPR_X&& x,
                                                EXPR_Y&& y,
                                                EXPR_Z&& z) {
    return create<ast::WorkgroupDecoration>(
        source, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
        Expr(std::forward<EXPR_Z>(z)));
  }

  /// Creates an ast::WorkgroupDecoration
  /// @param x the x dimension expression
  /// @param y the y dimension expression
  /// @param z the z dimension expression
  /// @returns the workgroup decoration pointer
  template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
  const ast::WorkgroupDecoration* WorkgroupSize(EXPR_X&& x,
                                                EXPR_Y&& y,
                                                EXPR_Z&& z) {
    return create<ast::WorkgroupDecoration>(
        source_, Expr(std::forward<EXPR_X>(x)), Expr(std::forward<EXPR_Y>(y)),
        Expr(std::forward<EXPR_Z>(z)));
  }

  /// Creates an ast::DisableValidationDecoration
  /// @param validation the validation to disable
  /// @returns the disable validation decoration pointer
  const ast::DisableValidationDecoration* Disable(
      ast::DisabledValidation validation) {
    return ASTNodes().Create<ast::DisableValidationDecoration>(ID(),
                                                               validation);
  }

  /// Sets the current builder source to `src`
  /// @param src the Source used for future create() calls
  void SetSource(const Source& src) {
    AssertNotMoved();
    source_ = src;
  }

  /// Sets the current builder source to `loc`
  /// @param loc the Source used for future create() calls
  void SetSource(const Source::Location& loc) {
    AssertNotMoved();
    source_ = Source(loc);
  }

  /// Marks that the given transform has been applied to this program.
  /// @param transform the transform that has been applied
  void SetTransformApplied(const CastableBase* transform) {
    transforms_applied_.emplace(&transform->TypeInfo());
  }

  /// Marks that the given transform `T` has been applied to this program.
  template <typename T>
  void SetTransformApplied() {
    transforms_applied_.emplace(&TypeInfo::Of<T>());
  }

  /// Marks that the transforms with the given TypeInfos have been applied to
  /// this program.
  /// @param transforms the set of transform TypeInfos that has been applied
  void SetTransformApplied(
      const std::unordered_set<const TypeInfo*>& transforms) {
    for (auto* transform : transforms) {
      transforms_applied_.emplace(transform);
    }
  }

  /// @returns true if the transform of type `T` was applied.
  template <typename T>
  bool HasTransformApplied() {
    return transforms_applied_.count(&TypeInfo::Of<T>());
  }

  /// @return the TypeInfo pointers of all transforms that have been applied to
  /// this program.
  std::unordered_set<const TypeInfo*> TransformsApplied() const {
    return transforms_applied_;
  }

  /// Helper for returning the resolved semantic type of the expression `expr`.
  /// @note As the Resolver is run when the Program is built, this will only be
  /// useful for the Resolver itself and tests that use their own Resolver.
  /// @param expr the AST expression
  /// @return the resolved semantic type for the expression, or nullptr if the
  /// expression has no resolved type.
  const sem::Type* TypeOf(const ast::Expression* expr) const;

  /// Helper for returning the resolved semantic type of the variable `var`.
  /// @note As the Resolver is run when the Program is built, this will only be
  /// useful for the Resolver itself and tests that use their own Resolver.
  /// @param var the AST variable
  /// @return the resolved semantic type for the variable, or nullptr if the
  /// variable has no resolved type.
  const sem::Type* TypeOf(const ast::Variable* var) const;

  /// Helper for returning the resolved semantic type of the AST type `type`.
  /// @note As the Resolver is run when the Program is built, this will only be
  /// useful for the Resolver itself and tests that use their own Resolver.
  /// @param type the AST type
  /// @return the resolved semantic type for the type, or nullptr if the type
  /// has no resolved type.
  const sem::Type* TypeOf(const ast::Type* type) const;

  /// Helper for returning the resolved semantic type of the AST type
  /// declaration `type_decl`.
  /// @note As the Resolver is run when the Program is built, this will only be
  /// useful for the Resolver itself and tests that use their own Resolver.
  /// @param type_decl the AST type declaration
  /// @return the resolved semantic type for the type declaration, or nullptr if
  /// the type declaration has no resolved type.
  const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const;

  /// Wraps the ast::Expression in a statement. This is used by tests that
  /// construct a partial AST and require the Resolver to reach these
  /// nodes.
  /// @param expr the ast::Expression to be wrapped by an ast::Statement
  /// @return the ast::Statement that wraps the ast::Expression
  const ast::Statement* WrapInStatement(const ast::Expression* expr);
  /// Wraps the ast::Variable in a ast::VariableDeclStatement. This is used by
  /// tests that construct a partial AST and require the Resolver to reach
  /// these nodes.
  /// @param v the ast::Variable to be wrapped by an ast::VariableDeclStatement
  /// @return the ast::VariableDeclStatement that wraps the ast::Variable
  const ast::VariableDeclStatement* WrapInStatement(const ast::Variable* v);
  /// Returns the statement argument. Used as a passthrough-overload by
  /// WrapInFunction().
  /// @param stmt the ast::Statement
  /// @return `stmt`
  const ast::Statement* WrapInStatement(const ast::Statement* stmt);
  /// Wraps the list of arguments in a simple function so that each is reachable
  /// by the Resolver.
  /// @param args a mix of ast::Expression, ast::Statement, ast::Variables.
  /// @returns the function
  template <typename... ARGS>
  const ast::Function* WrapInFunction(ARGS&&... args) {
    ast::StatementList stmts{WrapInStatement(std::forward<ARGS>(args))...};
    return WrapInFunction(std::move(stmts));
  }
  /// @param stmts a list of ast::Statement that will be wrapped by a function,
  /// so that each statement is reachable by the Resolver.
  /// @returns the function
  const ast::Function* WrapInFunction(ast::StatementList stmts);

  /// The builder types
  TypesBuilder const ty{this};

 protected:
  /// Asserts that the builder has not been moved.
  void AssertNotMoved() const;

 private:
  ProgramID id_;
  sem::Manager types_;
  ASTNodeAllocator ast_nodes_;
  SemNodeAllocator sem_nodes_;
  ast::Module* ast_;
  sem::Info sem_;
  SymbolTable symbols_{id_};
  diag::List diagnostics_;
  std::unordered_set<const TypeInfo*> transforms_applied_;

  /// The source to use when creating AST nodes without providing a Source as
  /// the first argument.
  Source source_;

  /// Set by SetResolveOnBuild(). If set, the Resolver will be run on the
  /// program when built.
  bool resolve_on_build_ = true;

  /// Set by MarkAsMoved(). Once set, no methods may be called on this builder.
  bool moved_ = false;
};

//! @cond Doxygen_Suppress
// Various template specializations for ProgramBuilder::TypesBuilder::CToAST.
template <>
struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::i32> {
  static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) {
    return t->i32();
  }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::u32> {
  static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) {
    return t->u32();
  }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<ProgramBuilder::f32> {
  static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) {
    return t->f32();
  }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<bool> {
  static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) {
    return t->bool_();
  }
};
template <>
struct ProgramBuilder::TypesBuilder::CToAST<void> {
  static const ast::Type* get(const ProgramBuilder::TypesBuilder* t) {
    return t->void_();
  }
};
//! @endcond

/// @param builder the ProgramBuilder
/// @returns the ProgramID of the ProgramBuilder
inline ProgramID ProgramIDOf(const ProgramBuilder* builder) {
  return builder->ID();
}

}  // namespace tint

#endif  // SRC_PROGRAM_BUILDER_H_
