Split Program into Program and ProgramBuilder

Program is now immutable*, and remains part of the public Tint
interface.

ProgramBuilder is the mutable builder for Programs, and is not part of
the public Tint interface. ast::Builder has been folded into
ProgramBuilder.

Immutable Programs can be cloned into a mutable ProgramBuilder with
Program::CloneAsBuilder().

Mutable ProgramBuilders can be moved into immutable Programs.

* - mostly immutable. It still has a move constructor and move
  assignment operator - required for practical usage - and the
  semantic information on AST nodes is still mutable.

Bug: tint:390
Change-Id: Ia856c50b1880c2f95c91467a9eef5024cbc380c6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38240
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/access_decoration.cc b/src/ast/access_decoration.cc
index 996c3c7..c535160 100644
--- a/src/ast/access_decoration.cc
+++ b/src/ast/access_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/access_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::AccessDecoration);
 
diff --git a/src/ast/array_accessor_expression.cc b/src/ast/array_accessor_expression.cc
index 6a9e6be..be763db 100644
--- a/src/ast/array_accessor_expression.cc
+++ b/src/ast/array_accessor_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/array_accessor_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ArrayAccessorExpression);
 
diff --git a/src/ast/assignment_statement.cc b/src/ast/assignment_statement.cc
index a0b1a2b..a92c6e3 100644
--- a/src/ast/assignment_statement.cc
+++ b/src/ast/assignment_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/assignment_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::AssignmentStatement);
 
diff --git a/src/ast/binary_expression.cc b/src/ast/binary_expression.cc
index de5065d..5c59cbd 100644
--- a/src/ast/binary_expression.cc
+++ b/src/ast/binary_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/binary_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BinaryExpression);
 
diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc
index 05a0d86..10a6bff 100644
--- a/src/ast/binding_decoration.cc
+++ b/src/ast/binding_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/binding_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BindingDecoration);
 
diff --git a/src/ast/bitcast_expression.cc b/src/ast/bitcast_expression.cc
index 85c42a5..26e5230 100644
--- a/src/ast/bitcast_expression.cc
+++ b/src/ast/bitcast_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/bitcast_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BitcastExpression);
 
diff --git a/src/ast/block_statement.cc b/src/ast/block_statement.cc
index 2ce6b34..07ff30f 100644
--- a/src/ast/block_statement.cc
+++ b/src/ast/block_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/block_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BlockStatement);
 
diff --git a/src/ast/bool_literal.cc b/src/ast/bool_literal.cc
index a8004e6..e162d1c 100644
--- a/src/ast/bool_literal.cc
+++ b/src/ast/bool_literal.cc
@@ -15,7 +15,7 @@
 #include "src/ast/bool_literal.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BoolLiteral);
 
diff --git a/src/ast/break_statement.cc b/src/ast/break_statement.cc
index 1a7cc9d..6bf034c 100644
--- a/src/ast/break_statement.cc
+++ b/src/ast/break_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/break_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BreakStatement);
 
