// Copyright 2021 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef SRC_TINT_LANG_WGSL_AST_BUILDER_H_
#define SRC_TINT_LANG_WGSL_AST_BUILDER_H_

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

#include "src/tint/api/common/override_id.h"

#include "src/tint/lang/core/constant/manager.h"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/interpolation_sampling.h"
#include "src/tint/lang/core/interpolation_type.h"
#include "src/tint/lang/core/number.h"
#include "src/tint/lang/core/type/array.h"
#include "src/tint/lang/core/type/bool.h"
#include "src/tint/lang/core/type/depth_texture.h"
#include "src/tint/lang/core/type/external_texture.h"
#include "src/tint/lang/core/type/f16.h"
#include "src/tint/lang/core/type/f32.h"
#include "src/tint/lang/core/type/i32.h"
#include "src/tint/lang/core/type/matrix.h"
#include "src/tint/lang/core/type/multisampled_texture.h"
#include "src/tint/lang/core/type/pointer.h"
#include "src/tint/lang/core/type/sampled_texture.h"
#include "src/tint/lang/core/type/sampler_kind.h"
#include "src/tint/lang/core/type/storage_texture.h"
#include "src/tint/lang/core/type/texture_dimension.h"
#include "src/tint/lang/core/type/u32.h"
#include "src/tint/lang/core/type/vector.h"
#include "src/tint/lang/core/type/void.h"
#include "src/tint/lang/wgsl/ast/alias.h"
#include "src/tint/lang/wgsl/ast/assignment_statement.h"
#include "src/tint/lang/wgsl/ast/binary_expression.h"
#include "src/tint/lang/wgsl/ast/binding_attribute.h"
#include "src/tint/lang/wgsl/ast/bitcast_expression.h"
#include "src/tint/lang/wgsl/ast/bool_literal_expression.h"
#include "src/tint/lang/wgsl/ast/break_if_statement.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
#include "src/tint/lang/wgsl/ast/call_expression.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/case_statement.h"
#include "src/tint/lang/wgsl/ast/compound_assignment_statement.h"
#include "src/tint/lang/wgsl/ast/const.h"
#include "src/tint/lang/wgsl/ast/const_assert.h"
#include "src/tint/lang/wgsl/ast/continue_statement.h"
#include "src/tint/lang/wgsl/ast/diagnostic_attribute.h"
#include "src/tint/lang/wgsl/ast/diagnostic_control.h"
#include "src/tint/lang/wgsl/ast/diagnostic_directive.h"
#include "src/tint/lang/wgsl/ast/diagnostic_rule_name.h"
#include "src/tint/lang/wgsl/ast/disable_validation_attribute.h"
#include "src/tint/lang/wgsl/ast/discard_statement.h"
#include "src/tint/lang/wgsl/ast/enable.h"
#include "src/tint/lang/wgsl/ast/float_literal_expression.h"
#include "src/tint/lang/wgsl/ast/for_loop_statement.h"
#include "src/tint/lang/wgsl/ast/id_attribute.h"
#include "src/tint/lang/wgsl/ast/identifier.h"
#include "src/tint/lang/wgsl/ast/if_statement.h"
#include "src/tint/lang/wgsl/ast/increment_decrement_statement.h"
#include "src/tint/lang/wgsl/ast/index_accessor_expression.h"
#include "src/tint/lang/wgsl/ast/index_attribute.h"
#include "src/tint/lang/wgsl/ast/int_literal_expression.h"
#include "src/tint/lang/wgsl/ast/interpolate_attribute.h"
#include "src/tint/lang/wgsl/ast/invariant_attribute.h"
#include "src/tint/lang/wgsl/ast/let.h"
#include "src/tint/lang/wgsl/ast/loop_statement.h"
#include "src/tint/lang/wgsl/ast/member_accessor_expression.h"
#include "src/tint/lang/wgsl/ast/module.h"
#include "src/tint/lang/wgsl/ast/must_use_attribute.h"
#include "src/tint/lang/wgsl/ast/override.h"
#include "src/tint/lang/wgsl/ast/parameter.h"
#include "src/tint/lang/wgsl/ast/phony_expression.h"
#include "src/tint/lang/wgsl/ast/requires.h"
#include "src/tint/lang/wgsl/ast/return_statement.h"
#include "src/tint/lang/wgsl/ast/stage_attribute.h"
#include "src/tint/lang/wgsl/ast/stride_attribute.h"
#include "src/tint/lang/wgsl/ast/struct.h"
#include "src/tint/lang/wgsl/ast/struct_member_align_attribute.h"
#include "src/tint/lang/wgsl/ast/struct_member_offset_attribute.h"
#include "src/tint/lang/wgsl/ast/struct_member_size_attribute.h"
#include "src/tint/lang/wgsl/ast/switch_statement.h"
#include "src/tint/lang/wgsl/ast/templated_identifier.h"
#include "src/tint/lang/wgsl/ast/type.h"
#include "src/tint/lang/wgsl/ast/unary_op_expression.h"
#include "src/tint/lang/wgsl/ast/var.h"
#include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
#include "src/tint/lang/wgsl/ast/while_statement.h"
#include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
#include "src/tint/lang/wgsl/extension.h"
#include "src/tint/utils/id/generation_id.h"
#include "src/tint/utils/text/string.h"

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

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

namespace tint::ast {

/// Evaluates to true if T is a Infer, AInt or AFloat.
template <typename T>
static constexpr const bool IsInferOrAbstract =
    std::is_same_v<std::decay_t<T>, core::fluent_types::Infer> || core::IsAbstract<std::decay_t<T>>;

// Forward declare metafunction that evaluates to true iff T can be wrapped in a statement.
template <typename T, typename = void>
struct CanWrapInStatement;

/// Builder is a mutable builder for AST nodes.
/// To construct a Program, populate the builder and then `std::move` it to a
/// Program.
class Builder {
    /// Evaluates to true if T is a Source
    template <typename T>
    static constexpr const bool IsSource = std::is_same_v<T, Source>;

    /// Evaluates to true if T is a Number or bool.
    template <typename T>
    static constexpr const bool IsScalar =
        std::is_integral_v<core::UnwrapNumber<T>> ||
        std::is_floating_point_v<core::UnwrapNumber<T>> || std::is_same_v<T, bool>;

    /// Evaluates to true if T can be converted to an identifier.
    template <typename T>
    static constexpr const bool IsIdentifierLike = std::is_same_v<T, Symbol> ||  // Symbol
                                                   std::is_enum_v<T> ||          // Enum
                                                   traits::IsStringLike<T>;      // String

    /// 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::EnableIf<!IsSource<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to disable overloads if the first type in `TYPES` is a scalar type. Used to
    /// avoid ambiguities in overloads that take a scalar as the first parameter and those that
    /// perfectly-forward the first argument.
    template <typename... TYPES>
    using DisableIfScalar =
        traits::EnableIf<!IsScalar<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to enable overloads if the first type in `TYPES` is a scalar type. Used to
    /// avoid ambiguities in overloads that take a scalar as the first parameter and those that
    /// perfectly-forward the first argument.
    template <typename... TYPES>
    using EnableIfScalar =
        traits::EnableIf<IsScalar<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to disable overloads if the first type in `TYPES` is a Vector or
    /// VectorRef.
    template <typename... TYPES>
    using DisableIfVectorLike =
        traits::EnableIf<!IsVectorLike<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to enable overloads if the first type in `TYPES` is identifier-like.
    template <typename... TYPES>
    using EnableIfIdentifierLike =
        traits::EnableIf<IsIdentifierLike<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to disable overloads if the first type in `TYPES` is Infer or an abstract
    /// numeric.
    template <typename... TYPES>
    using DisableIfInferOrAbstract =
        traits::EnableIf<!IsInferOrAbstract<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// A helper used to enable overloads if the first type in `TYPES` is Infer or an abstract
    /// numeric.
    template <typename... TYPES>
    using EnableIfInferOrAbstract =
        traits::EnableIf<IsInferOrAbstract<traits::Decay<traits::NthTypeOf<0, TYPES..., void>>>>;

    /// VarOptions is a helper for accepting an arbitrary number of order independent options for
    /// constructing an ast::Var.
    struct VarOptions {
        template <typename... ARGS>
        explicit VarOptions(Builder& b, ARGS&&... args) {
            (Set(b, std::forward<ARGS>(args)), ...);
        }
        ~VarOptions();

        ast::Type type;
        const ast::Expression* address_space = nullptr;
        const ast::Expression* access = nullptr;
        const ast::Expression* initializer = nullptr;
        Vector<const ast::Attribute*, 4> attributes;

      private:
        void Set(Builder&, ast::Type t) { type = t; }
        void Set(Builder& b, core::AddressSpace addr_space) {
            if (addr_space != core::AddressSpace::kUndefined) {
                address_space = b.Expr(addr_space);
            }
        }
        void Set(Builder& b, core::Access ac) {
            if (ac != core::Access::kUndefined) {
                access = b.Expr(ac);
            }
        }
        void Set(Builder&, const ast::Expression* c) { initializer = c; }
        void Set(Builder&, VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
        void Set(Builder&, const ast::Attribute* a) { attributes.Push(a); }
    };

    /// LetOptions is a helper for accepting an arbitrary number of order independent options for
    /// constructing an ast::Let.
    struct LetOptions {
        template <typename... ARGS>
        explicit LetOptions(ARGS&&... args) {
            static constexpr bool has_init =
                (traits::IsTypeOrDerived<traits::PtrElTy<ARGS>, ast::Expression> || ...);
            static_assert(has_init, "Let() must be constructed with an initializer expression");
            (Set(std::forward<ARGS>(args)), ...);
        }
        ~LetOptions();

        ast::Type type;
        const ast::Expression* initializer = nullptr;
        Vector<const ast::Attribute*, 4> attributes;

      private:
        void Set(ast::Type t) { type = t; }
        void Set(const ast::Expression* c) { initializer = c; }
        void Set(VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
        void Set(const ast::Attribute* a) { attributes.Push(a); }
    };

    /// ConstOptions is a helper for accepting an arbitrary number of order independent options for
    /// constructing an ast::Const.
    struct ConstOptions {
        template <typename... ARGS>
        explicit ConstOptions(ARGS&&... args) {
            static constexpr bool has_init =
                (traits::IsTypeOrDerived<traits::PtrElTy<ARGS>, ast::Expression> || ...);
            static_assert(has_init, "Const() must be constructed with an initializer expression");
            (Set(std::forward<ARGS>(args)), ...);
        }
        ~ConstOptions();

        ast::Type type;
        const ast::Expression* initializer = nullptr;
        Vector<const ast::Attribute*, 4> attributes;

      private:
        void Set(ast::Type t) { type = t; }
        void Set(const ast::Expression* c) { initializer = c; }
        void Set(VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
        void Set(const ast::Attribute* a) { attributes.Push(a); }
    };

    /// OverrideOptions is a helper for accepting an arbitrary number of order independent options
    /// for constructing an ast::Override.
    struct OverrideOptions {
        template <typename... ARGS>
        explicit OverrideOptions(ARGS&&... args) {
            (Set(std::forward<ARGS>(args)), ...);
        }
        ~OverrideOptions();

        ast::Type type;
        const ast::Expression* initializer = nullptr;
        Vector<const ast::Attribute*, 4> attributes;

      private:
        void Set(ast::Type t) { type = t; }
        void Set(const ast::Expression* c) { initializer = c; }
        void Set(VectorRef<const ast::Attribute*> l) { attributes = std::move(l); }
        void Set(const ast::Attribute* a) { attributes.Push(a); }
    };

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

    /// Constructor
    Builder();

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

    /// Destructor
    ~Builder();

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

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

    /// @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 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 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_;
    }

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

    /// @returns the last allocated (numerically highest) AST node identifier.
    ast::NodeID LastAllocatedNodeID() const { return last_ast_node_id_; }

    /// @returns the next sequentially unique node identifier.
    ast::NodeID AllocateNodeID() {
        auto out = ast::NodeID{last_ast_node_id_.value + 1};
        last_ast_node_id_ = out;
        return out;
    }

    /// Creates a new ast::Node owned by the Builder. When the
    /// Builder is destructed, the ast::Node will also be destructed.
    /// @param source the Source of the node
    /// @param args the arguments to pass to the 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_, AllocateNodeID(), source, std::forward<ARGS>(args)...);
    }

    /// Creates a new ast::Node owned by the Builder, injecting the current
    /// Source as set by the last call to SetSource() as the only argument to the
    /// constructor.
    /// When the Builder 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_, AllocateNodeID(), source_);
    }

