// 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/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_expression.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_expression.h"
#include "src/ast/for_loop_statement.h"
#include "src/ast/i32.h"
#include "src/ast/if_statement.h"
#include "src/ast/index_accessor_expression.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_expression.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_expression.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::IndexAccessorExpression` that indexes `arr` with `idx`
  template <typename ARR, typename IDX>
  const ast::IndexAccessorExpression* IndexAccessor(const Source& source,
                                                    ARR&& arr,
                                                    IDX&& idx) {
    return create<ast::IndexAccessorExpression>(
        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::IndexAccessorExpression` that indexes `arr` with `idx`
  template <typename ARR, typename IDX>
  const ast::IndexAccessorExpression* IndexAccessor(ARR&& arr, IDX&& idx) {
    return create<ast::IndexAccessorExpression>(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_