diff --git a/src/ast/builder.cc b/src/ast/builder.cc
deleted file mode 100644
index 9e3062e..0000000
--- a/src/ast/builder.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/ast/builder.h"
-
-namespace tint {
-namespace ast {
-
-TypesBuilder::TypesBuilder(Program* p)
-    : program_(p) {}
-
-Builder::Builder(Program* p) : program(p), ty(p), mod(p) {}
-
-Builder::~Builder() = default;
-
-Variable* Builder::Var(const std::string& name,
-                       StorageClass storage,
-                       type::Type* type) {
-  return Var(name, storage, type, nullptr, {});
-}
-
-Variable* Builder::Var(const std::string& name,
-                       StorageClass storage,
-                       type::Type* type,
-                       Expression* constructor,
-                       VariableDecorationList decorations) {
-  auto* var = create<Variable>(program->Symbols().Register(name), storage, type,
-                               false, constructor, decorations);
-  OnVariableBuilt(var);
-  return var;
-}
-
-Variable* Builder::Var(const Source& source,
-                       const std::string& name,
-                       StorageClass storage,
-                       type::Type* type,
-                       Expression* constructor,
-                       VariableDecorationList decorations) {
-  auto* var = create<Variable>(source, program->Symbols().Register(name),
-                               storage, type, false, constructor, decorations);
-  OnVariableBuilt(var);
-  return var;
-}
-
-Variable* Builder::Const(const std::string& name,
-                         StorageClass storage,
-                         type::Type* type) {
-  return Const(name, storage, type, nullptr, {});
-}
-
-Variable* Builder::Const(const std::string& name,
-                         StorageClass storage,
-                         type::Type* type,
-                         Expression* constructor,
-                         VariableDecorationList decorations) {
-  auto* var = create<Variable>(program->Symbols().Register(name), storage, type,
-                               true, constructor, decorations);
-  OnVariableBuilt(var);
-  return var;
-}
-
-Variable* Builder::Const(const Source& source,
-                         const std::string& name,
-                         StorageClass storage,
-                         type::Type* type,
-                         Expression* constructor,
-                         VariableDecorationList decorations) {
-  auto* var = create<Variable>(source, program->Symbols().Register(name),
-                               storage, type, true, constructor, decorations);
-  OnVariableBuilt(var);
-  return var;
-}
-
-BuilderWithProgram::BuilderWithProgram() : Builder(new Program()) {}
-
-BuilderWithProgram::~BuilderWithProgram() {
-  delete program;
-}
-
-}  // namespace ast
-}  // namespace tint
diff --git a/src/ast/builder.h b/src/ast/builder.h
deleted file mode 100644
index d77b0b9..0000000
--- a/src/ast/builder.h
+++ /dev/null
@@ -1,804 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#ifndef SRC_AST_BUILDER_H_
-#define SRC_AST_BUILDER_H_
-
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "src/ast/array_accessor_expression.h"
-#include "src/ast/binary_expression.h"
-#include "src/ast/bool_literal.h"
-#include "src/ast/call_expression.h"
-#include "src/ast/expression.h"
-#include "src/ast/float_literal.h"
-#include "src/ast/identifier_expression.h"
-#include "src/ast/member_accessor_expression.h"
-#include "src/ast/scalar_constructor_expression.h"
-#include "src/ast/sint_literal.h"
-#include "src/ast/struct.h"
-#include "src/ast/struct_member.h"
-#include "src/ast/struct_member_offset_decoration.h"
-#include "src/ast/type_constructor_expression.h"
-#include "src/ast/uint_literal.h"
-#include "src/ast/variable.h"
-#include "src/program.h"
-#include "src/type/alias_type.h"
-#include "src/type/array_type.h"
-#include "src/type/bool_type.h"
-#include "src/type/f32_type.h"
-#include "src/type/i32_type.h"
-#include "src/type/matrix_type.h"
-#include "src/type/pointer_type.h"
-#include "src/type/struct_type.h"
-#include "src/type/u32_type.h"
-#include "src/type/vector_type.h"
-#include "src/type/void_type.h"
-
-namespace tint {
-namespace ast {
-
-/// TypesBuilder holds basic `tint` types and methods for constructing
-/// complex types.
-class TypesBuilder {
- public:
-  /// Constructor
-  /// @param program the program
-  explicit TypesBuilder(Program* program);
-
-  /// @return the tint AST type for the C type `T`.
-  template <typename T>
-  type::Type* Of() const {
-    return CToAST<T>::get(this);
-  }
-
-  /// @returns A boolean type
-  type::Bool* bool_() const { return program_->create<type::Bool>(); }
-
-  /// @returns A f32 type
-  type::F32* f32() const { return program_->create<type::F32>(); }
-
-  /// @returns A i32 type
-  type::I32* i32() const { return program_->create<type::I32>(); }
-
-  /// @returns A u32 type
-  type::U32* u32() const { return program_->create<type::U32>(); }
-
-  /// @returns A void type
-  type::Void* void_() const { return program_->create<type::Void>(); }
-
-  /// @return the tint AST type for a 2-element vector of the C type `T`.
-  template <typename T>
-  type::Vector* vec2() const {
-    return program_->create<type::Vector>(Of<T>(), 2);
-  }
-
-  /// @return the tint AST type for a 3-element vector of the C type `T`.
-  template <typename T>
-  type::Vector* vec3() const {
-    return program_->create<type::Vector>(Of<T>(), 3);
-  }
-
-  /// @return the tint AST type for a 4-element vector of the C type `T`.
-  template <typename T>
-  type::Type* vec4() const {
-    return program_->create<type::Vector>(Of<T>(), 4);
-  }
-
-  /// @return the tint AST type for a 2x3 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat2x2() const {
-    return program_->create<type::Matrix>(Of<T>(), 2, 2);
-  }
-
-  /// @return the tint AST type for a 2x3 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat2x3() const {
-    return program_->create<type::Matrix>(Of<T>(), 3, 2);
-  }
-
-  /// @return the tint AST type for a 2x4 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat2x4() const {
-    return program_->create<type::Matrix>(Of<T>(), 4, 2);
-  }
-
-  /// @return the tint AST type for a 3x2 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat3x2() const {
-    return program_->create<type::Matrix>(Of<T>(), 2, 3);
-  }
-
-  /// @return the tint AST type for a 3x3 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat3x3() const {
-    return program_->create<type::Matrix>(Of<T>(), 3, 3);
-  }
-
-  /// @return the tint AST type for a 3x4 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat3x4() const {
-    return program_->create<type::Matrix>(Of<T>(), 4, 3);
-  }
-
-  /// @return the tint AST type for a 4x2 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat4x2() const {
-    return program_->create<type::Matrix>(Of<T>(), 2, 4);
-  }
-
-  /// @return the tint AST type for a 4x3 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat4x3() const {
-    return program_->create<type::Matrix>(Of<T>(), 3, 4);
-  }
-
-  /// @return the tint AST type for a 4x4 matrix of the C type `T`.
-  template <typename T>
-  type::Matrix* mat4x4() const {
-    return program_->create<type::Matrix>(Of<T>(), 4, 4);
-  }
-
-  /// @param subtype the array element type
-  /// @param n the array size. 0 represents a runtime-array.
-  /// @return the tint AST type for a array of size `n` of type `T`
-  type::Array* array(type::Type* subtype, uint32_t n) const {
-    return program_->create<type::Array>(subtype, n, ArrayDecorationList{});
-  }
-
-  /// @return the tint AST type for an array of size `N` of type `T`
-  template <typename T, int N = 0>
-  type::Array* array() const {
-    return array(Of<T>(), N);
-  }
-
-  /// Creates an alias type
-  /// @param name the alias name
-  /// @param type the alias type
-  /// @returns the alias pointer
-  type::Alias* alias(const std::string& name, type::Type* type) const {
-    return program_->create<type::Alias>(program_->Symbols().Register(name),
-                                         type);
-  }
-
-  /// @return the tint AST pointer to type `T` with the given StorageClass.
-  /// @param storage_class the storage class of the pointer
-  template <typename T>
-  type::Pointer* pointer(StorageClass storage_class) const {
-    return program_->create<type::Pointer>(Of<T>(), storage_class);
-  }
-
-  /// @param name the struct name
-  /// @param impl the struct implementation
-  /// @returns a struct pointer
-  type::Struct* struct_(const std::string& name, ast::Struct* impl) const {
-    return program_->create<type::Struct>(program_->Symbols().Register(name),
-                                          impl);
-  }
-
- 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 type::Type* get(Types* t)`
-  template <typename T>
-  struct CToAST {};
-
-  Program* const program_;
-};
-
-/// Helper for building common AST constructs.
-class Builder {
- public:
-  /// `i32` is a type alias to `int`.
-  /// Useful for passing to template methods such as `vec2<i32>()` to imitate
-  /// WGSL syntax.
-  /// Note: this is intentionally not aliased to uint32_t as we want integer
-  /// literals passed to the builder to match WGSL's integer literal types.
-  using i32 = decltype(1);
-  /// `u32` is a type alias to `unsigned int`.
-  /// Useful for passing to template methods such as `vec2<u32>()` to imitate
-  /// WGSL syntax.
-  /// Note: this is intentionally not aliased to uint32_t as we want integer
-  /// literals passed to the builder to match WGSL's integer literal types.
-  using u32 = decltype(1u);
-  /// `f32` is a type alias to `float`
-  /// Useful for passing to template methods such as `vec2<f32>()` to imitate
-  /// WGSL syntax.
-  using f32 = float;
-
-  /// Constructor
-  /// @param program the program to build
-  explicit Builder(Program* program);
-  virtual ~Builder();
-
-  /// @param expr the expression
-  /// @return expr
-  Expression* Expr(Expression* expr) { return expr; }
-
-  /// @param name the identifier name
-  /// @return an IdentifierExpression with the given name
-  IdentifierExpression* Expr(const std::string& name) {
-    return create<IdentifierExpression>(program->Symbols().Register(name));
-  }
-
-  /// @param source the source information
-  /// @param name the identifier name
-  /// @return an IdentifierExpression with the given name
-  IdentifierExpression* Expr(const Source& source, const std::string& name) {
-    return create<IdentifierExpression>(source,
-                                        program->Symbols().Register(name));
-  }
-
-  /// @param name the identifier name
-  /// @return an IdentifierExpression with the given name
-  IdentifierExpression* Expr(const char* name) {
-    return create<IdentifierExpression>(program->Symbols().Register(name));
-  }
-
-  /// @param value the boolean value
-  /// @return a Scalar constructor for the given value
-  ScalarConstructorExpression* Expr(bool value) {
-    return create<ScalarConstructorExpression>(Literal(value));
-  }
-
-  /// @param value the float value
-  /// @return a Scalar constructor for the given value
-  ScalarConstructorExpression* Expr(f32 value) {
-    return create<ScalarConstructorExpression>(Literal(value));
-  }
-
-  /// @param value the integer value
-  /// @return a Scalar constructor for the given value
-  ScalarConstructorExpression* Expr(i32 value) {
-    return create<ScalarConstructorExpression>(Literal(value));
-  }
-
-  /// @param value the unsigned int value
-  /// @return a Scalar constructor for the given value
-  ScalarConstructorExpression* Expr(u32 value) {
-    return create<ScalarConstructorExpression>(Literal(value));
-  }
-
-  /// Converts `arg` to an `Expression` using `Expr()`, then appends it to
-  /// `list`.
-  /// @param list the list to append too
-  /// @param arg the arg to create
-  template <typename ARG>
-  void Append(ExpressionList& list, ARG&& arg) {
-    list.emplace_back(Expr(std::forward<ARG>(arg)));
-  }
-
-  /// Converts `arg0` and `args` to `Expression`s using `Expr()`,
-  /// then appends them to `list`.
-  /// @param list the list to append too
-  /// @param arg0 the first argument
-  /// @param args the rest of the arguments
-  template <typename ARG0, typename... ARGS>
-  void Append(ExpressionList& list, ARG0&& arg0, ARGS&&... args) {
-    Append(list, std::forward<ARG0>(arg0));
-    Append(list, std::forward<ARGS>(args)...);
-  }
-
-  /// @return an empty list of expressions
-  ExpressionList ExprList() { return {}; }
-
-  /// @param args the list of expressions
-  /// @return the list of expressions converted to `Expression`s using
-  /// `Expr()`,
-  template <typename... ARGS>
-  ExpressionList ExprList(ARGS&&... args) {
-    ExpressionList list;
-    list.reserve(sizeof...(args));
-    Append(list, std::forward<ARGS>(args)...);
-    return list;
-  }
-
-  /// @param list the list of expressions
-  /// @return `list`
-  ExpressionList ExprList(ExpressionList list) { return list; }
-
-  /// @param val the boolan value
-  /// @return a boolean literal with the given value
-  BoolLiteral* Literal(bool val) {
-    return create<BoolLiteral>(ty.bool_(), val);
-  }
-
-  /// @param val the float value
-  /// @return a float literal with the given value
-  FloatLiteral* Literal(f32 val) { return create<FloatLiteral>(ty.f32(), val); }
-
-  /// @param val the unsigned int value
-  /// @return a UintLiteral with the given value
-  UintLiteral* Literal(u32 val) { return create<UintLiteral>(ty.u32(), val); }
-
-  /// @param val the integer value
-  /// @return the SintLiteral with the given value
-  SintLiteral* Literal(i32 val) { return create<SintLiteral>(ty.i32(), val); }
-
-  /// @param args the arguments for the type constructor
-  /// @return an `TypeConstructorExpression` of type `ty`, with the values
-  /// of `args` converted to `Expression`s using `Expr()`
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* Construct(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.Of<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param type the type to construct
-  /// @param args the arguments for the constructor
-  /// @return an `TypeConstructorExpression` of `type` constructed with the
-  /// values `args`.
-  template <typename... ARGS>
-  TypeConstructorExpression* Construct(type::Type* type, ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        type, ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the vector constructor
-  /// @return an `TypeConstructorExpression` of a 2-element vector of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* vec2(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.vec2<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the vector constructor
-  /// @return an `TypeConstructorExpression` of a 3-element vector of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* vec3(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.vec3<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the vector constructor
-  /// @return an `TypeConstructorExpression` of a 4-element vector of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* vec4(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.vec4<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 2x2 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat2x2(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat2x2<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 2x3 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat2x3(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat2x3<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 2x4 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat2x4(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat2x4<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 3x2 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat3x2(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat3x2<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 3x3 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat3x3(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat3x3<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 3x4 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat3x4(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat3x4<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 4x2 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat4x2(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat4x2<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 4x3 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat4x3(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat4x3<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the matrix constructor
-  /// @return an `TypeConstructorExpression` of a 4x4 matrix of type
-  /// `T`, constructed with the values `args`.
-  template <typename T, typename... ARGS>
-  TypeConstructorExpression* mat4x4(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.mat4x4<T>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param args the arguments for the array constructor
-  /// @return an `TypeConstructorExpression` of an array with element type
-  /// `T`, constructed with the values `args`.
-  template <typename T, int N = 0, typename... ARGS>
-  TypeConstructorExpression* array(ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.array<T, N>(), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param subtype the array element type
-  /// @param n the array size. 0 represents a runtime-array.
-  /// @param args the arguments for the array constructor
-  /// @return an `TypeConstructorExpression` of an array with element type
-  /// `subtype`, constructed with the values `args`.
-  template <typename... ARGS>
-  TypeConstructorExpression* array(type::Type* subtype,
-                                   uint32_t n,
-                                   ARGS&&... args) {
-    return create<TypeConstructorExpression>(
-        ty.array(subtype, n), ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @returns a `Variable` with the given name, storage and type. The variable
-  /// will be built with a nullptr constructor and no decorations.
-  Variable* Var(const std::string& name,
-                StorageClass storage,
-                type::Type* type);
-
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @param constructor constructor expression
-  /// @param decorations variable decorations
-  /// @returns a `Variable` with the given name, storage and type
-  Variable* Var(const std::string& name,
-                StorageClass storage,
-                type::Type* type,
-                Expression* constructor,
-                VariableDecorationList decorations);
-
-  /// @param source the variable source
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @param constructor constructor expression
-  /// @param decorations variable decorations
-  /// @returns a `Variable` with the given name, storage and type
-  Variable* Var(const Source& source,
-                const std::string& name,
-                StorageClass storage,
-                type::Type* type,
-                Expression* constructor,
-                VariableDecorationList decorations);
-
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @returns a constant `Variable` with the given name, storage and type. The
-  /// variable will be built with a nullptr constructor and no decorations.
-  Variable* Const(const std::string& name,
-                  StorageClass storage,
-                  type::Type* type);
-
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @param constructor optional constructor expression
-  /// @param decorations optional variable decorations
-  /// @returns a constant `Variable` with the given name, storage and type
-  Variable* Const(const std::string& name,
-                  StorageClass storage,
-                  type::Type* type,
-                  Expression* constructor,
-                  VariableDecorationList decorations);
-
-  /// @param source the variable source
-  /// @param name the variable name
-  /// @param storage the variable storage class
-  /// @param type the variable type
-  /// @param constructor optional constructor expression
-  /// @param decorations optional variable decorations
-  /// @returns a constant `Variable` with the given name, storage and type
-  Variable* Const(const Source& source,
-                  const std::string& name,
-                  StorageClass storage,
-                  type::Type* type,
-                  Expression* constructor,
-                  VariableDecorationList decorations);
-
-  /// @param func the function name
-  /// @param args the function call arguments
-  /// @returns a `CallExpression` to the function `func`, with the
-  /// arguments of `args` converted to `Expression`s using `Expr()`.
-  template <typename NAME, typename... ARGS>
-  CallExpression* Call(NAME&& func, ARGS&&... args) {
-    return create<CallExpression>(Expr(func),
-                                  ExprList(std::forward<ARGS>(args)...));
-  }
-
-  /// @param lhs the left hand argument to the addition operation
-  /// @param rhs the right hand argument to the addition operation
-  /// @returns a `BinaryExpression` summing the arguments `lhs` and `rhs`
-  template <typename LHS, typename RHS>
-  Expression* Add(LHS&& lhs, RHS&& rhs) {
-    return create<BinaryExpression>(BinaryOp::kAdd,
-                                    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 `BinaryExpression` subtracting `rhs` from `lhs`
-  template <typename LHS, typename RHS>
-  Expression* Sub(LHS&& lhs, RHS&& rhs) {
-    return create<BinaryExpression>(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 `BinaryExpression` multiplying `rhs` from `lhs`
-  template <typename LHS, typename RHS>
-  Expression* Mul(LHS&& lhs, RHS&& rhs) {
-    return create<BinaryExpression>(BinaryOp::kMultiply,
-                                    Expr(std::forward<LHS>(lhs)),
-                                    Expr(std::forward<RHS>(rhs)));
-  }
-
-  /// @param arr the array argument for the array accessor expression
-  /// @param idx the index argument for the array accessor expression
-  /// @returns a `ArrayAccessorExpression` that indexes `arr` with `idx`
-  template <typename ARR, typename IDX>
-  Expression* IndexAccessor(ARR&& arr, IDX&& idx) {
-    return create<ArrayAccessorExpression>(Expr(std::forward<ARR>(arr)),
-                                           Expr(std::forward<IDX>(idx)));
-  }
-
-  /// @param obj the object for the member accessor expression
-  /// @param idx the index argument for the array accessor expression
-  /// @returns a `MemberAccessorExpression` that indexes `obj` with `idx`
-  template <typename OBJ, typename IDX>
-  Expression* MemberAccessor(OBJ&& obj, IDX&& idx) {
-    return create<MemberAccessorExpression>(Expr(std::forward<OBJ>(obj)),
-                                            Expr(std::forward<IDX>(idx)));
-  }
-
-  /// Creates a StructMemberOffsetDecoration
-  /// @param val the offset value
-  /// @returns the offset decoration pointer
-  StructMemberOffsetDecoration* MemberOffset(uint32_t val) {
-    return program->create<StructMemberOffsetDecoration>(source_, val);
-  }
-
-  /// Creates a Function
-  /// @param source the source information
-  /// @param name the function name
-  /// @param params the function parameters
-  /// @param type the function return type
-  /// @param body the function body
-  /// @param decorations the function decorations
-  /// @returns the function pointer
-  Function* Func(Source source,
-                 std::string name,
-                 ast::VariableList params,
-                 type::Type* type,
-                 ast::StatementList body,
-                 ast::FunctionDecorationList decorations) {
-    return program->create<ast::Function>(
-        source, program->Symbols().Register(name), params, type,
-        create<ast::BlockStatement>(body), decorations);
-  }
-
-  /// Creates a Function
-  /// @param name the function name
-  /// @param params the function parameters
-  /// @param type the function return type
-  /// @param body the function body
-  /// @param decorations the function decorations
-  /// @returns the function pointer
-  Function* Func(std::string name,
-                 ast::VariableList params,
-                 type::Type* type,
-                 ast::StatementList body,
-                 ast::FunctionDecorationList decorations) {
-    return create<ast::Function>(program->Symbols().Register(name), params,
-                                 type, create<ast::BlockStatement>(body),
-                                 decorations);
-  }
-
-  /// Creates a StructMember
-  /// @param source the source information
-  /// @param name the struct member name
-  /// @param type the struct member type
-  /// @returns the struct member pointer
-  StructMember* Member(const Source& source,
-                       const std::string& name,
-                       type::Type* type) {
-    return program->create<StructMember>(source,
-                                         program->Symbols().Register(name),
-                                         type, StructMemberDecorationList{});
-  }
-
-  /// Creates a StructMember
-  /// @param name the struct member name
-  /// @param type the struct member type
-  /// @returns the struct member pointer
-  StructMember* Member(const std::string& name, type::Type* type) {
-    return program->create<StructMember>(source_,
-                                         program->Symbols().Register(name),
-                                         type, StructMemberDecorationList{});
-  }
-
-  /// Creates a StructMember
-  /// @param name the struct member name
-  /// @param type the struct member type
-  /// @param decos the struct member decorations
-  /// @returns the struct member pointer
-  StructMember* Member(const std::string& name,
-                       type::Type* type,
-                       StructMemberDecorationList decos) {
-    return program->create<StructMember>(
-        source_, program->Symbols().Register(name), type, decos);
-  }
-
-  /// Creates a new Node owned by the Module, with the explicit Source.
-  /// When the Module is destructed, the `Node` will also be destructed.
-  /// @param source the source to apply to the Node
-  /// @param args the arguments to pass to the type constructor
-  /// @returns the node pointer
-  template <typename T, typename... ARGS>
-  traits::EnableIfIsType<T, Node>* create(const Source& source,
-                                          ARGS&&... args) {
-    return program->create<T>(source, std::forward<ARGS>(args)...);
-  }
-
-  /// Creates a new Node owned by the Module, with the explicit Source.
-  /// When the Module is destructed, the `Node` will also be destructed.
-  /// @param source the source to apply to the Node
-  /// @param args the arguments to pass to the type constructor
-  /// @returns the node pointer
-  template <typename T, typename... ARGS>
-  traits::EnableIfIsType<T, Node>* create(Source&& source, ARGS&&... args) {
-    return program->create<T>(std::move(source), std::forward<ARGS>(args)...);
-  }
-
-  /// Creates a new type::Type owned by the Module, using the Builder's
-  /// current Source. When the Module is destructed, the `Node` will also be
-  /// destructed.
-  /// @param args the arguments to pass to the type constructor
-  /// @returns the node pointer
-  template <typename T, typename... ARGS>
-  traits::EnableIfIsType<T, Node>* create(ARGS&&... args) {
-    return program->create<T>(source_, std::forward<ARGS>(args)...);
-  }
-
-  /// Creates a new type::Type owned by the Module.
-  /// When the Module is destructed, owned Module and the returned `Type` will
-  /// also be destructed. Types are unique (de-aliased), and so calling create()
-  /// for the same `T` and arguments will return the same pointer.
-  /// @warning Use this method to acquire a type only if all of its type
-  /// information is provided in the constructor arguments `args`.<br>
-  /// If the type requires additional configuration after construction that
-  /// affect its fundamental type, build the type with `std::make_unique`, make
-  /// any necessary alterations and then call unique_type() instead.
-  /// @param args the arguments to pass to the type constructor
-  /// @returns the de-aliased type pointer
-  template <typename T, typename... ARGS>
-  traits::EnableIfIsType<T, type::Type>* create(ARGS&&... args) {
-    static_assert(std::is_base_of<type::Type, T>::value,
-                  "T does not derive from type::Type");
-    return program->create<T>(std::forward<ARGS>(args)...);
-  }
-
-  /// Sets the current builder source to `src`
-  /// @param src the Source used for future create() calls
-  void SetSource(const Source& src) { source_ = src; }
-
-  /// Sets the current builder source to `loc`
-  /// @param loc the Source used for future create() calls
-  void SetSource(const Source::Location& loc) { source_ = Source(loc); }
-
-  /// @returns true if all required fields in the AST are present.
-  bool IsValid() const { return mod->IsValid(); }
-
-  /// @returns a reference to the program's AST root Module
-  ast::Module& AST() { return mod->AST(); }
-
-  /// @returns a reference to the program's SymbolTable
-  SymbolTable& Symbols() { return mod->Symbols(); }
-
-  /// The builder program
-  Program* const program;
-  /// The builder types
-  const TypesBuilder ty;
-
-  /// [DEPRECATED] Temporary alias to #program
-  Program* const mod;
-
- protected:
-  /// Called whenever a new variable is built with `Var()`.
-  virtual void OnVariableBuilt(Variable*) {}
-
-  /// The source to use when creating AST nodes.
-  Source source_;
-};
-
-/// BuilderWithProgram is a `Builder` that constructs and owns its `Program`.
-class BuilderWithProgram : public Builder {
- public:
-  BuilderWithProgram();
-  ~BuilderWithProgram() override;
-};
-
-//! @cond Doxygen_Suppress
-// Various template specializations for TypesBuilder::CToAST.
-template <>
-struct TypesBuilder::CToAST<Builder::i32> {
-  static type::Type* get(const TypesBuilder* t) { return t->i32(); }
-};
-template <>
-struct TypesBuilder::CToAST<Builder::u32> {
-  static type::Type* get(const TypesBuilder* t) { return t->u32(); }
-};
-template <>
-struct TypesBuilder::CToAST<Builder::f32> {
-  static type::Type* get(const TypesBuilder* t) { return t->f32(); }
-};
-template <>
-struct TypesBuilder::CToAST<bool> {
-  static type::Type* get(const TypesBuilder* t) { return t->bool_(); }
-};
-template <>
-struct TypesBuilder::CToAST<void> {
-  static type::Type* get(const TypesBuilder* t) { return t->void_(); }
-};
-//! @endcond
-
-}  // namespace ast
-}  // namespace tint
-
-#endif  // SRC_AST_BUILDER_H_
diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc
index d0db918..1c33150 100644
--- a/src/ast/builtin_decoration.cc
+++ b/src/ast/builtin_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/builtin_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::BuiltinDecoration);
 
diff --git a/src/ast/call_expression.cc b/src/ast/call_expression.cc
index 61e5316..674350a 100644
--- a/src/ast/call_expression.cc
+++ b/src/ast/call_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/call_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::CallExpression);
 
diff --git a/src/ast/call_statement.cc b/src/ast/call_statement.cc
index 82eedc8..66b94e5 100644
--- a/src/ast/call_statement.cc
+++ b/src/ast/call_statement.cc
@@ -16,7 +16,7 @@
 
 #include "src/ast/call_expression.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::CallStatement);
 
diff --git a/src/ast/case_statement.cc b/src/ast/case_statement.cc
index 84e6b21..ac1a267 100644
--- a/src/ast/case_statement.cc
+++ b/src/ast/case_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/case_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::CaseStatement);
 
diff --git a/src/ast/constant_id_decoration.cc b/src/ast/constant_id_decoration.cc
index c2bb255..463e5b3 100644
--- a/src/ast/constant_id_decoration.cc
+++ b/src/ast/constant_id_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/constant_id_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ConstantIdDecoration);
 
diff --git a/src/ast/continue_statement.cc b/src/ast/continue_statement.cc
index 98557bc..58edfba 100644
--- a/src/ast/continue_statement.cc
+++ b/src/ast/continue_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/continue_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ContinueStatement);
 
diff --git a/src/ast/discard_statement.cc b/src/ast/discard_statement.cc
index 1a522cc..3d4ae66 100644
--- a/src/ast/discard_statement.cc
+++ b/src/ast/discard_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/discard_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::DiscardStatement);
 
diff --git a/src/ast/else_statement.cc b/src/ast/else_statement.cc
index 67c52f2..63201a3 100644
--- a/src/ast/else_statement.cc
+++ b/src/ast/else_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/else_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ElseStatement);
 
diff --git a/src/ast/fallthrough_statement.cc b/src/ast/fallthrough_statement.cc
index f18ea60..ede2ca6 100644
--- a/src/ast/fallthrough_statement.cc
+++ b/src/ast/fallthrough_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/fallthrough_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::FallthroughStatement);
 
diff --git a/src/ast/float_literal.cc b/src/ast/float_literal.cc
index 734706f..6e48199 100644
--- a/src/ast/float_literal.cc
+++ b/src/ast/float_literal.cc
@@ -18,7 +18,7 @@
 #include <sstream>
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::FloatLiteral);
 
diff --git a/src/ast/function.cc b/src/ast/function.cc
index 9123896..ceb2d3d 100644
--- a/src/ast/function.cc
+++ b/src/ast/function.cc
@@ -20,7 +20,7 @@
 #include "src/ast/variable.h"
 #include "src/ast/workgroup_decoration.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 #include "src/type/multisampled_texture_type.h"
 #include "src/type/sampled_texture_type.h"
 #include "src/type/texture_type.h"
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index fac3dd1..1181efa 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -36,7 +36,7 @@
 
   auto* f = Func("func", params, ty.void_(), StatementList{},
                  FunctionDecorationList{});
-  EXPECT_EQ(f->symbol(), Symbols().Register("func"));
+  EXPECT_EQ(f->symbol(), Symbols().Get("func"));
   ASSERT_EQ(f->params().size(), 1u);
   EXPECT_EQ(f->return_type(), ty.void_());
   EXPECT_EQ(f->params()[0], var);
@@ -151,7 +151,7 @@
   auto* f = Func("func", VariableList{}, ty.void_(), StatementList{},
                  FunctionDecorationList{});
 
-  auto main_sym = Symbols().Register("main");
+  auto main_sym = Symbols().Get("main");
   f->add_ancestor_entry_point(main_sym);
   ASSERT_EQ(1u, f->ancestor_entry_points().size());
   EXPECT_EQ(main_sym, f->ancestor_entry_points()[0]);
diff --git a/src/ast/group_decoration.cc b/src/ast/group_decoration.cc
index 738882c..019cc36 100644
--- a/src/ast/group_decoration.cc
+++ b/src/ast/group_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/group_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::GroupDecoration);
 
diff --git a/src/ast/identifier_expression.cc b/src/ast/identifier_expression.cc
index e10c664..c6c0779 100644
--- a/src/ast/identifier_expression.cc
+++ b/src/ast/identifier_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/identifier_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::IdentifierExpression);
 
diff --git a/src/ast/if_statement.cc b/src/ast/if_statement.cc
index e7e0609..16a677d 100644
--- a/src/ast/if_statement.cc
+++ b/src/ast/if_statement.cc
@@ -16,7 +16,7 @@
 
 #include "src/ast/else_statement.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::IfStatement);
 
diff --git a/src/ast/intrinsic_texture_helper_test.cc b/src/ast/intrinsic_texture_helper_test.cc
index ac48c3e..56fc77a 100644
--- a/src/ast/intrinsic_texture_helper_test.cc
+++ b/src/ast/intrinsic_texture_helper_test.cc
@@ -14,8 +14,8 @@
 
 #include "src/ast/intrinsic_texture_helper_test.h"
 
-#include "src/ast/builder.h"
 #include "src/ast/type_constructor_expression.h"
+#include "src/program_builder.h"
 #include "src/type/access_control_type.h"
 #include "src/type/depth_texture_type.h"
 #include "src/type/multisampled_texture_type.h"
@@ -27,9 +27,9 @@
 namespace intrinsic {
 namespace test {
 
-using u32 = ast::Builder::u32;
-using i32 = ast::Builder::i32;
-using f32 = ast::Builder::f32;
+using u32 = ProgramBuilder::u32;
+using i32 = ProgramBuilder::i32;
+using f32 = ProgramBuilder::f32;
 
 TextureOverloadCase::TextureOverloadCase(
     ValidTextureOverload o,
@@ -39,7 +39,7 @@
     type::TextureDimension dims,
     TextureDataType datatype,
     const char* f,
-    std::function<ExpressionList(Builder*)> a)
+    std::function<ExpressionList(ProgramBuilder*)> a)
     : overload(o),
       description(desc),
       texture_kind(tk),
@@ -55,7 +55,7 @@
     type::TextureDimension dims,
     TextureDataType datatype,
     const char* f,
-    std::function<ExpressionList(Builder*)> a)
+    std::function<ExpressionList(ProgramBuilder*)> a)
     : overload(o),
       description(desc),
       texture_kind(tk),
@@ -71,7 +71,7 @@
     type::TextureDimension dims,
     TextureDataType datatype,
     const char* f,
-    std::function<ExpressionList(Builder*)> a)
+    std::function<ExpressionList(ProgramBuilder*)> a)
     : overload(o),
       description(d),
       texture_kind(TextureKind::kStorage),
@@ -136,7 +136,7 @@
 }
 
 type::Type* TextureOverloadCase::resultVectorComponentType(
-    ast::Builder* b) const {
+    ProgramBuilder* b) const {
   switch (texture_data_type) {
     case ast::intrinsic::test::TextureDataType::kF32:
       return b->ty.f32();
@@ -151,7 +151,7 @@
 }
 
 ast::Variable* TextureOverloadCase::buildTextureVariable(
-    ast::Builder* b) const {
+    ProgramBuilder* b) const {
   auto* datatype = resultVectorComponentType(b);
 
   VariableDecorationList decos = {
@@ -192,7 +192,7 @@
 }
 
 ast::Variable* TextureOverloadCase::buildSamplerVariable(
-    ast::Builder* b) const {
+    ProgramBuilder* b) const {
   VariableDecorationList decos = {
       b->create<ast::GroupDecoration>(0),
       b->create<ast::BindingDecoration>(1),
@@ -211,7 +211,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensions1dArray,
@@ -221,7 +221,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensions2d,
@@ -231,7 +231,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensions2dLevel,
@@ -242,7 +242,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensions2dArray,
@@ -252,7 +252,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensions2dArrayLevel,
@@ -263,7 +263,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensions3d,
@@ -273,7 +273,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensions3dLevel,
@@ -284,7 +284,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsCube,
@@ -294,7 +294,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsCubeLevel,
@@ -305,7 +305,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsCubeArray,
@@ -315,7 +315,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsCubeArrayLevel,
@@ -326,7 +326,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsMultisampled2d,
@@ -336,7 +336,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsMultisampled2dArray,
@@ -347,7 +347,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsDepth2d,
@@ -357,7 +357,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsDepth2dLevel,
@@ -368,7 +368,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsDepth2dArray,
@@ -378,7 +378,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsDepth2dArrayLevel,
@@ -389,7 +389,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsDepthCube,
@@ -399,7 +399,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsDepthCubeLevel,
@@ -410,7 +410,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsDepthCubeArray,
@@ -420,7 +420,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsDepthCubeArrayLevel,
@@ -431,7 +431,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture", 1); },
+          [](ProgramBuilder* b) { return b->ExprList("texture", 1); },
       },
       {
           ValidTextureOverload::kDimensionsStorageRO1d,
@@ -441,7 +441,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageRO1dArray,
@@ -452,7 +452,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageRO2d,
@@ -463,7 +463,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageRO2dArray,
@@ -474,7 +474,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageRO3d,
@@ -485,7 +485,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageWO1d,
@@ -495,7 +495,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageWO1dArray,
@@ -506,7 +506,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageWO2d,
@@ -517,7 +517,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageWO2dArray,
@@ -528,7 +528,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kDimensionsStorageWO3d,
@@ -539,7 +539,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureDimensions",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayers1dArray,
@@ -549,7 +549,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayers2dArray,
@@ -559,7 +559,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersCubeArray,
@@ -569,7 +569,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersMultisampled2dArray,
@@ -579,7 +579,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersDepth2dArray,
@@ -589,7 +589,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersDepthCubeArray,
@@ -599,7 +599,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersStorageWO1dArray,
@@ -609,7 +609,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLayersStorageWO2dArray,
@@ -619,7 +619,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLayers",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevels2d,
@@ -629,7 +629,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevels2dArray,
@@ -639,7 +639,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevels3d,
@@ -649,7 +649,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsCube,
@@ -659,7 +659,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsCubeArray,
@@ -669,7 +669,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsDepth2d,
@@ -679,7 +679,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsDepth2dArray,
@@ -689,7 +689,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsDepthCube,
@@ -699,7 +699,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumLevelsDepthCubeArray,
@@ -709,7 +709,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureNumLevels",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumSamplesMultisampled2d,
@@ -719,7 +719,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureNumSamples",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kNumSamplesMultisampled2dArray,
@@ -729,7 +729,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureNumSamples",
-          [](Builder* b) { return b->ExprList("texture"); },
+          [](ProgramBuilder* b) { return b->ExprList("texture"); },
       },
       {
           ValidTextureOverload::kSample1dF32,
@@ -741,7 +741,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                "sampler",  // s
                                1.0f);      // coords
@@ -758,7 +758,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                "sampler",  // s
                                1.0f,       // coords
@@ -775,7 +775,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                // t
                                "sampler",                // s
                                b->vec2<f32>(1.f, 2.f));  // coords
@@ -792,7 +792,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -810,7 +810,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -829,7 +829,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -847,7 +847,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                     // t
                                "sampler",                     // s
                                b->vec3<f32>(1.f, 2.f, 3.f));  // coords
@@ -864,7 +864,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -881,7 +881,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                     // t
                                "sampler",                     // s
                                b->vec3<f32>(1.f, 2.f, 3.f));  // coords
@@ -898,7 +898,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -915,7 +915,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                // t
                                "sampler",                // s
                                b->vec2<f32>(1.f, 2.f));  // coords
@@ -932,7 +932,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -950,7 +950,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -969,7 +969,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -987,7 +987,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                     // t
                                "sampler",                     // s
                                b->vec3<f32>(1.f, 2.f, 3.f));  // coords
@@ -1004,7 +1004,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSample",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1022,7 +1022,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1041,7 +1041,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1061,7 +1061,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1082,7 +1082,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1102,7 +1102,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1121,7 +1121,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1140,7 +1140,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1159,7 +1159,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSampleBias",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1178,7 +1178,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1197,7 +1197,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1217,7 +1217,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1238,7 +1238,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1258,7 +1258,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1277,7 +1277,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1296,7 +1296,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1315,7 +1315,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1334,7 +1334,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1353,7 +1353,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1373,7 +1373,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1394,7 +1394,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1414,7 +1414,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1433,7 +1433,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSampleLevel",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1453,7 +1453,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                  // t
                                "sampler",                  // s
                                b->vec2<f32>(1.0f, 2.0f),   // coords
@@ -1474,7 +1474,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1496,7 +1496,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                // t
                                "sampler",                // s
                                b->vec2<f32>(1.f, 2.f),   // coords
@@ -1519,7 +1519,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1541,7 +1541,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                     // t
                                "sampler",                     // s
                                b->vec3<f32>(1.f, 2.f, 3.f),   // coords
@@ -1562,7 +1562,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1583,7 +1583,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                     // t
                                "sampler",                     // s
                                b->vec3<f32>(1.f, 2.f, 3.f),   // coords
@@ -1604,7 +1604,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSampleGrad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                      // t
                                "sampler",                      // s
                                b->vec3<f32>(1.f, 2.f, 3.f),    // coords
@@ -1624,7 +1624,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1643,7 +1643,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1663,7 +1663,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1684,7 +1684,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                "sampler",               // s
                                b->vec2<f32>(1.f, 2.f),  // coords
@@ -1704,7 +1704,7 @@
           type::TextureDimension::kCube,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1723,7 +1723,7 @@
           type::TextureDimension::kCubeArray,
           TextureDataType::kF32,
           "textureSampleCompare",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                    // t
                                "sampler",                    // s
                                b->vec3<f32>(1.f, 2.f, 3.f),  // coords
@@ -1739,7 +1739,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1);         // coords
           },
@@ -1752,7 +1752,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1);         // coords
           },
@@ -1765,7 +1765,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1);         // coords
           },
@@ -1779,7 +1779,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1,          // coords
                                2);         // array_index
@@ -1794,7 +1794,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1,          // coords
                                2);         // array_index
@@ -1809,7 +1809,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1,          // coords
                                2);         // array_index
@@ -1823,7 +1823,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // coords
           },
@@ -1836,7 +1836,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // coords
           },
@@ -1849,7 +1849,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // coords
           },
@@ -1863,7 +1863,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // level
@@ -1878,7 +1878,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // level
@@ -1893,7 +1893,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // level
@@ -1908,7 +1908,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // array_index
@@ -1923,7 +1923,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // array_index
@@ -1938,7 +1938,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // array_index
@@ -1954,7 +1954,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -1971,7 +1971,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -1988,7 +1988,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2003,7 +2003,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                b->vec3<i32>(1, 2, 3));  // coords
           },
@@ -2016,7 +2016,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                b->vec3<i32>(1, 2, 3));  // coords
           },
@@ -2029,7 +2029,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                b->vec3<i32>(1, 2, 3));  // coords
           },
@@ -2043,7 +2043,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",              // t
                                b->vec3<i32>(1, 2, 3),  // coords
                                4);                     // level
@@ -2058,7 +2058,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",              // t
                                b->vec3<i32>(1, 2, 3),  // coords
                                4);                     // level
@@ -2073,7 +2073,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",              // t
                                b->vec3<i32>(1, 2, 3),  // coords
                                4);                     // level
@@ -2088,7 +2088,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // sample_index
@@ -2103,7 +2103,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // sample_index
@@ -2118,7 +2118,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // sample_index
@@ -2134,7 +2134,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2151,7 +2151,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2168,7 +2168,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2183,7 +2183,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // coords
           },
@@ -2197,7 +2197,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // level
@@ -2212,7 +2212,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // array_index
@@ -2228,7 +2228,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2244,7 +2244,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1);         // coords
           },
@@ -2260,7 +2260,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1,          // coords
                                2);         // array_index
@@ -2275,7 +2275,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2289,7 +2289,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2303,7 +2303,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2317,7 +2317,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2331,7 +2331,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2345,7 +2345,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2359,7 +2359,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2373,7 +2373,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2387,7 +2387,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2401,7 +2401,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2415,7 +2415,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2429,7 +2429,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2443,7 +2443,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2457,7 +2457,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kU32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2471,7 +2471,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kI32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2485,7 +2485,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",            // t
                                b->vec2<i32>(1, 2));  // array_index
           },
@@ -2501,7 +2501,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3);                  // array_index
@@ -2516,7 +2516,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureLoad",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",               // t
                                b->vec3<i32>(1, 2, 3));  // coords
           },
@@ -2531,7 +2531,7 @@
           type::TextureDimension::k1d,
           TextureDataType::kF32,
           "textureStore",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                          // t
                                1,                                  // coords
                                b->vec4<f32>(2.f, 3.f, 4.f, 5.f));  // value
@@ -2548,7 +2548,7 @@
           type::TextureDimension::k1dArray,
           TextureDataType::kF32,
           "textureStore",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",  // t
                                1,          // coords
                                2,          // array_index
@@ -2565,7 +2565,7 @@
           type::TextureDimension::k2d,
           TextureDataType::kF32,
           "textureStore",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                          // t
                                b->vec2<i32>(1, 2),                 // coords
                                b->vec4<f32>(3.f, 4.f, 5.f, 6.f));  // value
@@ -2582,7 +2582,7 @@
           type::TextureDimension::k2dArray,
           TextureDataType::kF32,
           "textureStore",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",           // t
                                b->vec2<i32>(1, 2),  // coords
                                3,                   // array_index
@@ -2599,7 +2599,7 @@
           type::TextureDimension::k3d,
           TextureDataType::kF32,
           "textureStore",
-          [](Builder* b) {
+          [](ProgramBuilder* b) {
             return b->ExprList("texture",                          // t
                                b->vec3<i32>(1, 2, 3),              // coords
                                b->vec4<f32>(4.f, 5.f, 6.f, 7.f));  // value
diff --git a/src/ast/intrinsic_texture_helper_test.h b/src/ast/intrinsic_texture_helper_test.h
index f8a4b53..c405c16 100644
--- a/src/ast/intrinsic_texture_helper_test.h
+++ b/src/ast/intrinsic_texture_helper_test.h
@@ -19,7 +19,7 @@
 #include <vector>
 
 #include "src/ast/access_control.h"
-#include "src/ast/builder.h"
+#include "src/program_builder.h"
 #include "src/type/sampler_type.h"
 #include "src/type/storage_texture_type.h"
 #include "src/type/texture_type.h"
@@ -211,7 +211,7 @@
                       type::TextureDimension,
                       TextureDataType,
                       const char*,
-                      std::function<ExpressionList(Builder*)>);
+                      std::function<ExpressionList(ProgramBuilder*)>);
   /// Constructor for textureLoad() functions with non-storage textures
   TextureOverloadCase(ValidTextureOverload,
                       const char*,
@@ -219,7 +219,7 @@
                       type::TextureDimension,
                       TextureDataType,
                       const char*,
-                      std::function<ExpressionList(Builder*)>);
+                      std::function<ExpressionList(ProgramBuilder*)>);
   /// Constructor for textureLoad() with storage textures
   TextureOverloadCase(ValidTextureOverload,
                       const char*,
@@ -228,7 +228,7 @@
                       type::TextureDimension,
                       TextureDataType,
                       const char*,
-                      std::function<ExpressionList(Builder*)>);
+                      std::function<ExpressionList(ProgramBuilder*)>);
   /// Copy constructor
   TextureOverloadCase(const TextureOverloadCase&);
   /// Destructor
@@ -240,13 +240,13 @@
 
   /// @param builder the AST builder used for the test
   /// @returns the vector component type of the texture function return value
-  type::Type* resultVectorComponentType(ast::Builder* builder) const;
+  type::Type* resultVectorComponentType(ProgramBuilder* builder) const;
   /// @param builder the AST builder used for the test
   /// @returns a Variable holding the test texture
-  ast::Variable* buildTextureVariable(ast::Builder* builder) const;
+  ast::Variable* buildTextureVariable(ProgramBuilder* builder) const;
   /// @param builder the AST builder used for the test
   /// @returns a Variable holding the test sampler
-  ast::Variable* buildSamplerVariable(ast::Builder* builder) const;
+  ast::Variable* buildSamplerVariable(ProgramBuilder* builder) const;
 
   /// The enumerator for this overload
   ValidTextureOverload const overload;
@@ -270,7 +270,7 @@
   /// Name of the function. e.g. `textureSample`, `textureSampleGrad`, etc
   const char* const function;
   /// A function that builds the AST arguments for the overload
-  std::function<ExpressionList(Builder*)> const args;
+  std::function<ExpressionList(ProgramBuilder*)> const args;
 };
 
 std::ostream& operator<<(std::ostream& out, const TextureOverloadCase& data);
diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc
index 7b23c2a..1eff8a6 100644
--- a/src/ast/location_decoration.cc
+++ b/src/ast/location_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/location_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::LocationDecoration);
 
diff --git a/src/ast/loop_statement.cc b/src/ast/loop_statement.cc
index cee9f23..68730c4 100644
--- a/src/ast/loop_statement.cc
+++ b/src/ast/loop_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/loop_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::LoopStatement);
 
diff --git a/src/ast/member_accessor_expression.cc b/src/ast/member_accessor_expression.cc
index d25c6e8..20e6ee6 100644
--- a/src/ast/member_accessor_expression.cc
+++ b/src/ast/member_accessor_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/member_accessor_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::MemberAccessorExpression);
 
diff --git a/src/ast/module.cc b/src/ast/module.cc
index e39e048..9d99c17 100644
--- a/src/ast/module.cc
+++ b/src/ast/module.cc
@@ -18,8 +18,7 @@
 #include <string>
 #include <utility>
 
-#include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 #include "src/type/alias_type.h"
 #include "src/type/struct_type.h"
 
@@ -28,12 +27,13 @@
 namespace tint {
 namespace ast {
 
-Module::Module() : Base(Source{}) {}
+Module::Module(const Source& source) : Base(source) {}
 
-Module::Module(std::vector<type::Type*> constructed_types,
+Module::Module(const Source& source,
+               std::vector<type::Type*> constructed_types,
                FunctionList functions,
                VariableList global_variables)
-    : Base(Source{}),
+    : Base(source),
       constructed_types_(std::move(constructed_types)),
       functions_(std::move(functions)),
       global_variables_(std::move(global_variables)) {}
diff --git a/src/ast/module.h b/src/ast/module.h
index 7227131..bbc3c0b 100644
--- a/src/ast/module.h
+++ b/src/ast/module.h
@@ -31,13 +31,16 @@
 class Module : public Castable<Module, Node> {
  public:
   /// Constructor
-  Module();
+  /// @param source the source of the module
+  explicit Module(const Source& source);
 
   /// Constructor
+  /// @param source the source of the module
   /// @param constructed_types the list of types explicitly declared in the AST
   /// @param functions the list of program functions
   /// @param global_variables the list of global variables
-  Module(std::vector<type::Type*> constructed_types,
+  Module(const Source& source,
+         std::vector<type::Type*> constructed_types,
          FunctionList functions,
          VariableList global_variables);
 
diff --git a/src/ast/module_clone_test.cc b/src/ast/module_clone_test.cc
index 995b1e5..a3bc10f 100644
--- a/src/ast/module_clone_test.cc
+++ b/src/ast/module_clone_test.cc
@@ -16,7 +16,10 @@
 
 #include "gtest/gtest.h"
 #include "src/ast/case_statement.h"
+#include "src/ast/module.h"
 #include "src/demangler.h"
+#include "src/program.h"
+#include "src/program_builder.h"
 #include "src/reader/wgsl/parser.h"
 #include "src/writer/wgsl/generator.h"
 
@@ -114,12 +117,12 @@
   auto src = parser.program();
 
   // Clone the src program to dst
-  auto dst = src.Clone();
+  Program dst(src.Clone());
 
   // Expect the AST printed with to_str() to match
   Demangler demanger;
-  EXPECT_EQ(demanger.Demangle(src.Symbols(), src.to_str()),
-            demanger.Demangle(dst.Symbols(), dst.to_str()));
+  EXPECT_EQ(demanger.Demangle(src.Symbols(), src.AST().to_str()),
+            demanger.Demangle(dst.Symbols(), dst.AST().to_str()));
 
   // Check that none of the AST nodes or type pointers in dst are found in src
   std::unordered_set<ast::Node*> src_nodes;
@@ -142,8 +145,8 @@
   // comparison.
   std::string src_wgsl;
   {
-    tint::writer::wgsl::Generator src_gen(&src);
-    ASSERT_TRUE(src_gen.Generate());
+    writer::wgsl::Generator src_gen(&src);
+    ASSERT_TRUE(src_gen.Generate()) << src_gen.error();
     src_wgsl = src_gen.result();
 
     // Move the src program to a temporary that'll be dropped, so that the src
@@ -154,8 +157,8 @@
     auto tmp = std::move(src);
   }
 
-  // Print the dst program, check it matches the original source
-  tint::writer::wgsl::Generator dst_gen(&dst);
+  // Print the dst module, check it matches the original source
+  writer::wgsl::Generator dst_gen(&dst);
   ASSERT_TRUE(dst_gen.Generate());
   auto dst_wgsl = dst_gen.result();
   ASSERT_EQ(src_wgsl, dst_wgsl);
diff --git a/src/ast/module_test.cc b/src/ast/module_test.cc
new file mode 100644
index 0000000..f987023
--- /dev/null
+++ b/src/ast/module_test.cc
@@ -0,0 +1,139 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/ast/module.h"
+
+#include <sstream>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "src/ast/function.h"
+#include "src/ast/test_helper.h"
+#include "src/ast/variable.h"
+#include "src/type/alias_type.h"
+#include "src/type/f32_type.h"
+#include "src/type/struct_type.h"
+
+namespace tint {
+namespace ast {
+namespace {
+
+using ModuleTest = TestHelper;
+
+TEST_F(ModuleTest, Creation) {
+  EXPECT_EQ(Program(std::move(*this)).AST().Functions().size(), 0u);
+}
+
+TEST_F(ModuleTest, ToStrEmitsPreambleAndPostamble) {
+  const auto str = Program(std::move(*this)).AST().to_str();
+  auto* const expected = "Module{\n}\n";
+  EXPECT_EQ(str, expected);
+}
+
+TEST_F(ModuleTest, LookupFunction) {
+  auto* func = Func("main", VariableList{}, ty.f32(), StatementList{},
+                    ast::FunctionDecorationList{});
+  AST().Functions().Add(func);
+  Program program(std::move(*this));
+  EXPECT_EQ(func,
+            program.AST().Functions().Find(program.Symbols().Get("main")));
+}
+
+TEST_F(ModuleTest, LookupFunctionMissing) {
+  Program program(std::move(*this));
+  EXPECT_EQ(nullptr,
+            program.AST().Functions().Find(program.Symbols().Get("Missing")));
+}
+
+TEST_F(ModuleTest, IsValid_Empty) {
+  Program program(std::move(*this));
+  EXPECT_TRUE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_GlobalVariable) {
+  auto* var = Var("var", StorageClass::kInput, ty.f32());
+  AST().AddGlobalVariable(var);
+  Program program(std::move(*this));
+  EXPECT_TRUE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Null_GlobalVariable) {
+  AST().AddGlobalVariable(nullptr);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Invalid_GlobalVariable) {
+  auto* var = Var("var", StorageClass::kInput, nullptr);
+  AST().AddGlobalVariable(var);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Alias) {
+  auto* alias = ty.alias("alias", ty.f32());
+  AST().AddConstructedType(alias);
+  Program program(std::move(*this));
+  EXPECT_TRUE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Null_Alias) {
+  AST().AddConstructedType(nullptr);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Struct) {
+  auto* st = ty.struct_("name", {});
+  auto* alias = ty.alias("name", st);
+  AST().AddConstructedType(alias);
+  Program program(std::move(*this));
+  EXPECT_TRUE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Struct_EmptyName) {
+  auto* st = ty.struct_("", {});
+  auto* alias = ty.alias("name", st);
+  AST().AddConstructedType(alias);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Function) {
+  auto* func = Func("main", VariableList(), ty.f32(), StatementList{},
+                    ast::FunctionDecorationList{});
+
+  AST().Functions().Add(func);
+  Program program(std::move(*this));
+  EXPECT_TRUE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Null_Function) {
+  AST().Functions().Add(nullptr);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+TEST_F(ModuleTest, IsValid_Invalid_Function) {
+  auto* func = Func("main", VariableList{}, nullptr, StatementList{},
+                    ast::FunctionDecorationList{});
+
+  AST().Functions().Add(func);
+  Program program(std::move(*this));
+  EXPECT_FALSE(program.AST().IsValid());
+}
+
+}  // namespace
+}  // namespace ast
+}  // namespace tint
diff --git a/src/ast/null_literal.cc b/src/ast/null_literal.cc
index 7a52a7f..edcf896 100644
--- a/src/ast/null_literal.cc
+++ b/src/ast/null_literal.cc
@@ -15,7 +15,7 @@
 #include "src/ast/null_literal.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::NullLiteral);
 
diff --git a/src/ast/return_statement.cc b/src/ast/return_statement.cc
index 8602460..38133c2 100644
--- a/src/ast/return_statement.cc
+++ b/src/ast/return_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/return_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ReturnStatement);
 
diff --git a/src/ast/scalar_constructor_expression.cc b/src/ast/scalar_constructor_expression.cc
index dfa4ae3..ebbecc6 100644
--- a/src/ast/scalar_constructor_expression.cc
+++ b/src/ast/scalar_constructor_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/scalar_constructor_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::ScalarConstructorExpression);
 
diff --git a/src/ast/sint_literal.cc b/src/ast/sint_literal.cc
index 4957286..bc78d50 100644
--- a/src/ast/sint_literal.cc
+++ b/src/ast/sint_literal.cc
@@ -15,7 +15,7 @@
 #include "src/ast/sint_literal.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::SintLiteral);
 
diff --git a/src/ast/stage_decoration.cc b/src/ast/stage_decoration.cc
index e359ac4..53cb362 100644
--- a/src/ast/stage_decoration.cc
+++ b/src/ast/stage_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/stage_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::StageDecoration);
 
diff --git a/src/ast/stride_decoration.cc b/src/ast/stride_decoration.cc
index 1473d02..0dd1990 100644
--- a/src/ast/stride_decoration.cc
+++ b/src/ast/stride_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/stride_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::StrideDecoration);
 
diff --git a/src/ast/struct.cc b/src/ast/struct.cc
index 92e01f7..cf696c5 100644
--- a/src/ast/struct.cc
+++ b/src/ast/struct.cc
@@ -16,7 +16,7 @@
 
 #include "src/ast/struct_block_decoration.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::Struct);
 
diff --git a/src/ast/struct_block_decoration.cc b/src/ast/struct_block_decoration.cc
index 55af859..2e1cf92 100644
--- a/src/ast/struct_block_decoration.cc
+++ b/src/ast/struct_block_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/struct_block_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::StructBlockDecoration);
 
diff --git a/src/ast/struct_member.cc b/src/ast/struct_member.cc
index 4ecd79d..0cc7a71 100644
--- a/src/ast/struct_member.cc
+++ b/src/ast/struct_member.cc
@@ -16,7 +16,7 @@
 
 #include "src/ast/struct_member_offset_decoration.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::StructMember);
 
diff --git a/src/ast/struct_member_offset_decoration.cc b/src/ast/struct_member_offset_decoration.cc
index 71fbfc9..09ebef6 100644
--- a/src/ast/struct_member_offset_decoration.cc
+++ b/src/ast/struct_member_offset_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/struct_member_offset_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::StructMemberOffsetDecoration);
 
diff --git a/src/ast/switch_statement.cc b/src/ast/switch_statement.cc
index 3e536cd..4bc34b3 100644
--- a/src/ast/switch_statement.cc
+++ b/src/ast/switch_statement.cc
@@ -16,7 +16,7 @@
 
 #include "src/ast/case_statement.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::SwitchStatement);
 
diff --git a/src/ast/test_helper.h b/src/ast/test_helper.h
index 8ae08f5..5621a32 100644
--- a/src/ast/test_helper.h
+++ b/src/ast/test_helper.h
@@ -20,16 +20,15 @@
 #include <utility>
 
 #include "gtest/gtest.h"
-#include "src/ast/builder.h"
 #include "src/demangler.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 namespace tint {
 namespace ast {
 
 /// Helper class for testing
 template <typename BASE>
-class TestHelperBase : public BASE, public BuilderWithProgram {
+class TestHelperBase : public BASE, public ProgramBuilder {
  public:
   /// Demangles the given string
   /// @param s the string to demangle
diff --git a/src/ast/type_constructor_expression.cc b/src/ast/type_constructor_expression.cc
index b5807b4..2afde7b 100644
--- a/src/ast/type_constructor_expression.cc
+++ b/src/ast/type_constructor_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/type_constructor_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::TypeConstructorExpression);
 
diff --git a/src/ast/uint_literal.cc b/src/ast/uint_literal.cc
index 00d414b..076b896 100644
--- a/src/ast/uint_literal.cc
+++ b/src/ast/uint_literal.cc
@@ -15,7 +15,7 @@
 #include "src/ast/uint_literal.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::UintLiteral);
 
diff --git a/src/ast/unary_op_expression.cc b/src/ast/unary_op_expression.cc
index 21c6a05..890e1ed 100644
--- a/src/ast/unary_op_expression.cc
+++ b/src/ast/unary_op_expression.cc
@@ -15,7 +15,7 @@
 #include "src/ast/unary_op_expression.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::UnaryOpExpression);
 
diff --git a/src/ast/variable.cc b/src/ast/variable.cc
index 0e4c336..52e869b 100644
--- a/src/ast/variable.cc
+++ b/src/ast/variable.cc
@@ -18,7 +18,7 @@
 
 #include "src/ast/constant_id_decoration.h"
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::Variable);
 
diff --git a/src/ast/variable_decl_statement.cc b/src/ast/variable_decl_statement.cc
index 91a56d1..8bdddcb 100644
--- a/src/ast/variable_decl_statement.cc
+++ b/src/ast/variable_decl_statement.cc
@@ -15,7 +15,7 @@
 #include "src/ast/variable_decl_statement.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::VariableDeclStatement);
 
diff --git a/src/ast/workgroup_decoration.cc b/src/ast/workgroup_decoration.cc
index 57ea5e4..914278a 100644
--- a/src/ast/workgroup_decoration.cc
+++ b/src/ast/workgroup_decoration.cc
@@ -15,7 +15,7 @@
 #include "src/ast/workgroup_decoration.h"
 
 #include "src/clone_context.h"
-#include "src/program.h"
+#include "src/program_builder.h"
 
 TINT_INSTANTIATE_CLASS_ID(tint::ast::WorkgroupDecoration);