    /// Creates a new ast::Node owned by the Builder, injecting the current
    /// Source as set by the last call to SetSource() as the first argument to the
    /// constructor.
    /// When the Builder is destructed, the ast::Node will also be
    /// destructed.
    /// @param arg0 the first arguments to pass to the constructor
    /// @param args the remaining arguments to pass to the 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> &&
                         !traits::IsTypeOrDerived<ARG0, Source>,
                     T>*
    create(ARG0&& arg0, ARGS&&... args) {
        AssertNotMoved();
        return ast_nodes_.Create<T>(id_, AllocateNodeID(), source_, std::forward<ARG0>(arg0),
                                    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(Builder* builder);

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

        /// @param type the type to return
        /// @return type (passthrough)
        ast::Type operator()(const ast::Type& type) const { return type; }

        /// Creates a type
        /// @param name the name
        /// @param args the optional template arguments
        /// @returns the type
        template <typename NAME,
                  typename... ARGS,
                  typename = DisableIfSource<NAME>,
                  typename = std::enable_if_t<!std::is_same_v<std::decay_t<NAME>, ast::Type>>>
        ast::Type operator()(NAME&& name, ARGS&&... args) const {
            if constexpr (traits::IsTypeOrDerived<traits::PtrElTy<NAME>, ast::Expression>) {
                static_assert(sizeof...(ARGS) == 0);
                return {name};
            } else {
                return {builder->Expr(
                    builder->Ident(std::forward<NAME>(name), std::forward<ARGS>(args)...))};
            }
        }

        /// Creates a type
        /// @param source the Source of the node
        /// @param name the name
        /// @param args the optional template arguments
        /// @returns the type
        template <typename NAME,
                  typename... ARGS,
                  typename = std::enable_if_t<!std::is_same_v<std::decay_t<NAME>, ast::Type>>>
        ast::Type operator()(const Source& source, NAME&& name, ARGS&&... args) const {
            return {builder->Expr(
                builder->Ident(source, std::forward<NAME>(name), std::forward<ARGS>(args)...))};
        }

        /// @returns a a nullptr expression wrapped in an ast::Type
        ast::Type void_() const { return ast::Type{}; }

        /// @returns a 'bool' type
        ast::Type bool_() const { return (*this)("bool"); }

        /// @param source the Source of the node
        /// @returns a 'bool' type
        ast::Type bool_(const Source& source) const { return (*this)(source, "bool"); }

        /// @returns a 'f16' type
        ast::Type f16() const { return (*this)("f16"); }

        /// @param source the Source of the node
        /// @returns a 'f16' type
        ast::Type f16(const Source& source) const { return (*this)(source, "f16"); }

        /// @returns a 'f32' type
        ast::Type f32() const { return (*this)("f32"); }

        /// @param source the Source of the node
        /// @returns a 'f32' type
        ast::Type f32(const Source& source) const { return (*this)(source, "f32"); }

        /// @returns a 'i32' type
        ast::Type i32() const { return (*this)("i32"); }

        /// @param source the Source of the node
        /// @returns a 'i32' type
        ast::Type i32(const Source& source) const { return (*this)(source, "i32"); }

        /// @returns a 'u32' type
        ast::Type u32() const { return (*this)("u32"); }

        /// @param source the Source of the node
        /// @returns a 'u32' type
        ast::Type u32(const Source& source) const { return (*this)(source, "u32"); }

        /// @param type vector subtype
        /// @param n vector width in elements
        /// @return a @p n element vector of @p type
        ast::Type vec(ast::Type type, uint32_t n) const { return vec(builder->source_, type, n); }

        /// @param source the Source of the node
        /// @param type vector subtype
        /// @param n vector width in elements
        /// @return a @p n element vector of @p type
        ast::Type vec(const Source& source, ast::Type type, uint32_t n) const {
            switch (n) {
                case 2:
                    return vec2(source, type);
                case 3:
                    return vec3(source, type);
                case 4:
                    return vec4(source, type);
            }
            TINT_ICE() << "invalid vector width " << n;
            return ast::Type{};
        }

        /// @param type vector subtype
        /// @return a 2-element vector of @p type
        ast::Type vec2(ast::Type type) const { return vec2(builder->source_, type); }

        /// @param source the vector source
        /// @param type vector subtype
        /// @return a 2-element vector of @p type
        ast::Type vec2(const Source& source, ast::Type type) const {
            return (*this)(source, "vec2", type);
        }

        /// @param type vector subtype
        /// @return a 3-element vector of @p type
        ast::Type vec3(ast::Type type) const { return vec3(builder->source_, type); }

        /// @param source the vector source
        /// @param type vector subtype
        /// @return a 3-element vector of @p type
        ast::Type vec3(const Source& source, ast::Type type) const {
            return (*this)(source, "vec3", type);
        }

        /// @param type vector subtype
        /// @return a 4-element vector of @p type
        ast::Type vec4(ast::Type type) const { return vec4(builder->source_, type); }

        /// @param source the vector source
        /// @param type vector subtype
        /// @return a 4-element vector of @p type
        ast::Type vec4(const Source& source, ast::Type type) const {
            return (*this)(source, "vec4", type);
        }

        /// @param source the Source of the node
        /// @return a 2-element vector of the type `T`
        template <typename T>
        ast::Type vec2(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "vec2");
            } else {
                return (*this)(source, "vec2", Of<T>());
            }
        }

        /// @param source the Source of the node
        /// @return a 3-element vector of the type `T`
        template <typename T>
        ast::Type vec3(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "vec3");
            } else {
                return (*this)(source, "vec3", Of<T>());
            }
        }

        /// @param source the Source of the node
        /// @return a 4-element vector of the type `T`
        template <typename T>
        ast::Type vec4(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "vec4");
            } else {
                return (*this)(source, "vec4", Of<T>());
            }
        }

        /// @return a 2-element vector of the type `T`
        template <typename T>
        ast::Type vec2() const {
            return vec2<T>(builder->source_);
        }

        /// @return a 3-element vector of the type `T`
        template <typename T>
        ast::Type vec3() const {
            return vec3<T>(builder->source_);
        }

        /// @return a 4-element vector of the type `T`
        template <typename T>
        ast::Type vec4() const {
            return vec4<T>(builder->source_);
        }

        /// @param source the Source of the node
        /// @param n vector width in elements
        /// @return a @p n element vector of @p type
        template <typename T>
        ast::Type vec(const Source& source, uint32_t n) const {
            switch (n) {
                case 2:
                    return vec2<T>(source);
                case 3:
                    return vec3<T>(source);
                case 4:
                    return vec4<T>(source);
            }
            TINT_ICE() << "invalid vector width " << n;
            return ast::Type{};
        }

        /// @return a @p N element vector of @p type
        template <typename T, uint32_t N>
        ast::Type vec() const {
            return vec<T>(builder->source_, N);
        }

        /// @param n vector width in elements
        /// @return a @p n element vector of @p type
        template <typename T>
        ast::Type vec(uint32_t n) const {
            return vec<T>(builder->source_, n);
        }

        /// @param type matrix subtype
        /// @param columns number of columns for the matrix
        /// @param rows number of rows for the matrix
        /// @return a matrix of @p type
        ast::Type mat(ast::Type type, uint32_t columns, uint32_t rows) const {
            return mat(builder->source_, type, columns, rows);
        }

        /// @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 a matrix of @p type
        ast::Type mat(const Source& source, ast::Type type, uint32_t columns, uint32_t rows) const {
            if (TINT_LIKELY(columns >= 2 && columns <= 4 && rows >= 2 && rows <= 4)) {
                static constexpr const char* names[] = {
                    "mat2x2", "mat2x3", "mat2x4",  //
                    "mat3x2", "mat3x3", "mat3x4",  //
                    "mat4x2", "mat4x3", "mat4x4",  //
                };
                auto i = (columns - 2) * 3 + (rows - 2);
                return (*this)(source, names[i], type);
            }
            TINT_ICE() << "invalid matrix dimensions " << columns << "x" << rows;
            return ast::Type{};
        }

        /// @param type matrix subtype
        /// @return a 2x3 matrix of @p type.
        ast::Type mat2x2(ast::Type type) const { return (*this)("mat2x2", type); }

        /// @param type matrix subtype
        /// @return a 2x3 matrix of @p type.
        ast::Type mat2x3(ast::Type type) const { return (*this)("mat2x3", type); }

        /// @param type matrix subtype
        /// @return a 2x4 matrix of @p type.
        ast::Type mat2x4(ast::Type type) const { return (*this)("mat2x4", type); }

        /// @param type matrix subtype
        /// @return a 3x2 matrix of @p type.
        ast::Type mat3x2(ast::Type type) const { return (*this)("mat3x2", type); }

        /// @param type matrix subtype
        /// @return a 3x3 matrix of @p type.
        ast::Type mat3x3(ast::Type type) const { return (*this)("mat3x3", type); }

        /// @param type matrix subtype
        /// @return a 3x4 matrix of @p type.
        ast::Type mat3x4(ast::Type type) const { return (*this)("mat3x4", type); }

        /// @param type matrix subtype
        /// @return a 4x2 matrix of @p type.
        ast::Type mat4x2(ast::Type type) const { return (*this)("mat4x2", type); }

        /// @param type matrix subtype
        /// @return a 4x3 matrix of @p type.
        ast::Type mat4x3(ast::Type type) const { return (*this)("mat4x3", type); }

        /// @param type matrix subtype
        /// @return a 4x4 matrix of @p type.
        ast::Type mat4x4(ast::Type type) const { return (*this)("mat4x4", type); }

        /// @param source the source of the type
        /// @return a 2x2 matrix of the type `T`
        template <typename T>
        ast::Type mat2x2(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat2x2");
            } else {
                return (*this)(source, "mat2x2", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 2x3 matrix of the type `T`
        template <typename T>
        ast::Type mat2x3(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat2x3");
            } else {
                return (*this)(source, "mat2x3", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 2x4 matrix of the type `T`
        template <typename T>
        ast::Type mat2x4(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat2x4");
            } else {
                return (*this)(source, "mat2x4", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 3x2 matrix of the type `T`
        template <typename T>
        ast::Type mat3x2(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat3x2");
            } else {
                return (*this)(source, "mat3x2", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 3x3 matrix of the type `T`
        template <typename T>
        ast::Type mat3x3(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat3x3");
            } else {
                return (*this)(source, "mat3x3", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 3x4 matrix of the type `T`
        template <typename T>
        ast::Type mat3x4(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat3x4");
            } else {
                return (*this)(source, "mat3x4", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 4x2 matrix of the type `T`
        template <typename T>
        ast::Type mat4x2(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat4x2");
            } else {
                return (*this)(source, "mat4x2", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 4x3 matrix of the type `T`
        template <typename T>
        ast::Type mat4x3(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat4x3");
            } else {
                return (*this)(source, "mat4x3", Of<T>());
            }
        }

        /// @param source the source of the type
        /// @return a 4x4 matrix of the type `T`
        template <typename T>
        ast::Type mat4x4(const Source& source) const {
            if constexpr (IsInferOrAbstract<T>) {
                return (*this)(source, "mat4x4");
            } else {
                return (*this)(source, "mat4x4", Of<T>());
            }
        }

        /// @return a 2x2 matrix of the type `T`
        template <typename T>
        ast::Type mat2x2() const {
            return mat2x2<T>(builder->source_);
        }

        /// @return a 2x3 matrix of the type `T`
        template <typename T>
        ast::Type mat2x3() const {
            return mat2x3<T>(builder->source_);
        }

        /// @return a 2x4 matrix of the type `T`
        template <typename T>
        ast::Type mat2x4() const {
            return mat2x4<T>(builder->source_);
        }

        /// @return a 3x2 matrix of the type `T`
        template <typename T>
        ast::Type mat3x2() const {
            return mat3x2<T>(builder->source_);
        }

        /// @return a 3x3 matrix of the type `T`
        template <typename T>
        ast::Type mat3x3() const {
            return mat3x3<T>(builder->source_);
        }

        /// @return a 3x4 matrix of the type `T`
        template <typename T>
        ast::Type mat3x4() const {
            return mat3x4<T>(builder->source_);
        }

        /// @return a 4x2 matrix of the type `T`
        template <typename T>
        ast::Type mat4x2() const {
            return mat4x2<T>(builder->source_);
        }

        /// @return a 4x3 matrix of the type `T`
        template <typename T>
        ast::Type mat4x3() const {
            return mat4x3<T>(builder->source_);
        }

        /// @return a 4x4 matrix of the type `T`
        template <typename T>
        ast::Type mat4x4() const {
            return mat4x4<T>(builder->source_);
        }

        /// @param source the Source of the node
        /// @param columns number of columns for the matrix
        /// @param rows number of rows for the matrix
        /// @return a matrix of @p type
        template <typename T>
        ast::Type mat(const Source& source, uint32_t columns, uint32_t rows) const {
            switch ((columns - 2) * 3 + (rows - 2)) {
                case 0:
                    return mat2x2<T>(source);
                case 1:
                    return mat2x3<T>(source);
                case 2:
                    return mat2x4<T>(source);
                case 3:
                    return mat3x2<T>(source);
                case 4:
                    return mat3x3<T>(source);
                case 5:
                    return mat3x4<T>(source);
                case 6:
                    return mat4x2<T>(source);
                case 7:
                    return mat4x3<T>(source);
                case 8:
                    return mat4x4<T>(source);
                default:
                    TINT_ICE() << "invalid matrix dimensions " << columns << "x" << rows;
                    return ast::Type{};
            }
        }

        /// @param columns number of columns for the matrix
        /// @param rows number of rows for the matrix
        /// @return a matrix of @p type
        template <typename T>
        ast::Type mat(uint32_t columns, uint32_t rows) const {
            return mat<T>(builder->source_, columns, rows);
        }

        /// @return a matrix of @p type
        template <typename T, uint32_t COLUMNS, uint32_t ROWS>
        ast::Type mat() const {
            return mat<T>(builder->source_, COLUMNS, ROWS);
        }

        /// @param subtype the array element type
        /// @param attrs the optional attributes for the array
        /// @return an array of type `T`
        ast::Type array(ast::Type subtype, VectorRef<const ast::Attribute*> attrs = Empty) const {
            return array(builder->source_, subtype, std::move(attrs));
        }

        /// @param source the Source of the node
        /// @param subtype the array element type
        /// @param attrs the optional attributes for the array
        /// @return an array of type `T`
        ast::Type array(const Source& source,
                        ast::Type subtype,
                        VectorRef<const ast::Attribute*> attrs = Empty) const {
            return ast::Type{builder->Expr(
                builder->create<ast::TemplatedIdentifier>(source, builder->Sym("array"),
                                                          Vector{
                                                              subtype.expr,
                                                          },
                                                          std::move(attrs)))};
        }

        /// @param subtype the array element type
        /// @param n the array size. nullptr represents a runtime-array
        /// @param attrs the optional attributes for the array
        /// @return an array of size `n` of type `T`
        template <typename COUNT, typename = DisableIfVectorLike<COUNT>>
        ast::Type array(ast::Type subtype,
                        COUNT&& n,
                        VectorRef<const ast::Attribute*> attrs = Empty) const {
            return array(builder->source_, subtype, std::forward<COUNT>(n), std::move(attrs));
        }

        /// @param source the Source of the node
        /// @param subtype the array element type
        /// @param n the array size. nullptr represents a runtime-array
        /// @param attrs the optional attributes for the array
        /// @return an array of size `n` of type `T`
        template <typename COUNT, typename = DisableIfVectorLike<COUNT>>
        ast::Type array(const Source& source,
                        ast::Type subtype,
                        COUNT&& n,
                        VectorRef<const ast::Attribute*> attrs = Empty) const {
            return ast::Type{builder->Expr(
                builder->create<ast::TemplatedIdentifier>(source, builder->Sym("array"),
                                                          Vector{
                                                              subtype.expr,
                                                              builder->Expr(std::forward<COUNT>(n)),
                                                          },
                                                          std::move(attrs)))};
        }

        /// @param source the Source of the node
        /// @return a inferred-size or runtime-sized array of type `T`
        template <typename T, int N = 0, typename = EnableIfInferOrAbstract<T>>
        ast::Type array(const Source& source) const {
            static_assert(N == 0, "arrays with a count cannot be inferred");
            return (*this)(source, "array");
        }

        /// @return a inferred-size or runtime-sized array of type `T`
        template <typename T, int N = 0, typename = EnableIfInferOrAbstract<T>>
        ast::Type array() const {
            static_assert(N == 0, "arrays with a count cannot be inferred");
            return array<T>(builder->source_);
        }

        /// @param source the Source of the node
        /// @param attrs the optional attributes for the array
        /// @return a inferred-size or runtime-sized array of type `T`
        template <typename T, int N = 0, typename = DisableIfInferOrAbstract<T>>
        ast::Type array(const Source& source,
                        VectorRef<const ast::Attribute*> attrs = Empty) const {
            if constexpr (N == 0) {
                return ast::Type{builder->Expr(
                    builder->create<ast::TemplatedIdentifier>(source, builder->Sym("array"),
                                                              Vector<const ast::Expression*, 1>{
                                                                  Of<T>().expr,
                                                              },
                                                              std::move(attrs)))};
            } else {
                return ast::Type{builder->Expr(builder->create<ast::TemplatedIdentifier>(
                    source, builder->Sym("array"),
                    Vector{
                        Of<T>().expr,
                        builder->Expr(builder->source_, core::u32(N)),
                    },
                    std::move(attrs)))};
            }
        }

        /// @param attrs the optional attributes for the array
        /// @return an array of size `N` of type `T`
        template <typename T, int N = 0, typename = DisableIfInferOrAbstract<T>>
        ast::Type array(VectorRef<const ast::Attribute*> attrs = Empty) const {
            return array<T, N>(builder->source_, std::move(attrs));
        }

        /// 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, ast::Type type) const {
            return alias(builder->source_, std::forward<NAME>(name), 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, ast::Type type) const {
            return builder->create<ast::Alias>(source, builder->Ident(std::forward<NAME>(name)),
                                               type);
        }

        /// @param address_space the address space of the pointer
        /// @param type the type of the pointer
        /// @param access the optional access control of the pointer
        /// @return the pointer to `type` with the given core::AddressSpace
        ast::Type ptr(core::AddressSpace address_space,
                      ast::Type type,
                      core::Access access = core::Access::kUndefined) const {
            return ptr(builder->source_, address_space, type, access);
        }

        /// @param source the Source of the node
        /// @param address_space the address space of the pointer
        /// @param type the type of the pointer
        /// @param access the optional access control of the pointer
        /// @return the pointer to `type` with the given core::AddressSpace
        ast::Type ptr(const Source& source,
                      core::AddressSpace address_space,
                      ast::Type type,
                      core::Access access = core::Access::kUndefined) const {
            if (access != core::Access::kUndefined) {
                return (*this)(source, "ptr", address_space, type, access);
            } else {
                return (*this)(source, "ptr", address_space, type);
            }
        }

        /// @param address_space the address space of the pointer
        /// @param access the optional access control of the pointer
        /// @return the pointer to type `T` with the given core::AddressSpace.
        template <typename T>
        ast::Type ptr(core::AddressSpace address_space,
                      core::Access access = core::Access::kUndefined) const {
            return ptr<T>(builder->source_, address_space, access);
        }

        /// @param source the Source of the node
        /// @return the pointer to type `T` with the core::AddressSpace `ADDRESS` and access
        /// control `ACCESS`.
        template <core::AddressSpace ADDRESS,
                  typename T,
                  core::Access ACCESS = core::Access::kUndefined>
        ast::Type ptr(const Source& source) const {
            return ptr<T>(source, ADDRESS, ACCESS);
        }

        /// @param type the type of the pointer
        /// @return the pointer to the given type with the core::AddressSpace `ADDRESS` and
        /// access control `ACCESS`.
        template <core::AddressSpace ADDRESS, core::Access ACCESS = core::Access::kUndefined>
        ast::Type ptr(ast::Type type) const {
            return ptr(builder->source_, ADDRESS, type, ACCESS);
        }

        /// @param source the Source of the node
        /// @param type the type of the pointer
        /// @return the pointer to the given type with the core::AddressSpace `ADDRESS` and
        /// access control `ACCESS`.
        template <core::AddressSpace ADDRESS, core::Access ACCESS = core::Access::kUndefined>
        ast::Type ptr(const Source& source, ast::Type type) const {
            return ptr(source, ADDRESS, type, ACCESS);
        }

        /// @return the pointer to type `T` with the core::AddressSpace `ADDRESS` and access
        /// control `ACCESS`.
        template <core::AddressSpace ADDRESS,
                  typename T,
                  core::Access ACCESS = core::Access::kUndefined>
        ast::Type ptr() const {
            return ptr<T>(builder->source_, ADDRESS, ACCESS);
        }

        /// @param source the Source of the node
        /// @param address_space the address space of the pointer
        /// @param access the optional access control of the pointer
        /// @return the pointer to type `T` the core::AddressSpace `ADDRESS` and access control
        /// `ACCESS`.
        template <typename T>
        ast::Type ptr(const Source& source,
                      core::AddressSpace address_space,
                      core::Access access = core::Access::kUndefined) const {
            if (access != core::Access::kUndefined) {
                return (*this)(source, "ptr", address_space, Of<T>(), access);
            } else {
                return (*this)(source, "ptr", address_space, Of<T>());
            }
        }

        /// @param source the Source of the node
        /// @param type the type of the atomic
        /// @return the atomic to `type`
        ast::Type atomic(const Source& source, ast::Type type) const {
            return (*this)(source, "atomic", type);
        }

        /// @param type the type of the atomic
        /// @return the atomic to `type`
        ast::Type atomic(ast::Type type) const { return (*this)("atomic", type); }

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

        /// @param kind the kind of sampler
        /// @returns the sampler
        ast::Type sampler(core::type::SamplerKind kind) const {
            return sampler(builder->source_, kind);
        }

        /// @param source the Source of the node
        /// @param kind the kind of sampler
        /// @returns the sampler
        ast::Type sampler(const Source& source, core::type::SamplerKind kind) const {
            switch (kind) {
                case core::type::SamplerKind::kSampler:
                    return (*this)(source, "sampler");
                case core::type::SamplerKind::kComparisonSampler:
                    return (*this)(source, "sampler_comparison");
            }
            TINT_ICE() << "invalid sampler kind " << kind;
            return ast::Type{};
        }

        /// @param dims the dimensionality of the texture
        /// @returns the depth texture
        ast::Type depth_texture(core::type::TextureDimension dims) const {
            return depth_texture(builder->source_, dims);
        }

        /// @param source the Source of the node
        /// @param dims the dimensionality of the texture
        /// @returns the depth texture
        ast::Type depth_texture(const Source& source, core::type::TextureDimension dims) const {
            switch (dims) {
                case core::type::TextureDimension::k2d:
                    return (*this)(source, "texture_depth_2d");
                case core::type::TextureDimension::k2dArray:
                    return (*this)(source, "texture_depth_2d_array");
                case core::type::TextureDimension::kCube:
                    return (*this)(source, "texture_depth_cube");
                case core::type::TextureDimension::kCubeArray:
                    return (*this)(source, "texture_depth_cube_array");
                default:
                    break;
            }
            TINT_ICE() << "invalid depth_texture dimensions: " << dims;
            return ast::Type{};
        }

        /// @param dims the dimensionality of the texture
        /// @returns the multisampled depth texture
        ast::Type depth_multisampled_texture(core::type::TextureDimension dims) const {
            return depth_multisampled_texture(builder->source_, dims);
        }

        /// @param source the Source of the node
        /// @param dims the dimensionality of the texture
        /// @returns the multisampled depth texture
        ast::Type depth_multisampled_texture(const Source& source,
                                             core::type::TextureDimension dims) const {
            if (dims == core::type::TextureDimension::k2d) {
                return (*this)(source, "texture_depth_multisampled_2d");
            }
            TINT_ICE() << "invalid depth_multisampled_texture dimensions: " << dims;
            return ast::Type{};
        }

        /// @param dims the dimensionality of the texture
        /// @param subtype the texture subtype.
        /// @returns the sampled texture
        ast::Type sampled_texture(core::type::TextureDimension dims, ast::Type subtype) const {
            return sampled_texture(builder->source_, 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
        ast::Type sampled_texture(const Source& source,
                                  core::type::TextureDimension dims,
                                  ast::Type subtype) const {
            switch (dims) {
                case core::type::TextureDimension::k1d:
                    return (*this)(source, "texture_1d", subtype);
                case core::type::TextureDimension::k2d:
                    return (*this)(source, "texture_2d", subtype);
                case core::type::TextureDimension::k3d:
                    return (*this)(source, "texture_3d", subtype);
                case core::type::TextureDimension::k2dArray:
                    return (*this)(source, "texture_2d_array", subtype);
                case core::type::TextureDimension::kCube:
                    return (*this)(source, "texture_cube", subtype);
                case core::type::TextureDimension::kCubeArray:
                    return (*this)(source, "texture_cube_array", subtype);
                default:
                    break;
            }
            TINT_ICE() << "invalid sampled_texture dimensions: " << dims;
            return ast::Type{};
        }

        /// @param dims the dimensionality of the texture
        /// @param subtype the texture subtype.
        /// @returns the multisampled texture
        ast::Type multisampled_texture(core::type::TextureDimension dims, ast::Type subtype) const {
            return multisampled_texture(builder->source_, 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
        ast::Type multisampled_texture(const Source& source,
                                       core::type::TextureDimension dims,
                                       ast::Type subtype) const {
            if (dims == core::type::TextureDimension::k2d) {
                return (*this)(source, "texture_multisampled_2d", subtype);
            }
            TINT_ICE() << "invalid multisampled_texture dimensions: " << dims;
            return ast::Type{};
        }

        /// @param dims the dimensionality of the texture
        /// @param format the texel format of the texture
        /// @param access the access control of the texture
        /// @returns the storage texture
        ast::Type storage_texture(core::type::TextureDimension dims,
                                  core::TexelFormat format,
                                  core::Access access) const {
            return storage_texture(builder->source_, dims, format, access);
        }

        /// @param source the Source of the node
        /// @param dims the dimensionality of the texture
        /// @param format the texel format of the texture
        /// @param access the access control of the texture
        /// @returns the storage texture
        ast::Type storage_texture(const Source& source,
                                  core::type::TextureDimension dims,
                                  core::TexelFormat format,
                                  core::Access access) const {
            switch (dims) {
                case core::type::TextureDimension::k1d:
                    return (*this)(source, "texture_storage_1d", format, access);
                case core::type::TextureDimension::k2d:
                    return (*this)(source, "texture_storage_2d", format, access);
                case core::type::TextureDimension::k2dArray:
                    return (*this)(source, "texture_storage_2d_array", format, access);
                case core::type::TextureDimension::k3d:
                    return (*this)(source, "texture_storage_3d", format, access);
                default:
                    break;
            }
            TINT_ICE() << "invalid storage_texture  dimensions: " << dims;
            return ast::Type{};
        }

        /// @returns the external texture
        ast::Type external_texture() const { return (*this)("texture_external"); }

        /// @param source the Source of the node
        /// @returns the external texture
        ast::Type external_texture(const Source& source) const {
            return (*this)(source, "texture_external");
        }

        /// @param type the type
        /// @return an ast::Type of the type declaration.
        ast::Type Of(const ast::TypeDecl* type) const { return (*this)(type->name->symbol); }

        /// The Builder
        Builder* 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 ast::Type get(Types* t)`
        template <typename T>
        struct CToAST {};
    };

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

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

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

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

    /// @param enumerator the enumerator
    /// @return a Symbol with the given enum value
    template <typename ENUM, typename = std::enable_if_t<std::is_enum_v<std::decay_t<ENUM>>>>
    Symbol Sym(ENUM&& enumerator) {
        return Sym(tint::ToString(enumerator));
    }

    /// @return nullptr
    const ast::Identifier* Ident(std::nullptr_t) { return nullptr; }

    /// @param identifier the identifier symbol
    /// @return an ast::Identifier with the given symbol
    template <typename IDENTIFIER>
    const ast::Identifier* Ident(IDENTIFIER&& identifier) {
        if constexpr (traits::IsTypeOrDerived<traits::PtrElTy<IDENTIFIER>, ast::Identifier>) {
            return identifier;  // Passthrough
        } else {
            return Ident(source_, std::forward<IDENTIFIER>(identifier));
        }
    }

    /// @param source the source information
    /// @param identifier the identifier symbol
    /// @return an ast::Identifier with the given symbol
    template <typename IDENTIFIER>
    const ast::Identifier* Ident(const Source& source, IDENTIFIER&& identifier) {
        return create<ast::Identifier>(source, Sym(std::forward<IDENTIFIER>(identifier)));
    }

    /// @param identifier the identifier symbol
    /// @param args the templated identifier arguments
    /// @return an ast::Identifier with the given symbol and template arguments
    template <typename IDENTIFIER, typename... ARGS, typename = DisableIfSource<IDENTIFIER>>
    const ast::Identifier* Ident(IDENTIFIER&& identifier, ARGS&&... args) {
        return Ident(source_, std::forward<IDENTIFIER>(identifier), std::forward<ARGS>(args)...);
    }

    /// @param source the source information
    /// @param identifier the identifier symbol
    /// @param args the templated identifier arguments
    /// @return an ast::Identifier with the given symbol and template arguments
    template <typename IDENTIFIER, typename... ARGS>
    const ast::Identifier* Ident(const Source& source, IDENTIFIER&& identifier, ARGS&&... args) {
        auto arg_exprs = ExprList(std::forward<ARGS>(args)...);
        if (arg_exprs.IsEmpty()) {
            return create<ast::Identifier>(source, Sym(std::forward<IDENTIFIER>(identifier)));
        }
        return create<ast::TemplatedIdentifier>(source, Sym(std::forward<IDENTIFIER>(identifier)),
                                                std::move(arg_exprs), Empty);
    }

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

    /// @param type an ast::Type
    /// @return type.expr
    const ast::IdentifierExpression* Expr(ast::Type type) { return type.expr; }

    /// @param ident the identifier
    /// @return an ast::IdentifierExpression with the given identifier
    const ast::IdentifierExpression* Expr(const ast::Identifier* ident) {
        return ident ? create<ast::IdentifierExpression>(ident->source, ident) : nullptr;
    }

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

    /// @param name the identifier name
    /// @return an ast::IdentifierExpression with the given name
    template <typename NAME, typename = EnableIfIdentifierLike<NAME>>
    const ast::IdentifierExpression* Expr(NAME&& name) {
        auto* ident = Ident(source_, name);
        return create<ast::IdentifierExpression>(ident->source, ident);
    }

    /// @param source the source information
    /// @param name the identifier name
    /// @return an ast::IdentifierExpression with the given name
    template <typename NAME, typename = EnableIfIdentifierLike<NAME>>
    const ast::IdentifierExpression* Expr(const Source& source, NAME&& name) {
        return create<ast::IdentifierExpression>(source, Ident(source, name));
    }

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

    /// @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, Ident(source, variable->name->symbol));
    }

    /// @param source the source information
    /// @param value the boolean value
    /// @return a Scalar constructor for the given value
    template <typename BOOL>
    std::enable_if_t<std::is_same_v<BOOL, bool>, const ast::BoolLiteralExpression*> Expr(
        const Source& source,
        BOOL value) {
        return create<ast::BoolLiteralExpression>(source, value);
    }

    /// @param source the source information
    /// @param value the float value
    /// @return a 'f'-suffixed FloatLiteralExpression for the f32 value
    const ast::FloatLiteralExpression* Expr(const Source& source, core::f32 value) {
        return create<ast::FloatLiteralExpression>(source, static_cast<double>(value.value),
                                                   ast::FloatLiteralExpression::Suffix::kF);
    }

    /// @param source the source information
    /// @param value the float value
    /// @return a 'h'-suffixed FloatLiteralExpression for the f16 value
    const ast::FloatLiteralExpression* Expr(const Source& source, core::f16 value) {
        return create<ast::FloatLiteralExpression>(source, static_cast<double>(value.value),
                                                   ast::FloatLiteralExpression::Suffix::kH);
    }

    /// @param source the source information
    /// @param value the integer value
    /// @return an unsuffixed IntLiteralExpression for the AInt value
    const ast::IntLiteralExpression* Expr(const Source& source, core::AInt value) {
        return create<ast::IntLiteralExpression>(source, value,
                                                 ast::IntLiteralExpression::Suffix::kNone);
    }

    /// @param source the source information
    /// @param value the integer value
    /// @return an unsuffixed FloatLiteralExpression for the AFloat value
    const ast::FloatLiteralExpression* Expr(const Source& source, core::AFloat value) {
        return create<ast::FloatLiteralExpression>(source, value.value,
                                                   ast::FloatLiteralExpression::Suffix::kNone);
    }

    /// @param source the source information
    /// @param value the integer value
    /// @return a signed 'i'-suffixed IntLiteralExpression for the i32 value
    const ast::IntLiteralExpression* Expr(const Source& source, core::i32 value) {
        return create<ast::IntLiteralExpression>(source, value,
                                                 ast::IntLiteralExpression::Suffix::kI);
    }

    /// @param source the source information
    /// @param value the unsigned int value
    /// @return an unsigned 'u'-suffixed IntLiteralExpression for the u32 value
    const ast::IntLiteralExpression* Expr(const Source& source, core::u32 value) {
        return create<ast::IntLiteralExpression>(source, value,
                                                 ast::IntLiteralExpression::Suffix::kU);
    }

    /// @param value the scalar value
    /// @return literal expression of the appropriate type
    template <typename SCALAR, typename = EnableIfScalar<SCALAR>>
    const auto* Expr(SCALAR&& value) {
        return Expr(source_, std::forward<SCALAR>(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 <size_t N, typename ARG>
    void Append(Vector<const ast::Expression*, N>& list, ARG&& arg) {
        list.Push(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 <size_t N, typename ARG0, typename... ARGS>
    void Append(Vector<const ast::Expression*, N>& list, ARG0&& arg0, ARGS&&... args) {
        Append(list, std::forward<ARG0>(arg0));
        Append(list, std::forward<ARGS>(args)...);
    }

    /// @return EmptyType
    EmptyType ExprList() { return Empty; }

    /// @param args the list of expressions
    /// @return the list of expressions converted to `ast::Expression`s using
    /// `Expr()`,
    template <typename... ARGS, typename = DisableIfVectorLike<ARGS...>>
    auto ExprList(ARGS&&... args) {
        return Vector<const ast::Expression*, sizeof...(ARGS)>{Expr(args)...};
    }

    /// @param list the list of expressions
    /// @return `list`
    template <typename T, size_t N>
    Vector<T, N> ExprList(Vector<T, N>&& list) {
        return std::move(list);
    }

    /// @param list the list of expressions
    /// @return `list`
    VectorRef<const ast::Expression*> ExprList(VectorRef<const ast::Expression*> list) {
        return list;
    }

    /// @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 @p type constructed with the values
    /// `expr`.
    template <typename EXPR>
    const ast::BitcastExpression* Bitcast(ast::Type type, EXPR&& expr) {
        return Bitcast(source_, 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 @p type constructed with the values
    /// `expr`.
    template <typename EXPR>
    const ast::BitcastExpression* Bitcast(const Source& source, ast::Type type, EXPR&& expr) {
        return create<ast::BitcastExpression>(source, type, Expr(std::forward<EXPR>(expr)));
    }

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

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

    /// Adds the extension to the list of enable directives at the top of the module.
    /// @param extension the extension to enable
    /// @return an `ast::Enable` enabling the given extension.
    const ast::Enable* Enable(wgsl::Extension extension) {
        auto* ext = create<ast::Extension>(extension);
        auto* enable = create<ast::Enable>(Vector{ext});
        AST().AddEnable(enable);
        return enable;
    }

    /// Adds the extension to the list of enable directives at the top of the module.
    /// @param source the enable source
    /// @param extension the extension to enable
    /// @return an `ast::Enable` enabling the given extension.
    const ast::Enable* Enable(const Source& source, wgsl::Extension extension) {
        auto* ext = create<ast::Extension>(source, extension);
        auto* enable = create<ast::Enable>(source, Vector{ext});
        AST().AddEnable(enable);
        return enable;
    }

    /// Adds the language feature to the list of requires directives at the top of the module.
    /// @param feature the feature to require
    /// @return a `ast::Requires` requiring the given language feature.
    const ast::Requires* Require(wgsl::LanguageFeature feature) {
        auto* req = create<ast::Requires>(wgsl::LanguageFeatures({feature}));
        AST().AddRequires(req);
        return req;
    }

    /// Adds the language feature to the list of requires directives at the top of the module.
    /// @param source the requires source
    /// @param feature the feature to require
    /// @return a `ast::Requires` requiring the given language feature.
    const ast::Requires* Require(const Source& source, wgsl::LanguageFeature feature) {
        auto* req = create<ast::Requires>(source, wgsl::LanguageFeatures({feature}));
        AST().AddRequires(req);
        return req;
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Type              - specifies the variable's type
    ///   * core::AddressSpace  - specifies the variable's address space
    ///   * core::Access        - specifies the variable's access control
    ///   * ast::Expression*       - specifies the variable's initializer expression
    ///   * ast::Attribute*        - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns a `ast::Var` with the given name, type and additional
    /// options
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Var* Var(NAME&& name, OPTIONS&&... options) {
        return Var(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Type              - specifies the variable's type
    ///   * core::AddressSpace  - specifies the variable's address space
    ///   * core::Access        - specifies the variable's access control
    ///   * ast::Expression*       - specifies the variable's initializer expression
    ///   * ast::Attribute*        - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns a `ast::Var` with the given name, address_space and type
    template <typename NAME, typename... OPTIONS>
    const ast::Var* Var(const Source& source, NAME&& name, OPTIONS&&... options) {
        VarOptions opts(*this, std::forward<OPTIONS>(options)...);
        return create<ast::Var>(source, Ident(std::forward<NAME>(name)), opts.type,
                                opts.address_space, opts.access, opts.initializer,
                                std::move(opts.attributes));
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Const` with the given name, type and additional options
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Const* Const(NAME&& name, OPTIONS&&... options) {
        return Const(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Identifier*    - specifies the variable's type
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Const` with the given name, type and additional options
    template <typename NAME, typename... OPTIONS>
    const ast::Const* Const(const Source& source, NAME&& name, OPTIONS&&... options) {
        ConstOptions opts(std::forward<OPTIONS>(options)...);
        return create<ast::Const>(source, Ident(std::forward<NAME>(name)), opts.type,
                                  opts.initializer, std::move(opts.attributes));
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Let` with the given name, type and additional options
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Let* Let(NAME&& name, OPTIONS&&... options) {
        return Let(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Let` with the given name, type and additional options
    template <typename NAME, typename... OPTIONS>
    const ast::Let* Let(const Source& source, NAME&& name, OPTIONS&&... options) {
        LetOptions opts(std::forward<OPTIONS>(options)...);
        return create<ast::Let>(source, Ident(std::forward<NAME>(name)), opts.type,
                                opts.initializer, std::move(opts.attributes));
    }

    /// @param name the parameter name
    /// @param type the parameter type
    /// @param attributes optional parameter attributes
    /// @returns an `ast::Parameter` with the given name and type
    template <typename NAME>
    const ast::Parameter* Param(NAME&& name,
                                ast::Type type,
                                VectorRef<const ast::Attribute*> attributes = Empty) {
        return Param(source_, std::forward<NAME>(name), type, std::move(attributes));
    }

    /// @param source the parameter source
    /// @param name the parameter name
    /// @param type the parameter type
    /// @param attributes optional parameter attributes
    /// @returns an `ast::Parameter` with the given name and type
    template <typename NAME>
    const ast::Parameter* Param(const Source& source,
                                NAME&& name,
                                ast::Type type,
                                VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::Parameter>(source, Ident(std::forward<NAME>(name)), type,
                                      std::move(attributes));
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Type           - specifies the variable's type
    ///   * core::AddressSpace  - specifies the variable address space
    ///   * core::Access        - specifies the variable's access control
    ///   * ast::Expression*    - specifies the variable's initializer expression
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns a new `ast::Var`, which is automatically registered as a global variable with the
    /// ast::Module.
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Var* GlobalVar(NAME&& name, OPTIONS&&... options) {
        return GlobalVar(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Var initializer
    /// Can be any of the following, in any order:
    ///   * ast::Type           - specifies the variable's type
    ///   * core::AddressSpace  - specifies the variable address space
    ///   * core::Access        - specifies the variable's access control
    ///   * ast::Expression*    - specifies the variable's initializer expression
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns a new `ast::Var`, which is automatically registered as a global variable with the
    /// ast::Module.
    template <typename NAME, typename... OPTIONS>
    const ast::Var* GlobalVar(const Source& source, NAME&& name, OPTIONS&&... options) {
        auto* variable = Var(source, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
        AST().AddGlobalVariable(variable);
        return variable;
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Const initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Const` with the given name, type and additional options, which is
    /// automatically registered as a global variable with the ast::Module.
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Const* GlobalConst(NAME&& name, OPTIONS&&... options) {
        return GlobalConst(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Const initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Const` with the given name, type and additional options, which is
    /// automatically registered as a global variable with the ast::Module.
    template <typename NAME, typename... OPTIONS>
    const ast::Const* GlobalConst(const Source& source, NAME&& name, OPTIONS&&... options) {
        auto* variable = Const(source, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
        AST().AddGlobalVariable(variable);
        return variable;
    }

    /// @param name the variable name
    /// @param options the extra options passed to the ast::Override initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Override` with the given name, type and additional options, which is
    /// automatically registered as a global variable with the ast::Module.
    template <typename NAME, typename... OPTIONS, typename = DisableIfSource<NAME>>
    const ast::Override* Override(NAME&& name, OPTIONS&&... options) {
        return Override(source_, std::forward<NAME>(name), std::forward<OPTIONS>(options)...);
    }

    /// @param source the variable source
    /// @param name the variable name
    /// @param options the extra options passed to the ast::Override initializer
    /// Can be any of the following, in any order:
    ///   * ast::Expression*    - specifies the variable's initializer expression (required)
    ///   * ast::Type           - specifies the variable's type
    ///   * ast::Attribute*     - specifies the variable's attributes (repeatable, or vector)
    /// Note that non-repeatable arguments of the same type will use the last argument's value.
    /// @returns an `ast::Override` with the given name, type and additional options, which is
    /// automatically registered as a global variable with the ast::Module.
    template <typename NAME, typename... OPTIONS>
    const ast::Override* Override(const Source& source, NAME&& name, OPTIONS&&... options) {
        OverrideOptions opts(std::forward<OPTIONS>(options)...);
        auto* variable = create<ast::Override>(source, Ident(std::forward<NAME>(name)), opts.type,
                                               opts.initializer, std::move(opts.attributes));
        AST().AddGlobalVariable(variable);
        return variable;
    }

    /// @param source the source information
    /// @param condition the assertion condition
    /// @returns a new `ast::ConstAssert`, which is automatically registered as a global statement
    /// with the ast::Module.
    template <typename EXPR>
    const ast::ConstAssert* GlobalConstAssert(const Source& source, EXPR&& condition) {
        auto* sa = ConstAssert(source, std::forward<EXPR>(condition));
        AST().AddConstAssert(sa);
        return sa;
    }

    /// @param condition the assertion condition
    /// @returns a new `ast::ConstAssert`, which is automatically registered as a global statement
    /// with the ast::Module.
    template <typename EXPR, typename = DisableIfSource<EXPR>>
    const ast::ConstAssert* GlobalConstAssert(EXPR&& condition) {
        auto* sa = ConstAssert(std::forward<EXPR>(condition));
        AST().AddConstAssert(sa);
        return sa;
    }

    /// @param source the source information
    /// @param condition the assertion condition
    /// @returns a new `ast::ConstAssert` with the given assertion condition
    template <typename EXPR>
    const ast::ConstAssert* ConstAssert(const Source& source, EXPR&& condition) {
        return create<ast::ConstAssert>(source, Expr(std::forward<EXPR>(condition)));
    }

    /// @param condition the assertion condition
    /// @returns a new `ast::ConstAssert` with the given assertion condition
    template <typename EXPR, typename = DisableIfSource<EXPR>>
    const ast::ConstAssert* ConstAssert(EXPR&& condition) {
        return create<ast::ConstAssert>(Expr(std::forward<EXPR>(condition)));
    }

    /// @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, core::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>(core::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, core::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>(core::UnaryOp::kIndirection,
                                              Expr(std::forward<EXPR>(expr)));
    }

    /// @param expr the expression to perform a unary not on
    /// @return an ast::UnaryOpExpression that is the unary not of the input
    /// expression
    template <typename EXPR>
    const ast::UnaryOpExpression* Not(EXPR&& expr) {
        return create<ast::UnaryOpExpression>(core::UnaryOp::kNot, Expr(std::forward<EXPR>(expr)));
    }

    /// @param source the source information
    /// @param expr the expression to perform a unary not on
    /// @return an ast::UnaryOpExpression that is the unary not of the input
    /// expression
    template <typename EXPR>
    const ast::UnaryOpExpression* Not(const Source& source, EXPR&& expr) {
        return create<ast::UnaryOpExpression>(source, core::UnaryOp::kNot,
                                              Expr(std::forward<EXPR>(expr)));
    }

    /// @param expr the expression to perform a unary complement on
    /// @return an ast::UnaryOpExpression that is the unary complement of the
    /// input expression
    template <typename EXPR>
    const ast::UnaryOpExpression* Complement(EXPR&& expr) {
        return create<ast::UnaryOpExpression>(core::UnaryOp::kComplement,
                                              Expr(std::forward<EXPR>(expr)));
    }

    /// @param expr the expression to perform a unary negation on
    /// @return an ast::UnaryOpExpression that is the unary negation of the
    /// input expression
    template <typename EXPR>
    const ast::UnaryOpExpression* Negation(EXPR&& expr) {
        return create<ast::UnaryOpExpression>(core::UnaryOp::kNegation,
                                              Expr(std::forward<EXPR>(expr)));
    }

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

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

    /// @param target the call target
    /// @param args the function call arguments
    /// @returns an ast::CallExpression to the target @p target, with the arguments of @p args
    /// converted to `ast::Expression`s using Expr().
    template <typename TARGET,
              typename... ARGS,
              typename = DisableIfSource<TARGET>,
              typename = DisableIfScalar<TARGET>>
    const ast::CallExpression* Call(TARGET&& target, ARGS&&... args) {
        return Call(source_, Expr(std::forward<TARGET>(target)), std::forward<ARGS>(args)...);
    }

    /// @param source the source of the call
    /// @param target the call target
    /// @param args the function call arguments
    /// @returns an ast::CallExpression to the target @p target, with the arguments of @p args
    /// converted to `ast::Expression`s using Expr().
    template <typename TARGET, typename... ARGS, typename = DisableIfScalar<TARGET>>
    const ast::CallExpression* Call(const Source& source, TARGET&& target, ARGS&&... args) {
        return create<ast::CallExpression>(source, Expr(std::forward<TARGET>(target)),
                                           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>(core::BinaryOp::kAdd, Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @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(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::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>(core::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>(core::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>(
            core::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>(
            core::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, core::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::BinaryExpression* Div(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kDivide, Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @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::BinaryExpression* Div(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::BinaryOp::kDivide,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the modulo operation
    /// @param rhs the right hand argument to the modulo operation
    /// @returns a `ast::BinaryExpression` applying modulo of `lhs` by `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* Mod(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kModulo, 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>(core::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>(
            core::BinaryOp::kShiftLeft, Expr(std::forward<LHS>(lhs)), Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @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(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::BinaryOp::kShiftLeft,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

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

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

    /// @param source the source information
    /// @param lhs the left hand argument to the logical and operation
    /// @param rhs the right hand argument to the logical and operation
    /// @returns a `ast::BinaryExpression` of `lhs` && `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* LogicalAnd(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::BinaryOp::kLogicalAnd,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the logical or operation
    /// @param rhs the right hand argument to the logical or operation
    /// @returns a `ast::BinaryExpression` of `lhs` || `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* LogicalOr(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(
            core::BinaryOp::kLogicalOr, Expr(std::forward<LHS>(lhs)), Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @param lhs the left hand argument to the logical or operation
    /// @param rhs the right hand argument to the logical or operation
    /// @returns a `ast::BinaryExpression` of `lhs` || `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* LogicalOr(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::BinaryOp::kLogicalOr,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the greater than operation
    /// @param rhs the right hand argument to the greater than operation
    /// @returns a `ast::BinaryExpression` of `lhs` > `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* GreaterThan(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kGreaterThan,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the greater than or equal operation
    /// @param rhs the right hand argument to the greater than or equal operation
    /// @returns a `ast::BinaryExpression` of `lhs` >= `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* GreaterThanEqual(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kGreaterThanEqual,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the less than operation
    /// @param rhs the right hand argument to the less than operation
    /// @returns a `ast::BinaryExpression` of `lhs` < `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* LessThan(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(
            core::BinaryOp::kLessThan, Expr(std::forward<LHS>(lhs)), Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the less than or equal operation
    /// @param rhs the right hand argument to the less than or equal operation
    /// @returns a `ast::BinaryExpression` of `lhs` <= `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* LessThanEqual(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kLessThanEqual,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the equal expression
    /// @param rhs the right hand argument to the equal expression
    /// @returns a `ast::BinaryExpression` comparing `lhs` equal to `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* Equal(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(core::BinaryOp::kEqual, Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @param lhs the left hand argument to the equal expression
    /// @param rhs the right hand argument to the equal expression
    /// @returns a `ast::BinaryExpression` comparing `lhs` equal to `rhs`
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* Equal(const Source& source, LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(source, core::BinaryOp::kEqual,
                                             Expr(std::forward<LHS>(lhs)),
                                             Expr(std::forward<RHS>(rhs)));
    }

    /// @param lhs the left hand argument to the not-equal expression
    /// @param rhs the right hand argument to the not-equal expression
    /// @returns a `ast::BinaryExpression` comparing `lhs` equal to `rhs` for
    ///          disequality
    template <typename LHS, typename RHS>
    const ast::BinaryExpression* NotEqual(LHS&& lhs, RHS&& rhs) {
        return create<ast::BinaryExpression>(
            core::BinaryOp::kNotEqual, Expr(std::forward<LHS>(lhs)), Expr(std::forward<RHS>(rhs)));
    }

    /// @param source the source information
    /// @param object the object for the index accessor expression
    /// @param index the index argument for the index accessor expression
    /// @returns a `ast::IndexAccessorExpression` that indexes @p object with @p index
    template <typename OBJECT, typename INDEX>
    const ast::IndexAccessorExpression* IndexAccessor(const Source& source,
                                                      OBJECT&& object,
                                                      INDEX&& index) {
        return create<ast::IndexAccessorExpression>(source, Expr(std::forward<OBJECT>(object)),
                                                    Expr(std::forward<INDEX>(index)));
    }

    /// @param object the object for the index accessor expression
    /// @param index the index argument for the index accessor expression
    /// @returns a `ast::IndexAccessorExpression` that indexes @p object with @p index
    template <typename OBJECT, typename INDEX>
    const ast::IndexAccessorExpression* IndexAccessor(OBJECT&& object, INDEX&& index) {
        return create<ast::IndexAccessorExpression>(Expr(std::forward<OBJECT>(object)),
                                                    Expr(std::forward<INDEX>(index)));
    }

    /// @param source the source information
    /// @param object the object for the member accessor expression
    /// @param member the member argument for the member accessor expression
    /// @returns a `ast::MemberAccessorExpression` that indexes @p object with @p member
    template <typename OBJECT, typename MEMBER>
    const ast::MemberAccessorExpression* MemberAccessor(const Source& source,
                                                        OBJECT&& object,
                                                        MEMBER&& member) {
        static_assert(!traits::IsType<traits::PtrElTy<MEMBER>, ast::TemplatedIdentifier>,
                      "it is currently invalid for a structure to hold a templated member");
        return create<ast::MemberAccessorExpression>(source, Expr(std::forward<OBJECT>(object)),
                                                     Ident(std::forward<MEMBER>(member)));
    }

    /// @param object the object for the member accessor expression
    /// @param member the member argument for the member accessor expression
    /// @returns a `ast::MemberAccessorExpression` that indexes @p object with @p member
    template <typename OBJECT, typename MEMBER>
    const ast::MemberAccessorExpression* MemberAccessor(OBJECT&& object, MEMBER&& member) {
        return MemberAccessor(source_, std::forward<OBJECT>(object), std::forward<MEMBER>(member));
    }

    /// Creates a ast::StructMemberOffsetAttribute
    /// @param val the offset expression
    /// @returns the offset attribute pointer
    template <typename EXPR>
    const ast::StructMemberOffsetAttribute* MemberOffset(EXPR&& val) {
        return create<ast::StructMemberOffsetAttribute>(source_, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StructMemberOffsetAttribute
    /// @param source the source information
    /// @param val the offset expression
    /// @returns the offset attribute pointer
    template <typename EXPR>
    const ast::StructMemberOffsetAttribute* MemberOffset(const Source& source, EXPR&& val) {
        return create<ast::StructMemberOffsetAttribute>(source, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StructMemberSizeAttribute
    /// @param source the source information
    /// @param val the size value
    /// @returns the size attribute pointer
    template <typename EXPR>
    const ast::StructMemberSizeAttribute* MemberSize(const Source& source, EXPR&& val) {
        return create<ast::StructMemberSizeAttribute>(source, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StructMemberSizeAttribute
    /// @param val the size value
    /// @returns the size attribute pointer
    template <typename EXPR>
    const ast::StructMemberSizeAttribute* MemberSize(EXPR&& val) {
        return create<ast::StructMemberSizeAttribute>(source_, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StructMemberAlignAttribute
    /// @param source the source information
    /// @param val the align value expression
    /// @returns the align attribute pointer
    template <typename EXPR>
    const ast::StructMemberAlignAttribute* MemberAlign(const Source& source, EXPR&& val) {
        return create<ast::StructMemberAlignAttribute>(source, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StructMemberAlignAttribute
    /// @param val the align value expression
    /// @returns the align attribute pointer
    template <typename EXPR>
    const ast::StructMemberAlignAttribute* MemberAlign(EXPR&& val) {
        return create<ast::StructMemberAlignAttribute>(source_, Expr(std::forward<EXPR>(val)));
    }

    /// Creates a ast::StrideAttribute
    /// @param stride the array stride
    /// @returns the ast::StrideAttribute attribute
    const ast::StrideAttribute* Stride(uint32_t stride) {
        return create<ast::StrideAttribute>(source_, stride);
    }

    /// Creates the ast::GroupAttribute
    /// @param value group attribute index expresion
    /// @returns the group attribute pointer
    template <typename EXPR>
    const ast::GroupAttribute* Group(EXPR&& value) {
        return create<ast::GroupAttribute>(Expr(std::forward<EXPR>(value)));
    }

    /// Creates the ast::GroupAttribute
    /// @param source the source
    /// @param value group attribute index expression
    /// @returns the group attribute pointer
    template <typename EXPR>
    const ast::GroupAttribute* Group(const Source& source, EXPR&& value) {
        return create<ast::GroupAttribute>(source, Expr(std::forward<EXPR>(value)));
    }

    /// Creates the ast::BindingAttribute
    /// @param value the binding index expression
    /// @returns the binding deocration pointer
    template <typename EXPR>
    const ast::BindingAttribute* Binding(EXPR&& value) {
        return create<ast::BindingAttribute>(Expr(std::forward<EXPR>(value)));
    }

    /// Creates the ast::BindingAttribute
    /// @param source the source
    /// @param value the binding index expression
    /// @returns the binding deocration pointer
    template <typename EXPR>
    const ast::BindingAttribute* Binding(const Source& source, EXPR&& value) {
        return create<ast::BindingAttribute>(source, Expr(std::forward<EXPR>(value)));
    }

    /// 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. Can be an ast::BlockStatement*, as ast::Statement* which will
    /// be automatically placed into a block, or nullptr for a stub function.
    /// @param attributes the optional function attributes
    /// @param return_type_attributes the optional function return type attributes
    /// @returns the function pointer
    template <typename NAME, typename BODY = VectorRef<const ast::Statement*>>
    const ast::Function* Func(NAME&& name,
                              VectorRef<const ast::Parameter*> params,
                              ast::Type type,
                              BODY&& body,
                              VectorRef<const ast::Attribute*> attributes = Empty,
                              VectorRef<const ast::Attribute*> return_type_attributes = Empty) {
        return Func(source_, std::forward<NAME>(name), std::move(params), type,
                    std::forward<BODY>(body), std::move(attributes),
                    std::move(return_type_attributes));
    }

    /// 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. Can be an ast::BlockStatement*, as ast::Statement* which will
    /// be automatically placed into a block, or nullptr for a stub function.
    /// @param attributes the optional function attributes
    /// @param return_type_attributes the optional function return type attributes
    /// @returns the function pointer
    template <typename NAME, typename BODY = VectorRef<const ast::Statement*>>
    const ast::Function* Func(const Source& source,
                              NAME&& name,
                              VectorRef<const ast::Parameter*> params,
                              ast::Type type,
                              BODY&& body,
                              VectorRef<const ast::Attribute*> attributes = Empty,
                              VectorRef<const ast::Attribute*> return_type_attributes = Empty) {
        const ast::BlockStatement* block = nullptr;
        using BODY_T = traits::PtrElTy<BODY>;
        if constexpr (traits::IsTypeOrDerived<BODY_T, ast::BlockStatement> ||
                      std::is_same_v<BODY_T, std::nullptr_t>) {
            block = body;
        } else {
            block = Block(std::forward<BODY>(body));
        }
        auto* func =
            create<ast::Function>(source, Ident(std::forward<NAME>(name)), std::move(params), type,
                                  block, std::move(attributes), std::move(return_type_attributes));
        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 a ast::BreakIfStatement with input condition
    /// @param source the source information for the if statement
    /// @param condition the if statement condition expression
    /// @returns the break-if statement pointer
    template <typename CONDITION>
    const ast::BreakIfStatement* BreakIf(const Source& source, CONDITION&& condition) {
        return create<ast::BreakIfStatement>(source, Expr(std::forward<CONDITION>(condition)));
    }

    /// Creates a ast::BreakIfStatement with input condition
    /// @param condition the if statement condition expression
    /// @returns the break-if statement pointer
    template <typename CONDITION>
    const ast::BreakIfStatement* BreakIf(CONDITION&& condition) {
        return create<ast::BreakIfStatement>(Expr(std::forward<CONDITION>(condition)));
    }

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

    /// Creates an ast::ContinueStatement
    /// @returns the continue statement pointer
    const ast::ContinueStatement* Continue() { return create<ast::ContinueStatement>(); }

    /// 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 an ast::DiscardStatement
    /// @param source the source information
    /// @returns the discard statement pointer
    const ast::DiscardStatement* Discard(const Source& source) {
        return create<ast::DiscardStatement>(source);
    }

    /// Creates an ast::DiscardStatement
    /// @returns the discard statement pointer
    const ast::DiscardStatement* Discard() { return create<ast::DiscardStatement>(); }

    /// 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, ast::Type type) {
        return Alias(source_, std::forward<NAME>(name), type);
    }

    /// 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, ast::Type type) {
        auto out = ty.alias(source, std::forward<NAME>(name), type);
        AST().AddTypeDecl(out);
        return out;
    }

    /// Creates a ast::Struct registering it with the AST().TypeDecls().
    /// @param name the struct name
    /// @param members the struct members
    /// @param attributes the optional struct attributes
    /// @returns the struct type
    template <typename NAME>
    const ast::Struct* Structure(NAME&& name,
                                 VectorRef<const ast::StructMember*> members,
                                 VectorRef<const ast::Attribute*> attributes = Empty) {
        return Structure(source_, std::forward<NAME>(name), std::move(members),
                         std::move(attributes));
    }

    /// 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 attributes the optional struct attributes
    /// @returns the struct type
    template <typename NAME>
    const ast::Struct* Structure(const Source& source,
                                 NAME&& name,
                                 VectorRef<const ast::StructMember*> members,
                                 VectorRef<const ast::Attribute*> attributes = Empty) {
        auto* type = create<ast::Struct>(source, Ident(std::forward<NAME>(name)),
                                         std::move(members), std::move(attributes));
        AST().AddTypeDecl(type);
        return type;
    }

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

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

    /// Creates a ast::StructMember with the given byte offset
    /// @param offset the offset to use in the StructMemberOffsetAttribute
    /// @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, ast::Type type) {
        return create<ast::StructMember>(source_, Ident(std::forward<NAME>(name)), type,
                                         Vector<const ast::Attribute*, 1>{
                                             MemberOffset(core::AInt(offset)),
                                         });
    }

    /// Creates a ast::BlockStatement with input statements and attributes
    /// @param statements the statements of the block
    /// @param attributes the optional attributes of the block
    /// @returns the block statement pointer
    const ast::BlockStatement* Block(VectorRef<const ast::Statement*> statements,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return Block(source_, std::move(statements), std::move(attributes));
    }

    /// Creates a ast::BlockStatement with input statements and attributes
    /// @param source the source information for the block
    /// @param statements the statements of the block
    /// @param attributes the optional attributes of the block
    /// @returns the block statement pointer
    const ast::BlockStatement* Block(const Source& source,
                                     VectorRef<const ast::Statement*> statements,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::BlockStatement>(source, std::move(statements), std::move(attributes));
    }

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

    /// Creates a ast::BlockStatement with a parameter list of input statements
    /// @param source the source information for the block
    /// @param statements the optional statements of the block
    /// @returns the block statement pointer
    template <typename... STATEMENTS, typename = DisableIfVectorLike<STATEMENTS...>>
    const ast::BlockStatement* Block(const Source& source, STATEMENTS&&... statements) {
        return create<ast::BlockStatement>(source,
                                           Vector<const ast::Statement*, sizeof...(statements)>{
                                               std::forward<STATEMENTS>(statements)...,
                                           },
                                           Empty);
    }

    /// A wrapper type for the Else statement used to create If statements.
    struct ElseStmt {
        /// Default constructor - no else statement.
        ElseStmt() : stmt(nullptr) {}
        /// Constructor
        /// @param s The else statement
        explicit ElseStmt(const ast::Statement* s) : stmt(s) {}
        /// The else statement, or nullptr.
        const ast::Statement* stmt;
    };

    /// Creates a ast::IfStatement with input condition, body, and optional
    /// else statement
    /// @param source the source information for the if statement
    /// @param condition the if statement condition expression
    /// @param body the if statement body
    /// @param else_stmt optional else statement
    /// @param attributes optional attributes
    /// @returns the if statement pointer
    template <typename CONDITION>
    const ast::IfStatement* If(const Source& source,
                               CONDITION&& condition,
                               const ast::BlockStatement* body,
                               const ElseStmt else_stmt = ElseStmt(),
                               VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::IfStatement>(source, Expr(std::forward<CONDITION>(condition)), body,
                                        else_stmt.stmt, std::move(attributes));
    }

    /// Creates a ast::IfStatement with input condition, body, and optional
    /// else statement
    /// @param condition the if statement condition expression
    /// @param body the if statement body
    /// @param else_stmt optional else statement
    /// @param attributes optional attributes
    /// @returns the if statement pointer
    template <typename CONDITION>
    const ast::IfStatement* If(CONDITION&& condition,
                               const ast::BlockStatement* body,
                               const ElseStmt else_stmt = ElseStmt(),
                               VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::IfStatement>(Expr(std::forward<CONDITION>(condition)), body,
                                        else_stmt.stmt, std::move(attributes));
    }

    /// Creates an Else object.
    /// @param stmt else statement
    /// @returns the Else object
    ElseStmt Else(const ast::Statement* stmt) { return ElseStmt(stmt); }

    /// 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::CompoundAssignmentStatement with input lhs and rhs
    /// expressions, and a binary operator.
    /// @param source the source information
    /// @param lhs the left hand side expression initializer
    /// @param rhs the right hand side expression initializer
    /// @param op the binary operator
    /// @returns the compound assignment statement pointer
    template <typename LhsExpressionInit, typename RhsExpressionInit>
    const ast::CompoundAssignmentStatement* CompoundAssign(const Source& source,
                                                           LhsExpressionInit&& lhs,
                                                           RhsExpressionInit&& rhs,
                                                           core::BinaryOp op) {
        return create<ast::CompoundAssignmentStatement>(
            source, Expr(std::forward<LhsExpressionInit>(lhs)),
            Expr(std::forward<RhsExpressionInit>(rhs)), op);
    }

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

    /// Creates an ast::IncrementDecrementStatement with input lhs.
    /// @param source the source information
    /// @param lhs the left hand side expression initializer
    /// @returns the increment decrement statement pointer
    template <typename LhsExpressionInit>
    const ast::IncrementDecrementStatement* Increment(const Source& source,
                                                      LhsExpressionInit&& lhs) {
        return create<ast::IncrementDecrementStatement>(
            source, Expr(std::forward<LhsExpressionInit>(lhs)), true);
    }

    /// Creates a ast::IncrementDecrementStatement with input lhs.
    /// @param lhs the left hand side expression initializer
    /// @returns the increment decrement statement pointer
    template <typename LhsExpressionInit>
    const ast::IncrementDecrementStatement* Increment(LhsExpressionInit&& lhs) {
        return create<ast::IncrementDecrementStatement>(Expr(std::forward<LhsExpressionInit>(lhs)),
                                                        true);
    }

    /// Creates an ast::IncrementDecrementStatement with input lhs.
    /// @param source the source information
    /// @param lhs the left hand side expression initializer
    /// @returns the increment decrement statement pointer
    template <typename LhsExpressionInit>
    const ast::IncrementDecrementStatement* Decrement(const Source& source,
                                                      LhsExpressionInit&& lhs) {
        return create<ast::IncrementDecrementStatement>(
            source, Expr(std::forward<LhsExpressionInit>(lhs)), false);
    }

    /// Creates a ast::IncrementDecrementStatement with input lhs.
    /// @param lhs the left hand side expression initializer
    /// @returns the increment decrement statement pointer
    template <typename LhsExpressionInit>
    const ast::IncrementDecrementStatement* Decrement(LhsExpressionInit&& lhs) {
        return create<ast::IncrementDecrementStatement>(Expr(std::forward<LhsExpressionInit>(lhs)),
                                                        false);
    }

    /// Creates a ast::LoopStatement with input body and optional continuing
    /// @param source the source information
    /// @param body the loop body
    /// @param continuing the optional continuing block
    /// @param attributes optional attributes
    /// @returns the loop statement pointer
    const ast::LoopStatement* Loop(const Source& source,
                                   const ast::BlockStatement* body,
                                   const ast::BlockStatement* continuing = nullptr,
                                   VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::LoopStatement>(source, body, continuing, std::move(attributes));
    }

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

    /// Creates a ast::ForLoopStatement with input body and optional initializer, condition,
    /// continuing, and attributes.
    /// @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
    /// @param attributes optional attributes
    /// @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,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::ForLoopStatement>(source, init, Expr(std::forward<COND>(cond)), cont,
                                             body, std::move(attributes));
    }

    /// Creates a ast::ForLoopStatement with input body and optional initializer, condition,
    /// continuing, and attributes.
    /// @param init the optional loop initializer
    /// @param cond the optional loop condition
    /// @param cont the optional loop continuing
    /// @param body the loop body
    /// @param attributes optional attributes
    /// @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,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::ForLoopStatement>(init, Expr(std::forward<COND>(cond)), cont, body,
                                             std::move(attributes));
    }

    /// Creates a ast::WhileStatement with input body, condition, and optional attributes.
    /// @param source the source information
    /// @param cond the loop condition
    /// @param body the loop body
    /// @param attributes optional attributes
    /// @returns the while statement pointer
    template <typename COND>
    const ast::WhileStatement* While(const Source& source,
                                     COND&& cond,
                                     const ast::BlockStatement* body,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::WhileStatement>(source, Expr(std::forward<COND>(cond)), body,
                                           std::move(attributes));
    }

    /// Creates a ast::WhileStatement with input body, condition, and optional attributes.
    /// @param cond the condition
    /// @param body the loop body
    /// @param attributes optional attributes
    /// @returns the while loop statement pointer
    template <typename COND>
    const ast::WhileStatement* While(COND&& cond,
                                     const ast::BlockStatement* body,
                                     VectorRef<const ast::Attribute*> attributes = Empty) {
        return create<ast::WhileStatement>(Expr(std::forward<COND>(cond)), body,
                                           std::move(attributes));
    }

    /// 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, typename = DisableIfVectorLike<Cases...>>
    const ast::SwitchStatement* Switch(const Source& source,
                                       ExpressionInit&& condition,
                                       Cases&&... cases) {
        return create<ast::SwitchStatement>(
            source, Expr(std::forward<ExpressionInit>(condition)),
            Vector<const ast::CaseStatement*, sizeof...(cases)>{std::forward<Cases>(cases)...},
            Empty, Empty);
    }

    /// 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>,
              typename = DisableIfVectorLike<Cases...>>
    const ast::SwitchStatement* Switch(ExpressionInit&& condition, Cases&&... cases) {
        return create<ast::SwitchStatement>(
            Expr(std::forward<ExpressionInit>(condition)),
            Vector<const ast::CaseStatement*, sizeof...(cases)>{std::forward<Cases>(cases)...},
            Empty, Empty);
    }

    /// Creates a ast::SwitchStatement with input expression, cases, and optional attributes
    /// @param source the source information
    /// @param condition the condition expression initializer
    /// @param cases case statements
    /// @param stmt_attributes optional statement attributes
    /// @param body_attributes optional body attributes
    /// @returns the switch statement pointer
    template <typename ExpressionInit>
    const ast::SwitchStatement* Switch(const Source& source,
                                       ExpressionInit&& condition,
                                       VectorRef<const ast::CaseStatement*> cases,
                                       VectorRef<const ast::Attribute*> stmt_attributes = Empty,
                                       VectorRef<const ast::Attribute*> body_attributes = Empty) {
        return create<ast::SwitchStatement>(source, Expr(std::forward<ExpressionInit>(condition)),
                                            cases, std::move(stmt_attributes),
                                            std::move(body_attributes));
    }

    /// Creates a ast::SwitchStatement with input expression, cases, and optional attributes
    /// @param condition the condition expression initializer
    /// @param cases case statements
    /// @param stmt_attributes optional statement attributes
    /// @param body_attributes optional body attributes
    /// @returns the switch statement pointer
    template <typename ExpressionInit, typename = DisableIfSource<ExpressionInit>>
    const ast::SwitchStatement* Switch(ExpressionInit&& condition,
                                       VectorRef<const ast::CaseStatement*> cases,
                                       VectorRef<const ast::Attribute*> stmt_attributes = Empty,
                                       VectorRef<const ast::Attribute*> body_attributes = Empty) {
        return create<ast::SwitchStatement>(Expr(std::forward<ExpressionInit>(condition)), cases,
                                            std::move(stmt_attributes), std::move(body_attributes));
    }

    /// 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(VectorRef<const ast::CaseSelector*> selectors,
                                   const ast::BlockStatement* body = nullptr) {
        return Case(source_, std::move(selectors), body);
    }

    /// 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,
                                   VectorRef<const ast::CaseSelector*> selectors,
                                   const ast::BlockStatement* body = nullptr) {
        return create<ast::CaseStatement>(source, 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::CaseSelector* selector,
                                   const ast::BlockStatement* body = nullptr) {
        return Case(Vector{selector}, body ? body : Block());
    }

    /// 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 DefaultCase(source_, 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, Vector{DefaultCaseSelector(source)}, body);
    }

    /// Convenience function that creates a case selector
    /// @param source the source information
    /// @param expr the selector expression
    /// @returns the selector pointer
    template <typename EXPR>
    const ast::CaseSelector* CaseSelector(const Source& source, EXPR&& expr) {
        return create<ast::CaseSelector>(source, Expr(std::forward<EXPR>(expr)));
    }

    /// Convenience function that creates a case selector
    /// @param expr the selector expression
    /// @returns the selector pointer
    template <typename EXPR>
    const ast::CaseSelector* CaseSelector(EXPR&& expr) {
        return create<ast::CaseSelector>(source_, Expr(std::forward<EXPR>(expr)));
    }

    /// Convenience function that creates a default case selector
    /// @param source the source information
    /// @returns the selector pointer
    const ast::CaseSelector* DefaultCaseSelector(const Source& source) {
        return create<ast::CaseSelector>(source, nullptr);
    }

    /// Convenience function that creates a default case selector
    /// @returns the selector pointer
    const ast::CaseSelector* DefaultCaseSelector() { return create<ast::CaseSelector>(nullptr); }

    /// Creates an ast::BuiltinAttribute
    /// @param source the source information
    /// @param builtin the builtin value
    /// @returns the builtin attribute pointer
    template <typename BUILTIN>
    const ast::BuiltinAttribute* Builtin(const Source& source, BUILTIN&& builtin) {
        return create<ast::BuiltinAttribute>(source, Expr(std::forward<BUILTIN>(builtin)));
    }

    /// Creates an ast::BuiltinAttribute
    /// @param builtin the builtin value
    /// @returns the builtin attribute pointer
    template <typename BUILTIN>
    const ast::BuiltinAttribute* Builtin(BUILTIN&& builtin) {
        return create<ast::BuiltinAttribute>(source_, Expr(std::forward<BUILTIN>(builtin)));
    }

    /// Creates an ast::InterpolateAttribute
    /// @param type the interpolation type
    /// @returns the interpolate attribute pointer
    template <typename TYPE, typename = DisableIfSource<TYPE>>
    const ast::InterpolateAttribute* Interpolate(TYPE&& type) {
        return Interpolate(source_, std::forward<TYPE>(type));
    }

    /// Creates an ast::InterpolateAttribute
    /// @param source the source information
    /// @param type the interpolation type
    /// @returns the interpolate attribute pointer
    template <typename TYPE>
    const ast::InterpolateAttribute* Interpolate(const Source& source, TYPE&& type) {
        return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)), nullptr);
    }

    /// Creates an ast::InterpolateAttribute
    /// @param type the interpolation type
    /// @param sampling the interpolation sampling
    /// @returns the interpolate attribute pointer
    template <typename TYPE, typename SAMPLING, typename = DisableIfSource<TYPE>>
    const ast::InterpolateAttribute* Interpolate(TYPE&& type, SAMPLING&& sampling) {
        return Interpolate(source_, std::forward<TYPE>(type), std::forward<SAMPLING>(sampling));
    }

    /// Creates an ast::InterpolateAttribute
    /// @param source the source information
    /// @param type the interpolation type
    /// @param sampling the interpolation sampling
    /// @returns the interpolate attribute pointer
    template <typename TYPE, typename SAMPLING>
    const ast::InterpolateAttribute* Interpolate(const Source& source,
                                                 TYPE&& type,
                                                 SAMPLING&& sampling) {
        if constexpr (std::is_same_v<std::decay_t<SAMPLING>, core::InterpolationSampling>) {
            if (sampling == core::InterpolationSampling::kUndefined) {
                return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)),
                                                         nullptr);
            }
        }
        return create<ast::InterpolateAttribute>(source, Expr(std::forward<TYPE>(type)),
                                                 Expr(std::forward<SAMPLING>(sampling)));
    }

    /// Creates an ast::InterpolateAttribute using flat interpolation
    /// @param source the source information
    /// @returns the interpolate attribute pointer
    const ast::InterpolateAttribute* Flat(const Source& source) {
        return Interpolate(source, core::InterpolationType::kFlat);
    }

    /// Creates an ast::InterpolateAttribute using flat interpolation
    /// @returns the interpolate attribute pointer
    const ast::InterpolateAttribute* Flat() { return Interpolate(core::InterpolationType::kFlat); }

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

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

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

    /// Creates an ast::MustUseAttribute
    /// @returns the invariant attribute pointer
    const ast::MustUseAttribute* MustUse() { return create<ast::MustUseAttribute>(source_); }

    /// Creates an ast::LocationAttribute
    /// @param source the source information
    /// @param location the location value expression
    /// @returns the location attribute pointer
    template <typename EXPR>
    const ast::LocationAttribute* Location(const Source& source, EXPR&& location) {
        return create<ast::LocationAttribute>(source, Expr(std::forward<EXPR>(location)));
    }

    /// Creates an ast::LocationAttribute
    /// @param location the location value expression
    /// @returns the location attribute pointer
    template <typename EXPR>
    const ast::LocationAttribute* Location(EXPR&& location) {
        return create<ast::LocationAttribute>(source_, Expr(std::forward<EXPR>(location)));
    }

    /// Creates an ast::IndexAttribute
    /// @param source the source information
    /// @param index the index value expression
    /// @returns the index attribute pointer
    template <typename EXPR>
    const ast::IndexAttribute* Index(const Source& source, EXPR&& index) {
        return create<ast::IndexAttribute>(source, Expr(std::forward<EXPR>(index)));
    }

    /// Creates an ast::IndexAttribute
    /// @param index the index value expression
    /// @returns the index attribute pointer
    template <typename EXPR>
    const ast::IndexAttribute* Index(EXPR&& index) {
        return create<ast::IndexAttribute>(source_, Expr(std::forward<EXPR>(index)));
    }

    /// Creates an ast::IdAttribute
    /// @param source the source information
    /// @param id the id value
    /// @returns the override attribute pointer
    const ast::IdAttribute* Id(const Source& source, OverrideId id) {
        return create<ast::IdAttribute>(source, Expr(core::AInt(id.value)));
    }

    /// Creates an ast::IdAttribute with an override identifier
    /// @param id the optional id value
    /// @returns the override attribute pointer
    const ast::IdAttribute* Id(OverrideId id) {
        return create<ast::IdAttribute>(Expr(core::AInt(id.value)));
    }

    /// Creates an ast::IdAttribute
    /// @param source the source information
    /// @param id the id value expression
    /// @returns the override attribute pointer
    template <typename EXPR>
    const ast::IdAttribute* Id(const Source& source, EXPR&& id) {
        return create<ast::IdAttribute>(source, Expr(std::forward<EXPR>(id)));
    }

    /// Creates an ast::IdAttribute with an override identifier
    /// @param id the optional id value expression
    /// @returns the override attribute pointer
    template <typename EXPR>
    const ast::IdAttribute* Id(EXPR&& id) {
        return create<ast::IdAttribute>(Expr(std::forward<EXPR>(id)));
    }

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

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

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

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

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

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

    /// Creates an ast::WorkgroupAttribute
    /// @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 attribute pointer
    template <typename EXPR_X, typename EXPR_Y, typename EXPR_Z>
    const ast::WorkgroupAttribute* WorkgroupSize(const Source& source,
                                                 EXPR_X&& x,
                                                 EXPR_Y&& y,
                                                 EXPR_Z&& z) {
        return create<ast::WorkgroupAttribute>(source, Expr(std::forward<EXPR_X>(x)),
                                               Expr(std::forward<EXPR_Y>(y)),
                                               Expr(std::forward<EXPR_Z>(z)));
    }

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

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

    /// Passthrough overload
    /// @param name the diagnostic rule name
    /// @returns @p name
    const ast::DiagnosticRuleName* DiagnosticRuleName(const ast::DiagnosticRuleName* name) {
        return name;
    }

    /// Creates an ast::DiagnosticRuleName
    /// @param name the diagnostic rule name
    /// @returns the diagnostic rule name
    template <typename NAME>
    const ast::DiagnosticRuleName* DiagnosticRuleName(NAME&& name) {
        static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule name to be templated");
        auto* name_ident = Ident(std::forward<NAME>(name));
        return create<ast::DiagnosticRuleName>(name_ident->source, name_ident);
    }

    /// Creates an ast::DiagnosticRuleName
    /// @param category the diagnostic rule category
    /// @param name the diagnostic rule name
    /// @returns the diagnostic rule name
    template <typename CATEGORY, typename NAME, typename = DisableIfSource<CATEGORY>>
    const ast::DiagnosticRuleName* DiagnosticRuleName(CATEGORY&& category, NAME&& name) {
        static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule name to be templated");
        static_assert(!traits::IsType<traits::PtrElTy<CATEGORY>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule category to be templated");
        auto* category_ident = Ident(std::forward<CATEGORY>(category));
        auto* name_ident = Ident(std::forward<NAME>(name));
        Source source = category_ident->source;
        source.range.end = name_ident->source.range.end;
        return create<ast::DiagnosticRuleName>(source, category_ident, name_ident);
    }

    /// Creates an ast::DiagnosticRuleName
    /// @param source the source information
    /// @param name the diagnostic rule name
    /// @returns the diagnostic rule name
    template <typename NAME>
    const ast::DiagnosticRuleName* DiagnosticRuleName(const Source& source, NAME&& name) {
        static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule name to be templated");
        auto* name_ident = Ident(std::forward<NAME>(name));
        return create<ast::DiagnosticRuleName>(source, name_ident);
    }

    /// Creates an ast::DiagnosticRuleName
    /// @param source the source information
    /// @param category the diagnostic rule category
    /// @param name the diagnostic rule name
    /// @returns the diagnostic rule name
    template <typename CATEGORY, typename NAME>
    const ast::DiagnosticRuleName* DiagnosticRuleName(const Source& source,
                                                      CATEGORY&& category,
                                                      NAME&& name) {
        static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule name to be templated");
        static_assert(!traits::IsType<traits::PtrElTy<CATEGORY>, ast::TemplatedIdentifier>,
                      "it is invalid for a diagnostic rule category to be templated");
        auto* category_ident = Ident(std::forward<CATEGORY>(category));
        auto* name_ident = Ident(std::forward<NAME>(name));
        return create<ast::DiagnosticRuleName>(source, category_ident, name_ident);
    }

    /// Creates an ast::DiagnosticAttribute
    /// @param source the source information
    /// @param severity the diagnostic severity control
    /// @param rule_args the arguments used to construct the rule name
    /// @returns the diagnostic attribute pointer
    template <typename... RULE_ARGS>
    const ast::DiagnosticAttribute* DiagnosticAttribute(const Source& source,
                                                        wgsl::DiagnosticSeverity severity,
                                                        RULE_ARGS&&... rule_args) {
        return create<ast::DiagnosticAttribute>(
            source, ast::DiagnosticControl(
                        severity, DiagnosticRuleName(std::forward<RULE_ARGS>(rule_args)...)));
    }

    /// Creates an ast::DiagnosticAttribute
    /// @param severity the diagnostic severity control
    /// @param rule_args the arguments used to construct the rule name
    /// @returns the diagnostic attribute pointer
    template <typename... RULE_ARGS>
    const ast::DiagnosticAttribute* DiagnosticAttribute(wgsl::DiagnosticSeverity severity,
                                                        RULE_ARGS&&... rule_args) {
        return create<ast::DiagnosticAttribute>(
            source_, ast::DiagnosticControl(
                         severity, DiagnosticRuleName(std::forward<RULE_ARGS>(rule_args)...)));
    }

    /// Add a diagnostic directive to the module.
    /// @param source the source information
    /// @param severity the diagnostic severity control
    /// @param rule_args the arguments used to construct the rule name
    /// @returns the diagnostic directive pointer
    template <typename... RULE_ARGS>
    const ast::DiagnosticDirective* DiagnosticDirective(const Source& source,
                                                        wgsl::DiagnosticSeverity severity,
                                                        RULE_ARGS&&... rule_args) {
        auto* rule = DiagnosticRuleName(std::forward<RULE_ARGS>(rule_args)...);
        auto* directive =
            create<ast::DiagnosticDirective>(source, ast::DiagnosticControl(severity, rule));
        AST().AddDiagnosticDirective(directive);
        return directive;
    }

    /// Add a diagnostic directive to the module.
    /// @param severity the diagnostic severity control
    /// @param rule_args the arguments used to construct the rule name
    /// @returns the diagnostic directive pointer
    template <typename... RULE_ARGS>
    const ast::DiagnosticDirective* DiagnosticDirective(wgsl::DiagnosticSeverity severity,
                                                        RULE_ARGS&&... rule_args) {
        auto* rule = DiagnosticRuleName(std::forward<RULE_ARGS>(rule_args)...);
        auto* directive =
            create<ast::DiagnosticDirective>(source_, ast::DiagnosticControl(severity, rule));
        AST().AddDiagnosticDirective(directive);
        return directive;
    }

    /// 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);
    }

    /// 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,
              typename = traits::EnableIf<(CanWrapInStatement<ARGS>::value && ...)>>
    const ast::Function* WrapInFunction(ARGS&&... args) {
        Vector 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(VectorRef<const ast::Statement*> stmts);

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

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

    /// The unique identifier for this program
    GenerationID id_;

    /// The last Node identifier
    ast::NodeID last_ast_node_id_ = ast::NodeID{static_cast<decltype(ast::NodeID::value)>(0) - 1};

    /// Allocator for AST nodes
    ASTNodeAllocator ast_nodes_;

    /// The AST node module
    ast::Module* ast_ = nullptr;

    /// The symbol table
    SymbolTable symbols_{id_};

    /// The diagnostic list
    diag::List diagnostics_;

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

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

//! @cond Doxygen_Suppress
// Various template specializations for Builder::TypesBuilder::CToAST.
template <>
struct Builder::TypesBuilder::CToAST<core::AInt> {
    static ast::Type get(const Builder::TypesBuilder*) { return ast::Type{}; }
};
template <>
struct Builder::TypesBuilder::CToAST<core::AFloat> {
    static ast::Type get(const Builder::TypesBuilder*) { return ast::Type{}; }
};
template <>
struct Builder::TypesBuilder::CToAST<core::i32> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->i32(); }
};
template <>
struct Builder::TypesBuilder::CToAST<core::u32> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->u32(); }
};
template <>
struct Builder::TypesBuilder::CToAST<core::f32> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->f32(); }
};
template <>
struct Builder::TypesBuilder::CToAST<core::f16> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->f16(); }
};
template <>
struct Builder::TypesBuilder::CToAST<bool> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->bool_(); }
};
template <typename T, uint32_t N>
struct Builder::TypesBuilder::CToAST<core::fluent_types::array<T, N>> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->array<T, N>(); }
};
template <typename T>
struct Builder::TypesBuilder::CToAST<core::fluent_types::atomic<T>> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->atomic<T>(); }
};
template <uint32_t C, uint32_t R, typename T>
struct Builder::TypesBuilder::CToAST<core::fluent_types::mat<C, R, T>> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->mat<T>(C, R); }
};
template <uint32_t N, typename T>
struct Builder::TypesBuilder::CToAST<core::fluent_types::vec<N, T>> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->vec<T, N>(); }
};
template <core::AddressSpace ADDRESS, typename T, core::Access ACCESS>
struct Builder::TypesBuilder::CToAST<core::fluent_types::ptr<ADDRESS, T, ACCESS>> {
    static ast::Type get(const Builder::TypesBuilder* t) { return t->ptr<ADDRESS, T, ACCESS>(); }
};
//! @endcond

// Primary template for metafunction that evaluates to true iff T can be wrapped in a statement.
template <typename T, typename /*  = void */>
struct CanWrapInStatement : std::false_type {};

// Specialization of CanWrapInStatement
template <typename T>
struct CanWrapInStatement<
    T,
    std::void_t<decltype(std::declval<Builder>().WrapInStatement(std::declval<T>()))>>
    : std::true_type {};

}  // namespace tint::ast

namespace tint {

/// @param builder the Builder
/// @returns the GenerationID of the ast::Builder
inline GenerationID GenerationIDOf(const ast::Builder* builder) {
    return builder->ID();
}

}  // namespace tint

#endif  // SRC_TINT_LANG_WGSL_AST_BUILDER_H_
