[shuffle] Move program_id to new structure.

This CL moves the `program_id` to `utils/generation_id`. The program id
was renamed as it's also used by symbol which lives at a different
layering to the AST program.

Bug: tint:1988
Change-Id: I50146ac25e89e269276f9f7030ada989c98db66e
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/142861
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/core/ir/module.h b/src/tint/lang/core/ir/module.h
index 204e4ed..9f4a197 100644
--- a/src/tint/lang/core/ir/module.h
+++ b/src/tint/lang/core/ir/module.h
@@ -25,8 +25,8 @@
 #include "src/tint/lang/core/ir/instruction.h"
 #include "src/tint/lang/core/ir/value.h"
 #include "src/tint/lang/core/type/manager.h"
-#include "src/tint/program_id.h"
 #include "src/tint/utils/containers/vector.h"
+#include "src/tint/utils/generation_id.h"
 #include "src/tint/utils/memory/block_allocator.h"
 #include "src/tint/utils/result/result.h"
 #include "src/tint/utils/text/symbol_table.h"
@@ -36,7 +36,7 @@
 /// Main module class for the IR.
 class Module {
     /// Program Id required to create other components
-    ProgramID prog_id_;
+    GenerationID prog_id_;
 
     /// Map of value to name
     utils::Hashmap<Value*, Symbol, 32> value_to_name_;
diff --git a/src/tint/lang/core/type/builtin_structs_test.cc b/src/tint/lang/core/type/builtin_structs_test.cc
index 3c2ca71..589e5df 100644
--- a/src/tint/lang/core/type/builtin_structs_test.cc
+++ b/src/tint/lang/core/type/builtin_structs_test.cc
@@ -24,7 +24,7 @@
 #include "src/tint/lang/core/type/manager.h"
 #include "src/tint/lang/core/type/u32.h"
 #include "src/tint/lang/core/type/vector.h"
-#include "src/tint/program_id.h"
+#include "src/tint/utils/generation_id.h"
 #include "src/tint/utils/text/symbol_table.h"
 
 using namespace tint::number_suffixes;  // NOLINT
@@ -44,7 +44,7 @@
 template <typename T>
 class BuiltinStructsTest : public testing::TestWithParam<T> {
   protected:
-    BuiltinStructsTest() : symbols(ProgramID::New()) {}
+    BuiltinStructsTest() : symbols(GenerationID::New()) {}
 
     const Type* Make(ElementType t) {
         switch (t) {
diff --git a/src/tint/lang/core/type/struct_test.cc b/src/tint/lang/core/type/struct_test.cc
index d31e6a7..82cbc4a 100644
--- a/src/tint/lang/core/type/struct_test.cc
+++ b/src/tint/lang/core/type/struct_test.cc
@@ -216,7 +216,7 @@
                                            type::StructMemberAttributes{})},
         4u /* align */, 8u /* size */, 16u /* size_no_padding */);
 
-    ProgramID id;
+    GenerationID id;
     SymbolTable new_st{id};
 
     type::Manager mgr;
diff --git a/src/tint/lang/glsl/ast_writer/generator_impl.cc b/src/tint/lang/glsl/ast_writer/generator_impl.cc
index 1a5e3da..223fdb2 100644
--- a/src/tint/lang/glsl/ast_writer/generator_impl.cc
+++ b/src/tint/lang/glsl/ast_writer/generator_impl.cc
@@ -2199,7 +2199,7 @@
         EmitStatements(func->body->statements);
 
         if (!Is<ast::ReturnStatement>(func->body->Last())) {
-            ast::ReturnStatement ret(ProgramID{}, ast::NodeID{}, Source{});
+            ast::ReturnStatement ret(GenerationID{}, ast::NodeID{}, Source{});
             EmitStatement(&ret);
         }
     }
diff --git a/src/tint/lang/hlsl/ast_writer/generator_impl.cc b/src/tint/lang/hlsl/ast_writer/generator_impl.cc
index 53dd98d..a0ce5f3 100644
--- a/src/tint/lang/hlsl/ast_writer/generator_impl.cc
+++ b/src/tint/lang/hlsl/ast_writer/generator_impl.cc
@@ -3509,7 +3509,7 @@
         }
 
         if (!Is<ast::ReturnStatement>(func->body->Last())) {
-            ast::ReturnStatement ret(ProgramID(), ast::NodeID{}, Source{});
+            ast::ReturnStatement ret(GenerationID(), ast::NodeID{}, Source{});
             if (!EmitStatement(&ret)) {
                 return false;
             }
diff --git a/src/tint/lang/msl/ast_writer/generator_impl.cc b/src/tint/lang/msl/ast_writer/generator_impl.cc
index f476470..856a7eb 100644
--- a/src/tint/lang/msl/ast_writer/generator_impl.cc
+++ b/src/tint/lang/msl/ast_writer/generator_impl.cc
@@ -2009,7 +2009,7 @@
         }
 
         if (!Is<ast::ReturnStatement>(func->body->Last())) {
-            ast::ReturnStatement ret(ProgramID{}, ast::NodeID{}, Source{});
+            ast::ReturnStatement ret(GenerationID{}, ast::NodeID{}, Source{});
             if (!EmitStatement(&ret)) {
                 return false;
             }
diff --git a/src/tint/lang/spirv/reader/function.h b/src/tint/lang/spirv/reader/function.h
index 4bf0377..914ae5d 100644
--- a/src/tint/lang/spirv/reader/function.h
+++ b/src/tint/lang/spirv/reader/function.h
@@ -410,7 +410,7 @@
 class StatementBuilder : public utils::Castable<StatementBuilder, ast::Statement> {
   public:
     /// Constructor
-    StatementBuilder() : Base(ProgramID(), ast::NodeID(), Source{}) {}
+    StatementBuilder() : Base(GenerationID(), ast::NodeID(), Source{}) {}
 
     /// @param builder the program builder
     /// @returns the build AST node
diff --git a/src/tint/lang/wgsl/ast/accessor_expression.cc b/src/tint/lang/wgsl/ast/accessor_expression.cc
index 16cc58f..377466f 100644
--- a/src/tint/lang/wgsl/ast/accessor_expression.cc
+++ b/src/tint/lang/wgsl/ast/accessor_expression.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-AccessorExpression::AccessorExpression(ProgramID pid,
+AccessorExpression::AccessorExpression(GenerationID pid,
                                        NodeID nid,
                                        const Source& src,
                                        const Expression* obj)
     : Base(pid, nid, src), object(obj) {
     TINT_ASSERT(AST, object);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, object, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, object, generation_id);
 }
 
 AccessorExpression::~AccessorExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/accessor_expression.h b/src/tint/lang/wgsl/ast/accessor_expression.h
index 2551b5e..92f5cb10 100644
--- a/src/tint/lang/wgsl/ast/accessor_expression.h
+++ b/src/tint/lang/wgsl/ast/accessor_expression.h
@@ -27,7 +27,10 @@
     /// @param nid the unique node identifier
     /// @param source the member accessor expression source
     /// @param object the object
-    AccessorExpression(ProgramID pid, NodeID nid, const Source& source, const Expression* object);
+    AccessorExpression(GenerationID pid,
+                       NodeID nid,
+                       const Source& source,
+                       const Expression* object);
 
     /// Destructor
     ~AccessorExpression() override;
diff --git a/src/tint/lang/wgsl/ast/alias.cc b/src/tint/lang/wgsl/ast/alias.cc
index a1a9334..dfb563d 100644
--- a/src/tint/lang/wgsl/ast/alias.cc
+++ b/src/tint/lang/wgsl/ast/alias.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-Alias::Alias(ProgramID pid, NodeID nid, const Source& src, const Identifier* n, Type subtype)
+Alias::Alias(GenerationID pid, NodeID nid, const Source& src, const Identifier* n, Type subtype)
     : Base(pid, nid, src, n), type(subtype) {
     TINT_ASSERT(AST, type);
 }
diff --git a/src/tint/lang/wgsl/ast/alias.h b/src/tint/lang/wgsl/ast/alias.h
index 553f9c9..66db7c9 100644
--- a/src/tint/lang/wgsl/ast/alias.h
+++ b/src/tint/lang/wgsl/ast/alias.h
@@ -31,7 +31,7 @@
     /// @param src the source of this node
     /// @param name the symbol for the alias
     /// @param subtype the alias'd type
-    Alias(ProgramID pid, NodeID nid, const Source& src, const Identifier* name, Type subtype);
+    Alias(GenerationID pid, NodeID nid, const Source& src, const Identifier* name, Type subtype);
 
     /// Destructor
     ~Alias() override;
diff --git a/src/tint/lang/wgsl/ast/assignment_statement.cc b/src/tint/lang/wgsl/ast/assignment_statement.cc
index e49861d..173bbca 100644
--- a/src/tint/lang/wgsl/ast/assignment_statement.cc
+++ b/src/tint/lang/wgsl/ast/assignment_statement.cc
@@ -20,16 +20,16 @@
 
 namespace tint::ast {
 
-AssignmentStatement::AssignmentStatement(ProgramID pid,
+AssignmentStatement::AssignmentStatement(GenerationID pid,
                                          NodeID nid,
                                          const Source& src,
                                          const Expression* l,
                                          const Expression* r)
     : Base(pid, nid, src), lhs(l), rhs(r) {
     TINT_ASSERT(AST, lhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, lhs, generation_id);
     TINT_ASSERT(AST, rhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, rhs, generation_id);
 }
 
 AssignmentStatement::~AssignmentStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/assignment_statement.h b/src/tint/lang/wgsl/ast/assignment_statement.h
index a635987..e984d83 100644
--- a/src/tint/lang/wgsl/ast/assignment_statement.h
+++ b/src/tint/lang/wgsl/ast/assignment_statement.h
@@ -29,7 +29,7 @@
     /// @param source the assignment statement source
     /// @param lhs the left side of the expression
     /// @param rhs the right side of the expression
-    AssignmentStatement(ProgramID pid,
+    AssignmentStatement(GenerationID pid,
                         NodeID nid,
                         const Source& source,
                         const Expression* lhs,
diff --git a/src/tint/lang/wgsl/ast/assignment_statement_test.cc b/src/tint/lang/wgsl/ast/assignment_statement_test.cc
index 9785a72..a839517 100644
--- a/src/tint/lang/wgsl/ast/assignment_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/assignment_statement_test.cc
@@ -69,7 +69,7 @@
         "internal compiler error");
 }
 
-TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_LHS) {
+TEST_F(AssignmentStatementTest, Assert_DifferentGenerationID_LHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -79,7 +79,7 @@
         "internal compiler error");
 }
 
-TEST_F(AssignmentStatementTest, Assert_DifferentProgramID_RHS) {
+TEST_F(AssignmentStatementTest, Assert_DifferentGenerationID_RHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/attribute.h b/src/tint/lang/wgsl/ast/attribute.h
index 6356bb4..a3d1599 100644
--- a/src/tint/lang/wgsl/ast/attribute.h
+++ b/src/tint/lang/wgsl/ast/attribute.h
@@ -35,7 +35,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    Attribute(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
+    Attribute(GenerationID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
 };
 
 /// @param attributes the list of attributes to search
diff --git a/src/tint/lang/wgsl/ast/binary_expression.cc b/src/tint/lang/wgsl/ast/binary_expression.cc
index 43c15ee..dd1fdb4 100644
--- a/src/tint/lang/wgsl/ast/binary_expression.cc
+++ b/src/tint/lang/wgsl/ast/binary_expression.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-BinaryExpression::BinaryExpression(ProgramID pid,
+BinaryExpression::BinaryExpression(GenerationID pid,
                                    NodeID nid,
                                    const Source& src,
                                    BinaryOp o,
@@ -28,9 +28,9 @@
                                    const Expression* r)
     : Base(pid, nid, src), op(o), lhs(l), rhs(r) {
     TINT_ASSERT(AST, lhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, lhs, generation_id);
     TINT_ASSERT(AST, rhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, rhs, generation_id);
     TINT_ASSERT(AST, op != BinaryOp::kNone);
 }
 
diff --git a/src/tint/lang/wgsl/ast/binary_expression.h b/src/tint/lang/wgsl/ast/binary_expression.h
index 12aa167..2a96e3d 100644
--- a/src/tint/lang/wgsl/ast/binary_expression.h
+++ b/src/tint/lang/wgsl/ast/binary_expression.h
@@ -52,7 +52,7 @@
     /// @param op the operation type
     /// @param lhs the left side of the expression
     /// @param rhs the right side of the expression
-    BinaryExpression(ProgramID pid,
+    BinaryExpression(GenerationID pid,
                      NodeID nid,
                      const Source& source,
                      BinaryOp op,
diff --git a/src/tint/lang/wgsl/ast/binary_expression_test.cc b/src/tint/lang/wgsl/ast/binary_expression_test.cc
index 6385ae1..fc645f8 100644
--- a/src/tint/lang/wgsl/ast/binary_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/binary_expression_test.cc
@@ -66,7 +66,7 @@
         "internal compiler error");
 }
 
-TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_LHS) {
+TEST_F(BinaryExpressionTest, Assert_DifferentGenerationID_LHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -76,7 +76,7 @@
         "internal compiler error");
 }
 
-TEST_F(BinaryExpressionTest, Assert_DifferentProgramID_RHS) {
+TEST_F(BinaryExpressionTest, Assert_DifferentGenerationID_RHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/binding_attribute.cc b/src/tint/lang/wgsl/ast/binding_attribute.cc
index fe9929d..662672e 100644
--- a/src/tint/lang/wgsl/ast/binding_attribute.cc
+++ b/src/tint/lang/wgsl/ast/binding_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-BindingAttribute::BindingAttribute(ProgramID pid,
+BindingAttribute::BindingAttribute(GenerationID pid,
                                    NodeID nid,
                                    const Source& src,
                                    const Expression* exp)
diff --git a/src/tint/lang/wgsl/ast/binding_attribute.h b/src/tint/lang/wgsl/ast/binding_attribute.h
index 918674e..6dd616a 100644
--- a/src/tint/lang/wgsl/ast/binding_attribute.h
+++ b/src/tint/lang/wgsl/ast/binding_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the binding expression
-    BindingAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    BindingAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* expr);
     ~BindingAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/bitcast_expression.cc b/src/tint/lang/wgsl/ast/bitcast_expression.cc
index eaf4a9e..9fd5024 100644
--- a/src/tint/lang/wgsl/ast/bitcast_expression.cc
+++ b/src/tint/lang/wgsl/ast/bitcast_expression.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-BitcastExpression::BitcastExpression(ProgramID pid,
+BitcastExpression::BitcastExpression(GenerationID pid,
                                      NodeID nid,
                                      const Source& src,
                                      Type t,
@@ -28,7 +28,7 @@
     : Base(pid, nid, src), type(t), expr(e) {
     TINT_ASSERT(AST, type);
     TINT_ASSERT(AST, expr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, expr, generation_id);
 }
 
 BitcastExpression::~BitcastExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/bitcast_expression.h b/src/tint/lang/wgsl/ast/bitcast_expression.h
index ef2de22..3d56bf9 100644
--- a/src/tint/lang/wgsl/ast/bitcast_expression.h
+++ b/src/tint/lang/wgsl/ast/bitcast_expression.h
@@ -29,7 +29,7 @@
     /// @param source the bitcast expression source
     /// @param type the type
     /// @param expr the expr
-    BitcastExpression(ProgramID pid,
+    BitcastExpression(GenerationID pid,
                       NodeID nid,
                       const Source& source,
                       Type type,
diff --git a/src/tint/lang/wgsl/ast/bitcast_expression_test.cc b/src/tint/lang/wgsl/ast/bitcast_expression_test.cc
index 54df821..54bb99e 100644
--- a/src/tint/lang/wgsl/ast/bitcast_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/bitcast_expression_test.cc
@@ -63,7 +63,7 @@
         "internal compiler error");
 }
 
-TEST_F(BitcastExpressionTest, Assert_DifferentProgramID_Expr) {
+TEST_F(BitcastExpressionTest, Assert_DifferentGenerationID_Expr) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/block_statement.cc b/src/tint/lang/wgsl/ast/block_statement.cc
index ed8ccc7..29b7912 100644
--- a/src/tint/lang/wgsl/ast/block_statement.cc
+++ b/src/tint/lang/wgsl/ast/block_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-BlockStatement::BlockStatement(ProgramID pid,
+BlockStatement::BlockStatement(GenerationID pid,
                                NodeID nid,
                                const Source& src,
                                utils::VectorRef<const Statement*> stmts,
@@ -28,11 +28,11 @@
     : Base(pid, nid, src), statements(std::move(stmts)), attributes(attrs) {
     for (auto* stmt : statements) {
         TINT_ASSERT(AST, stmt);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, stmt, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, stmt, generation_id);
     }
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/block_statement.h b/src/tint/lang/wgsl/ast/block_statement.h
index befb6c7..cbc6b6c 100644
--- a/src/tint/lang/wgsl/ast/block_statement.h
+++ b/src/tint/lang/wgsl/ast/block_statement.h
@@ -35,7 +35,7 @@
     /// @param source the block statement source
     /// @param statements the statements
     /// @param attributes the block statement attributes
-    BlockStatement(ProgramID pid,
+    BlockStatement(GenerationID pid,
                    NodeID nid,
                    const Source& source,
                    utils::VectorRef<const Statement*> statements,
diff --git a/src/tint/lang/wgsl/ast/block_statement_test.cc b/src/tint/lang/wgsl/ast/block_statement_test.cc
index d4ec4cf..599e266 100644
--- a/src/tint/lang/wgsl/ast/block_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/block_statement_test.cc
@@ -68,7 +68,7 @@
         "internal compiler error");
 }
 
-TEST_F(BlockStatementTest, Assert_DifferentProgramID_Statement) {
+TEST_F(BlockStatementTest, Assert_DifferentGenerationID_Statement) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/bool_literal_expression.cc b/src/tint/lang/wgsl/ast/bool_literal_expression.cc
index e9def0f..668b37f 100644
--- a/src/tint/lang/wgsl/ast/bool_literal_expression.cc
+++ b/src/tint/lang/wgsl/ast/bool_literal_expression.cc
@@ -20,7 +20,10 @@
 
 namespace tint::ast {
 
-BoolLiteralExpression::BoolLiteralExpression(ProgramID pid, NodeID nid, const Source& src, bool val)
+BoolLiteralExpression::BoolLiteralExpression(GenerationID pid,
+                                             NodeID nid,
+                                             const Source& src,
+                                             bool val)
     : Base(pid, nid, src), value(val) {}
 
 BoolLiteralExpression::~BoolLiteralExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/bool_literal_expression.h b/src/tint/lang/wgsl/ast/bool_literal_expression.h
index eef02fa..cb74b26 100644
--- a/src/tint/lang/wgsl/ast/bool_literal_expression.h
+++ b/src/tint/lang/wgsl/ast/bool_literal_expression.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param value the bool literals value
-    BoolLiteralExpression(ProgramID pid, NodeID nid, const Source& src, bool value);
+    BoolLiteralExpression(GenerationID pid, NodeID nid, const Source& src, bool value);
     ~BoolLiteralExpression() override;
 
     /// Clones this node and all transitive child nodes using the `CloneContext`
diff --git a/src/tint/lang/wgsl/ast/break_if_statement.cc b/src/tint/lang/wgsl/ast/break_if_statement.cc
index 893fced..3421b54 100644
--- a/src/tint/lang/wgsl/ast/break_if_statement.cc
+++ b/src/tint/lang/wgsl/ast/break_if_statement.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-BreakIfStatement::BreakIfStatement(ProgramID pid,
+BreakIfStatement::BreakIfStatement(GenerationID pid,
                                    NodeID nid,
                                    const Source& src,
                                    const Expression* cond)
     : Base(pid, nid, src), condition(cond) {
     TINT_ASSERT(AST, condition);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, condition, generation_id);
 }
 
 BreakIfStatement::~BreakIfStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/break_if_statement.h b/src/tint/lang/wgsl/ast/break_if_statement.h
index c986e90..bc5fae7 100644
--- a/src/tint/lang/wgsl/ast/break_if_statement.h
+++ b/src/tint/lang/wgsl/ast/break_if_statement.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param condition the if condition
-    BreakIfStatement(ProgramID pid, NodeID nid, const Source& src, const Expression* condition);
+    BreakIfStatement(GenerationID pid, NodeID nid, const Source& src, const Expression* condition);
 
     /// Destructor
     ~BreakIfStatement() override;
diff --git a/src/tint/lang/wgsl/ast/break_if_statement_test.cc b/src/tint/lang/wgsl/ast/break_if_statement_test.cc
index 2eb0091..9f68f64 100644
--- a/src/tint/lang/wgsl/ast/break_if_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/break_if_statement_test.cc
@@ -44,7 +44,7 @@
         "internal compiler error");
 }
 
-TEST_F(BreakIfStatementTest, Assert_DifferentProgramID_Cond) {
+TEST_F(BreakIfStatementTest, Assert_DifferentGenerationID_Cond) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/break_statement.cc b/src/tint/lang/wgsl/ast/break_statement.cc
index 2aed432..51bfd95 100644
--- a/src/tint/lang/wgsl/ast/break_statement.cc
+++ b/src/tint/lang/wgsl/ast/break_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-BreakStatement::BreakStatement(ProgramID pid, NodeID nid, const Source& src)
+BreakStatement::BreakStatement(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 BreakStatement::~BreakStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/break_statement.h b/src/tint/lang/wgsl/ast/break_statement.h
index 8d48e02..b56dc97 100644
--- a/src/tint/lang/wgsl/ast/break_statement.h
+++ b/src/tint/lang/wgsl/ast/break_statement.h
@@ -26,7 +26,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    BreakStatement(ProgramID pid, NodeID nid, const Source& src);
+    BreakStatement(GenerationID pid, NodeID nid, const Source& src);
 
     /// Destructor
     ~BreakStatement() override;
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute.cc b/src/tint/lang/wgsl/ast/builtin_attribute.cc
index b891842..4cfe251 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute.cc
+++ b/src/tint/lang/wgsl/ast/builtin_attribute.cc
@@ -22,12 +22,12 @@
 
 namespace tint::ast {
 
-BuiltinAttribute::BuiltinAttribute(ProgramID pid,
+BuiltinAttribute::BuiltinAttribute(GenerationID pid,
                                    NodeID nid,
                                    const Source& src,
                                    const Expression* b)
     : Base(pid, nid, src), builtin(b) {
-    TINT_ASSERT_PROGRAM_IDS_EQUAL(AST, b, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL(AST, b, generation_id);
 }
 
 BuiltinAttribute::~BuiltinAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute.h b/src/tint/lang/wgsl/ast/builtin_attribute.h
index a5157c2..ef5e26e 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute.h
+++ b/src/tint/lang/wgsl/ast/builtin_attribute.h
@@ -34,7 +34,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param builtin the builtin value
-    BuiltinAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* builtin);
+    BuiltinAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* builtin);
     ~BuiltinAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute_test.cc b/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
index a9cca5d..bd9e6f6 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
+++ b/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
@@ -36,7 +36,7 @@
         "internal compiler error");
 }
 
-TEST_F(BuiltinAttributeTest, Assert_DifferentProgramID_Builtin) {
+TEST_F(BuiltinAttributeTest, Assert_DifferentGenerationID_Builtin) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/call_expression.cc b/src/tint/lang/wgsl/ast/call_expression.cc
index 1ebc392..2e2215b 100644
--- a/src/tint/lang/wgsl/ast/call_expression.cc
+++ b/src/tint/lang/wgsl/ast/call_expression.cc
@@ -22,17 +22,17 @@
 
 namespace tint::ast {
 
-CallExpression::CallExpression(ProgramID pid,
+CallExpression::CallExpression(GenerationID pid,
                                NodeID nid,
                                const Source& src,
                                const IdentifierExpression* t,
                                utils::VectorRef<const Expression*> a)
     : Base(pid, nid, src), target(t), args(std::move(a)) {
     TINT_ASSERT(AST, target);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, target, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, target, generation_id);
     for (auto* arg : args) {
         TINT_ASSERT(AST, arg);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, arg, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, arg, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/call_expression.h b/src/tint/lang/wgsl/ast/call_expression.h
index ee76612..275dc71a 100644
--- a/src/tint/lang/wgsl/ast/call_expression.h
+++ b/src/tint/lang/wgsl/ast/call_expression.h
@@ -37,7 +37,7 @@
     /// @param source the call expression source
     /// @param target the target of the call
     /// @param args the arguments
-    CallExpression(ProgramID pid,
+    CallExpression(GenerationID pid,
                    NodeID nid,
                    const Source& source,
                    const IdentifierExpression* target,
diff --git a/src/tint/lang/wgsl/ast/call_expression_test.cc b/src/tint/lang/wgsl/ast/call_expression_test.cc
index c9117ee..b8f60b0 100644
--- a/src/tint/lang/wgsl/ast/call_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/call_expression_test.cc
@@ -100,7 +100,7 @@
         "internal compiler error");
 }
 
-TEST_F(CallExpressionTest, Assert_DifferentProgramID_Identifier) {
+TEST_F(CallExpressionTest, Assert_DifferentGenerationID_Identifier) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -110,7 +110,7 @@
         "internal compiler error");
 }
 
-TEST_F(CallExpressionTest, Assert_DifferentProgramID_Type) {
+TEST_F(CallExpressionTest, Assert_DifferentGenerationID_Type) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -120,7 +120,7 @@
         "internal compiler error");
 }
 
-TEST_F(CallExpressionTest, Assert_DifferentProgramID_Param) {
+TEST_F(CallExpressionTest, Assert_DifferentGenerationID_Param) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/call_statement.cc b/src/tint/lang/wgsl/ast/call_statement.cc
index 597a451..f19071f 100644
--- a/src/tint/lang/wgsl/ast/call_statement.cc
+++ b/src/tint/lang/wgsl/ast/call_statement.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-CallStatement::CallStatement(ProgramID pid,
+CallStatement::CallStatement(GenerationID pid,
                              NodeID nid,
                              const Source& src,
                              const CallExpression* call)
     : Base(pid, nid, src), expr(call) {
     TINT_ASSERT(AST, expr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, expr, generation_id);
 }
 
 CallStatement::~CallStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/call_statement.h b/src/tint/lang/wgsl/ast/call_statement.h
index fd0c3e7..10bdaed 100644
--- a/src/tint/lang/wgsl/ast/call_statement.h
+++ b/src/tint/lang/wgsl/ast/call_statement.h
@@ -28,7 +28,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node for the statement
     /// @param call the function
-    CallStatement(ProgramID pid, NodeID nid, const Source& src, const CallExpression* call);
+    CallStatement(GenerationID pid, NodeID nid, const Source& src, const CallExpression* call);
 
     /// Destructor
     ~CallStatement() override;
diff --git a/src/tint/lang/wgsl/ast/call_statement_test.cc b/src/tint/lang/wgsl/ast/call_statement_test.cc
index bcf3002..72f0d6c 100644
--- a/src/tint/lang/wgsl/ast/call_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/call_statement_test.cc
@@ -43,7 +43,7 @@
         "internal compiler error");
 }
 
-TEST_F(CallStatementTest, Assert_DifferentProgramID_Call) {
+TEST_F(CallStatementTest, Assert_DifferentGenerationID_Call) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/case_selector.cc b/src/tint/lang/wgsl/ast/case_selector.cc
index 655eed3..58a5172 100644
--- a/src/tint/lang/wgsl/ast/case_selector.cc
+++ b/src/tint/lang/wgsl/ast/case_selector.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-CaseSelector::CaseSelector(ProgramID pid, NodeID nid, const Source& src, const Expression* e)
+CaseSelector::CaseSelector(GenerationID pid, NodeID nid, const Source& src, const Expression* e)
     : Base(pid, nid, src), expr(e) {}
 
 CaseSelector::~CaseSelector() = default;
diff --git a/src/tint/lang/wgsl/ast/case_selector.h b/src/tint/lang/wgsl/ast/case_selector.h
index b91dce9..2eaba09 100644
--- a/src/tint/lang/wgsl/ast/case_selector.h
+++ b/src/tint/lang/wgsl/ast/case_selector.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the selector expression, |nullptr| for a `default` selector
-    CaseSelector(ProgramID pid, NodeID nid, const Source& src, const Expression* expr = nullptr);
+    CaseSelector(GenerationID pid, NodeID nid, const Source& src, const Expression* expr = nullptr);
 
     /// Destructor
     ~CaseSelector() override;
diff --git a/src/tint/lang/wgsl/ast/case_statement.cc b/src/tint/lang/wgsl/ast/case_statement.cc
index 5b082b2..bd89686 100644
--- a/src/tint/lang/wgsl/ast/case_statement.cc
+++ b/src/tint/lang/wgsl/ast/case_statement.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-CaseStatement::CaseStatement(ProgramID pid,
+CaseStatement::CaseStatement(GenerationID pid,
                              NodeID nid,
                              const Source& src,
                              utils::VectorRef<const CaseSelector*> s,
@@ -30,10 +30,10 @@
     : Base(pid, nid, src), selectors(std::move(s)), body(b) {
     TINT_ASSERT(AST, body);
     TINT_ASSERT(AST, !selectors.IsEmpty());
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
     for (auto* selector : selectors) {
         TINT_ASSERT(AST, selector);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, selector, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, selector, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/case_statement.h b/src/tint/lang/wgsl/ast/case_statement.h
index 026e14b..9579214 100644
--- a/src/tint/lang/wgsl/ast/case_statement.h
+++ b/src/tint/lang/wgsl/ast/case_statement.h
@@ -31,7 +31,7 @@
     /// @param src the source of this node
     /// @param selectors the case selectors
     /// @param body the case body
-    CaseStatement(ProgramID pid,
+    CaseStatement(GenerationID pid,
                   NodeID nid,
                   const Source& src,
                   utils::VectorRef<const CaseSelector*> selectors,
diff --git a/src/tint/lang/wgsl/ast/case_statement_test.cc b/src/tint/lang/wgsl/ast/case_statement_test.cc
index 4ef5471..07c2c83 100644
--- a/src/tint/lang/wgsl/ast/case_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/case_statement_test.cc
@@ -105,7 +105,7 @@
         "internal compiler error");
 }
 
-TEST_F(CaseStatementTest, Assert_DifferentProgramID_Call) {
+TEST_F(CaseStatementTest, Assert_DifferentGenerationID_Call) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -116,7 +116,7 @@
         "internal compiler error");
 }
 
-TEST_F(CaseStatementTest, Assert_DifferentProgramID_Selector) {
+TEST_F(CaseStatementTest, Assert_DifferentGenerationID_Selector) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/clone_context.h b/src/tint/lang/wgsl/ast/clone_context.h
index 94a2646..60471e5 100644
--- a/src/tint/lang/wgsl/ast/clone_context.h
+++ b/src/tint/lang/wgsl/ast/clone_context.h
@@ -21,11 +21,11 @@
 #include <utility>
 #include <vector>
 
-#include "src/tint/program_id.h"
 #include "src/tint/utils/containers/hashmap.h"
 #include "src/tint/utils/containers/hashset.h"
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/debug/debug.h"
+#include "src/tint/utils/generation_id.h"
 #include "src/tint/utils/macros/compiler.h"
 #include "src/tint/utils/rtti/castable.h"
 #include "src/tint/utils/text/symbol.h"
@@ -45,8 +45,8 @@
 
 namespace tint {
 
-ProgramID ProgramIDOf(const Program*);
-ProgramID ProgramIDOf(const ProgramBuilder*);
+GenerationID GenerationIDOf(const Program*);
+GenerationID GenerationIDOf(const ProgramBuilder*);
 
 /// Cloneable is the base class for all objects that can be cloned
 class Cloneable : public utils::Castable<Cloneable> {
@@ -64,9 +64,9 @@
     virtual const Cloneable* Clone(CloneContext* ctx) const = 0;
 };
 
-/// @returns an invalid ProgramID
-inline ProgramID ProgramIDOf(const Cloneable*) {
-    return ProgramID();
+/// @returns an invalid GenerationID
+inline GenerationID GenerationIDOf(const Cloneable*) {
+    return GenerationID();
 }
 
 /// CloneContext holds the state used while cloning AST nodes.
@@ -109,11 +109,11 @@
     template <typename T>
     const T* Clone(const T* object) {
         if (src) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, object);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, object);
         }
         if (auto* cloned = CloneCloneable(object)) {
             auto* out = CheckedCast<T>(cloned);
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, out);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, out);
             return out;
         }
         return nullptr;
@@ -137,7 +137,7 @@
             return nullptr;
         }
         if (src) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, a);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, a);
         }
         auto* c = a->Clone(this);
         return CheckedCast<T>(c);
@@ -360,8 +360,8 @@
               typename WITH,
               typename = utils::traits::EnableIfIsType<WITH, Cloneable>>
     CloneContext& Replace(const WHAT* what, const WITH* with) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, what);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, with);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, what);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, with);
         replacements_.Replace(what, [with]() -> const Cloneable* { return with; });
         return *this;
     }
@@ -381,7 +381,7 @@
     /// @returns this CloneContext so calls can be chained
     template <typename WHAT, typename WITH, typename = std::invoke_result_t<WITH>>
     CloneContext& Replace(const WHAT* what, WITH&& with) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, what);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, what);
         replacements_.Replace(what, with);
         return *this;
     }
@@ -393,7 +393,7 @@
     /// @returns this CloneContext so calls can be chained
     template <typename T, size_t N, typename OBJECT>
     CloneContext& Remove(const utils::Vector<T, N>& vector, OBJECT* object) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, object);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, object);
         if (TINT_UNLIKELY((std::find(vector.begin(), vector.end(), object) == vector.end()))) {
             TINT_ICE(Clone, Diagnostics())
                 << "CloneContext::Remove() vector does not contain object";
@@ -411,7 +411,7 @@
     /// @returns this CloneContext so calls can be chained
     template <typename T, size_t N, typename OBJECT>
     CloneContext& InsertFront(const utils::Vector<T, N>& vector, OBJECT* object) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, object);
         return InsertFront(vector, [object] { return object; });
     }
 
@@ -433,7 +433,7 @@
     /// @returns this CloneContext so calls can be chained
     template <typename T, size_t N, typename OBJECT>
     CloneContext& InsertBack(const utils::Vector<T, N>& vector, OBJECT* object) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, object);
         return InsertBack(vector, [object] { return object; });
     }
 
@@ -459,8 +459,8 @@
     CloneContext& InsertBefore(const utils::Vector<T, N>& vector,
                                const BEFORE* before,
                                const OBJECT* object) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, before);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, before);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, object);
         if (TINT_UNLIKELY((std::find(vector.begin(), vector.end(), before) == vector.end()))) {
             TINT_ICE(Clone, Diagnostics())
                 << "CloneContext::InsertBefore() vector does not contain before";
@@ -501,8 +501,8 @@
     CloneContext& InsertAfter(const utils::Vector<T, N>& vector,
                               const AFTER* after,
                               const OBJECT* object) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, after);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, object);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, after);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, object);
         if (TINT_UNLIKELY((std::find(vector.begin(), vector.end(), after) == vector.end()))) {
             TINT_ICE(Clone, Diagnostics())
                 << "CloneContext::InsertAfter() vector does not contain after";
diff --git a/src/tint/lang/wgsl/ast/clone_context_test.cc b/src/tint/lang/wgsl/ast/clone_context_test.cc
index 59175ee..ecdbe9d 100644
--- a/src/tint/lang/wgsl/ast/clone_context_test.cc
+++ b/src/tint/lang/wgsl/ast/clone_context_test.cc
@@ -76,20 +76,20 @@
 };
 
 struct ProgramNode : public utils::Castable<ProgramNode, Cloneable> {
-    ProgramNode(Allocator* alloc, ProgramID id, ProgramID cloned_id)
-        : allocator(alloc), program_id(id), cloned_program_id(cloned_id) {}
+    ProgramNode(Allocator* alloc, GenerationID id, GenerationID cloned_id)
+        : allocator(alloc), generation_id(id), cloned_generation_id(cloned_id) {}
 
     Allocator* const allocator;
-    const ProgramID program_id;
-    const ProgramID cloned_program_id;
+    const GenerationID generation_id;
+    const GenerationID cloned_generation_id;
 
     ProgramNode* Clone(CloneContext*) const override {
-        return allocator->Create<ProgramNode>(cloned_program_id, cloned_program_id);
+        return allocator->Create<ProgramNode>(cloned_generation_id, cloned_generation_id);
     }
 };
 
-ProgramID ProgramIDOf(const ProgramNode* node) {
-    return node->program_id;
+GenerationID GenerationIDOf(const ProgramNode* node) {
+    return node->generation_id;
 }
 
 using CloneContextNodeTest = ::testing::Test;
@@ -1250,37 +1250,37 @@
     EXPECT_EQ(new_c.Name(), "c");
 }
 
-TEST_F(CloneContextTest, ProgramIDs) {
+TEST_F(CloneContextTest, GenerationIDs) {
     ProgramBuilder dst;
     Program src(ProgramBuilder{});
     CloneContext ctx(&dst, &src);
     Allocator allocator;
     auto* cloned = ctx.Clone(allocator.Create<ProgramNode>(src.ID(), dst.ID()));
-    EXPECT_EQ(cloned->program_id, dst.ID());
+    EXPECT_EQ(cloned->generation_id, dst.ID());
 }
 
-TEST_F(CloneContextTest, ProgramIDs_Clone_ObjectNotOwnedBySrc) {
+TEST_F(CloneContextTest, GenerationIDs_Clone_ObjectNotOwnedBySrc) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder dst;
             Program src(ProgramBuilder{});
             CloneContext ctx(&dst, &src);
             Allocator allocator;
-            ctx.Clone(allocator.Create<ProgramNode>(ProgramID::New(), dst.ID()));
+            ctx.Clone(allocator.Create<ProgramNode>(GenerationID::New(), dst.ID()));
         },
-        R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, src, object))");
+        R"(internal compiler error: TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, src, object))");
 }
 
-TEST_F(CloneContextTest, ProgramIDs_Clone_ObjectNotOwnedByDst) {
+TEST_F(CloneContextTest, GenerationIDs_Clone_ObjectNotOwnedByDst) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder dst;
             Program src(ProgramBuilder{});
             CloneContext ctx(&dst, &src);
             Allocator allocator;
-            ctx.Clone(allocator.Create<ProgramNode>(src.ID(), ProgramID::New()));
+            ctx.Clone(allocator.Create<ProgramNode>(src.ID(), GenerationID::New()));
         },
-        R"(internal compiler error: TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(Clone, dst, out))");
+        R"(internal compiler error: TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(Clone, dst, out))");
 }
 
 }  // namespace
diff --git a/src/tint/lang/wgsl/ast/compound_assignment_statement.cc b/src/tint/lang/wgsl/ast/compound_assignment_statement.cc
index 41a8668..d235bc6 100644
--- a/src/tint/lang/wgsl/ast/compound_assignment_statement.cc
+++ b/src/tint/lang/wgsl/ast/compound_assignment_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-CompoundAssignmentStatement::CompoundAssignmentStatement(ProgramID pid,
+CompoundAssignmentStatement::CompoundAssignmentStatement(GenerationID pid,
                                                          NodeID nid,
                                                          const Source& src,
                                                          const Expression* l,
@@ -28,9 +28,9 @@
                                                          BinaryOp o)
     : Base(pid, nid, src), lhs(l), rhs(r), op(o) {
     TINT_ASSERT(AST, lhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, lhs, generation_id);
     TINT_ASSERT(AST, rhs);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, rhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, rhs, generation_id);
 }
 
 CompoundAssignmentStatement::~CompoundAssignmentStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/compound_assignment_statement.h b/src/tint/lang/wgsl/ast/compound_assignment_statement.h
index c59e5e7..bd7fa79 100644
--- a/src/tint/lang/wgsl/ast/compound_assignment_statement.h
+++ b/src/tint/lang/wgsl/ast/compound_assignment_statement.h
@@ -32,7 +32,7 @@
     /// @param lhs the left side of the expression
     /// @param rhs the right side of the expression
     /// @param op the binary operator
-    CompoundAssignmentStatement(ProgramID pid,
+    CompoundAssignmentStatement(GenerationID pid,
                                 NodeID nid,
                                 const Source& source,
                                 const Expression* lhs,
diff --git a/src/tint/lang/wgsl/ast/compound_assignment_statement_test.cc b/src/tint/lang/wgsl/ast/compound_assignment_statement_test.cc
index 2595c6a..20f42d8 100644
--- a/src/tint/lang/wgsl/ast/compound_assignment_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/compound_assignment_statement_test.cc
@@ -73,7 +73,7 @@
         "internal compiler error");
 }
 
-TEST_F(CompoundAssignmentStatementTest, Assert_DifferentProgramID_LHS) {
+TEST_F(CompoundAssignmentStatementTest, Assert_DifferentGenerationID_LHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -83,7 +83,7 @@
         "internal compiler error");
 }
 
-TEST_F(CompoundAssignmentStatementTest, Assert_DifferentProgramID_RHS) {
+TEST_F(CompoundAssignmentStatementTest, Assert_DifferentGenerationID_RHS) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/const.cc b/src/tint/lang/wgsl/ast/const.cc
index ad5c796..02439d6 100644
--- a/src/tint/lang/wgsl/ast/const.cc
+++ b/src/tint/lang/wgsl/ast/const.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Const::Const(ProgramID pid,
+Const::Const(GenerationID pid,
              NodeID nid,
              const Source& src,
              const Identifier* n,
diff --git a/src/tint/lang/wgsl/ast/const.h b/src/tint/lang/wgsl/ast/const.h
index 66c7882..1a50e14 100644
--- a/src/tint/lang/wgsl/ast/const.h
+++ b/src/tint/lang/wgsl/ast/const.h
@@ -40,7 +40,7 @@
     /// @param type the declared variable type
     /// @param initializer the initializer expression. Must not be nullptr.
     /// @param attributes the variable attributes
-    Const(ProgramID pid,
+    Const(GenerationID pid,
           NodeID nid,
           const Source& source,
           const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/const_assert.cc b/src/tint/lang/wgsl/ast/const_assert.cc
index ab27046..59c1cf8 100644
--- a/src/tint/lang/wgsl/ast/const_assert.cc
+++ b/src/tint/lang/wgsl/ast/const_assert.cc
@@ -20,10 +20,10 @@
 
 namespace tint::ast {
 
-ConstAssert::ConstAssert(ProgramID pid, NodeID nid, const Source& src, const Expression* cond)
+ConstAssert::ConstAssert(GenerationID pid, NodeID nid, const Source& src, const Expression* cond)
     : Base(pid, nid, src), condition(cond) {
     TINT_ASSERT(AST, cond);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, cond, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, cond, generation_id);
 }
 
 ConstAssert::~ConstAssert() = default;
diff --git a/src/tint/lang/wgsl/ast/const_assert.h b/src/tint/lang/wgsl/ast/const_assert.h
index a799093..13ed7d6 100644
--- a/src/tint/lang/wgsl/ast/const_assert.h
+++ b/src/tint/lang/wgsl/ast/const_assert.h
@@ -28,7 +28,7 @@
     /// @param nid the unique node identifier
     /// @param source the variable statement source
     /// @param condition the assertion condition
-    ConstAssert(ProgramID pid, NodeID nid, const Source& source, const Expression* condition);
+    ConstAssert(GenerationID pid, NodeID nid, const Source& source, const Expression* condition);
 
     /// Destructor
     ~ConstAssert() override;
diff --git a/src/tint/lang/wgsl/ast/const_assert_test.cc b/src/tint/lang/wgsl/ast/const_assert_test.cc
index b43cf61..703f47e 100644
--- a/src/tint/lang/wgsl/ast/const_assert_test.cc
+++ b/src/tint/lang/wgsl/ast/const_assert_test.cc
@@ -52,7 +52,7 @@
         "internal compiler error");
 }
 
-TEST_F(ConstAssertTest, Assert_DifferentProgramID_Condition) {
+TEST_F(ConstAssertTest, Assert_DifferentGenerationID_Condition) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/continue_statement.cc b/src/tint/lang/wgsl/ast/continue_statement.cc
index 8e8e40b..724a083 100644
--- a/src/tint/lang/wgsl/ast/continue_statement.cc
+++ b/src/tint/lang/wgsl/ast/continue_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-ContinueStatement::ContinueStatement(ProgramID pid, NodeID nid, const Source& src)
+ContinueStatement::ContinueStatement(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 ContinueStatement::~ContinueStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/continue_statement.h b/src/tint/lang/wgsl/ast/continue_statement.h
index 3b1201c..2805204 100644
--- a/src/tint/lang/wgsl/ast/continue_statement.h
+++ b/src/tint/lang/wgsl/ast/continue_statement.h
@@ -26,7 +26,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    ContinueStatement(ProgramID pid, NodeID nid, const Source& src);
+    ContinueStatement(GenerationID pid, NodeID nid, const Source& src);
 
     /// Destructor
     ~ContinueStatement() override;
diff --git a/src/tint/lang/wgsl/ast/diagnostic_attribute.cc b/src/tint/lang/wgsl/ast/diagnostic_attribute.cc
index de2e1ff..d3e5888 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_attribute.cc
+++ b/src/tint/lang/wgsl/ast/diagnostic_attribute.cc
@@ -23,7 +23,7 @@
 
 namespace tint::ast {
 
-DiagnosticAttribute::DiagnosticAttribute(ProgramID pid,
+DiagnosticAttribute::DiagnosticAttribute(GenerationID pid,
                                          NodeID nid,
                                          const Source& src,
                                          DiagnosticControl&& dc)
diff --git a/src/tint/lang/wgsl/ast/diagnostic_attribute.h b/src/tint/lang/wgsl/ast/diagnostic_attribute.h
index 38fbe23..319a476 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_attribute.h
+++ b/src/tint/lang/wgsl/ast/diagnostic_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param dc the diagnostic control
-    DiagnosticAttribute(ProgramID pid, NodeID nid, const Source& src, DiagnosticControl&& dc);
+    DiagnosticAttribute(GenerationID pid, NodeID nid, const Source& src, DiagnosticControl&& dc);
     ~DiagnosticAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/diagnostic_directive.cc b/src/tint/lang/wgsl/ast/diagnostic_directive.cc
index 09b5433..77ff219 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_directive.cc
+++ b/src/tint/lang/wgsl/ast/diagnostic_directive.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-DiagnosticDirective::DiagnosticDirective(ProgramID pid,
+DiagnosticDirective::DiagnosticDirective(GenerationID pid,
                                          NodeID nid,
                                          const Source& src,
                                          DiagnosticControl&& dc)
diff --git a/src/tint/lang/wgsl/ast/diagnostic_directive.h b/src/tint/lang/wgsl/ast/diagnostic_directive.h
index 5a917d9..a048782 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_directive.h
+++ b/src/tint/lang/wgsl/ast/diagnostic_directive.h
@@ -36,7 +36,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param dc the diagnostic control
-    DiagnosticDirective(ProgramID pid, NodeID nid, const Source& src, DiagnosticControl&& dc);
+    DiagnosticDirective(GenerationID pid, NodeID nid, const Source& src, DiagnosticControl&& dc);
 
     /// Destructor
     ~DiagnosticDirective() override;
diff --git a/src/tint/lang/wgsl/ast/diagnostic_rule_name.cc b/src/tint/lang/wgsl/ast/diagnostic_rule_name.cc
index 3c39e49..22ca445 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_rule_name.cc
+++ b/src/tint/lang/wgsl/ast/diagnostic_rule_name.cc
@@ -22,33 +22,33 @@
 
 namespace tint::ast {
 
-DiagnosticRuleName::DiagnosticRuleName(ProgramID pid,
+DiagnosticRuleName::DiagnosticRuleName(GenerationID pid,
                                        NodeID nid,
                                        const Source& src,
                                        const Identifier* n)
     : Base(pid, nid, src), name(n) {
     TINT_ASSERT(AST, name != nullptr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, name, generation_id);
     if (name) {
         // It is invalid for a diagnostic rule name to be templated
         TINT_ASSERT(AST, !name->Is<TemplatedIdentifier>());
     }
 }
 
-DiagnosticRuleName::DiagnosticRuleName(ProgramID pid,
+DiagnosticRuleName::DiagnosticRuleName(GenerationID pid,
                                        NodeID nid,
                                        const Source& src,
                                        const Identifier* c,
                                        const Identifier* n)
     : Base(pid, nid, src), category(c), name(n) {
     TINT_ASSERT(AST, name != nullptr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, name, generation_id);
     if (name) {
         // It is invalid for a diagnostic rule name to be templated
         TINT_ASSERT(AST, !name->Is<TemplatedIdentifier>());
     }
     if (category) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, category, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, category, generation_id);
         // It is invalid for a diagnostic rule category to be templated
         TINT_ASSERT(AST, !category->Is<TemplatedIdentifier>());
     }
diff --git a/src/tint/lang/wgsl/ast/diagnostic_rule_name.h b/src/tint/lang/wgsl/ast/diagnostic_rule_name.h
index b8692f9..c601d08 100644
--- a/src/tint/lang/wgsl/ast/diagnostic_rule_name.h
+++ b/src/tint/lang/wgsl/ast/diagnostic_rule_name.h
@@ -34,7 +34,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param name the rule name
-    DiagnosticRuleName(ProgramID pid, NodeID nid, const Source& src, const Identifier* name);
+    DiagnosticRuleName(GenerationID pid, NodeID nid, const Source& src, const Identifier* name);
 
     /// Constructor
     /// @param pid the identifier of the program that owns this node
@@ -42,7 +42,7 @@
     /// @param src the source of this node
     /// @param category the rule category.
     /// @param name the rule name
-    DiagnosticRuleName(ProgramID pid,
+    DiagnosticRuleName(GenerationID pid,
                        NodeID nid,
                        const Source& src,
                        const Identifier* category,
diff --git a/src/tint/lang/wgsl/ast/disable_validation_attribute.cc b/src/tint/lang/wgsl/ast/disable_validation_attribute.cc
index c0b1a12..f374ef7 100644
--- a/src/tint/lang/wgsl/ast/disable_validation_attribute.cc
+++ b/src/tint/lang/wgsl/ast/disable_validation_attribute.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-DisableValidationAttribute::DisableValidationAttribute(ProgramID pid,
+DisableValidationAttribute::DisableValidationAttribute(GenerationID pid,
                                                        NodeID nid,
                                                        DisabledValidation val)
     : Base(pid, nid, utils::Empty), validation(val) {}
diff --git a/src/tint/lang/wgsl/ast/disable_validation_attribute.h b/src/tint/lang/wgsl/ast/disable_validation_attribute.h
index 44b815b..0226659 100644
--- a/src/tint/lang/wgsl/ast/disable_validation_attribute.h
+++ b/src/tint/lang/wgsl/ast/disable_validation_attribute.h
@@ -59,7 +59,9 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param validation the validation to disable
-    explicit DisableValidationAttribute(ProgramID pid, NodeID nid, DisabledValidation validation);
+    explicit DisableValidationAttribute(GenerationID pid,
+                                        NodeID nid,
+                                        DisabledValidation validation);
 
     /// Destructor
     ~DisableValidationAttribute() override;
diff --git a/src/tint/lang/wgsl/ast/discard_statement.cc b/src/tint/lang/wgsl/ast/discard_statement.cc
index 6904fdf..de4d60f 100644
--- a/src/tint/lang/wgsl/ast/discard_statement.cc
+++ b/src/tint/lang/wgsl/ast/discard_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-DiscardStatement::DiscardStatement(ProgramID pid, NodeID nid, const Source& src)
+DiscardStatement::DiscardStatement(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 DiscardStatement::~DiscardStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/discard_statement.h b/src/tint/lang/wgsl/ast/discard_statement.h
index b192da9..b75163d 100644
--- a/src/tint/lang/wgsl/ast/discard_statement.h
+++ b/src/tint/lang/wgsl/ast/discard_statement.h
@@ -26,7 +26,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    DiscardStatement(ProgramID pid, NodeID nid, const Source& src);
+    DiscardStatement(GenerationID pid, NodeID nid, const Source& src);
 
     /// Destructor
     ~DiscardStatement() override;
diff --git a/src/tint/lang/wgsl/ast/enable.cc b/src/tint/lang/wgsl/ast/enable.cc
index b9169f3..b230428 100644
--- a/src/tint/lang/wgsl/ast/enable.cc
+++ b/src/tint/lang/wgsl/ast/enable.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-Enable::Enable(ProgramID pid,
+Enable::Enable(GenerationID pid,
                NodeID nid,
                const Source& src,
                utils::VectorRef<const Extension*> exts)
diff --git a/src/tint/lang/wgsl/ast/enable.h b/src/tint/lang/wgsl/ast/enable.h
index fa32c57..e0017a0 100644
--- a/src/tint/lang/wgsl/ast/enable.h
+++ b/src/tint/lang/wgsl/ast/enable.h
@@ -35,7 +35,10 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param exts the extensions being enabled by this directive
-    Enable(ProgramID pid, NodeID nid, const Source& src, utils::VectorRef<const Extension*> exts);
+    Enable(GenerationID pid,
+           NodeID nid,
+           const Source& src,
+           utils::VectorRef<const Extension*> exts);
 
     /// Destructor
     ~Enable() override;
diff --git a/src/tint/lang/wgsl/ast/expression.cc b/src/tint/lang/wgsl/ast/expression.cc
index 4321e57..0f60816 100644
--- a/src/tint/lang/wgsl/ast/expression.cc
+++ b/src/tint/lang/wgsl/ast/expression.cc
@@ -18,7 +18,7 @@
 
 namespace tint::ast {
 
-Expression::Expression(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
+Expression::Expression(GenerationID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
 
 Expression::~Expression() = default;
 
diff --git a/src/tint/lang/wgsl/ast/expression.h b/src/tint/lang/wgsl/ast/expression.h
index 1ad9e2d..b4297b4 100644
--- a/src/tint/lang/wgsl/ast/expression.h
+++ b/src/tint/lang/wgsl/ast/expression.h
@@ -32,7 +32,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    Expression(ProgramID pid, NodeID nid, const Source& src);
+    Expression(GenerationID pid, NodeID nid, const Source& src);
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/extension.cc b/src/tint/lang/wgsl/ast/extension.cc
index 672d3a5..ac8a3ad 100644
--- a/src/tint/lang/wgsl/ast/extension.cc
+++ b/src/tint/lang/wgsl/ast/extension.cc
@@ -23,7 +23,7 @@
 
 namespace tint::ast {
 
-Extension::Extension(ProgramID pid, NodeID nid, const Source& src, builtin::Extension ext)
+Extension::Extension(GenerationID pid, NodeID nid, const Source& src, builtin::Extension ext)
     : Base(pid, nid, src), name(ext) {}
 
 Extension::~Extension() = default;
diff --git a/src/tint/lang/wgsl/ast/extension.h b/src/tint/lang/wgsl/ast/extension.h
index 115f990..60b1e48 100644
--- a/src/tint/lang/wgsl/ast/extension.h
+++ b/src/tint/lang/wgsl/ast/extension.h
@@ -31,7 +31,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param ext the extension
-    Extension(ProgramID pid, NodeID nid, const Source& src, builtin::Extension ext);
+    Extension(GenerationID pid, NodeID nid, const Source& src, builtin::Extension ext);
 
     /// Destructor
     ~Extension() override;
diff --git a/src/tint/lang/wgsl/ast/float_literal_expression.cc b/src/tint/lang/wgsl/ast/float_literal_expression.cc
index 5e76322..0487b3a 100644
--- a/src/tint/lang/wgsl/ast/float_literal_expression.cc
+++ b/src/tint/lang/wgsl/ast/float_literal_expression.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-FloatLiteralExpression::FloatLiteralExpression(ProgramID pid,
+FloatLiteralExpression::FloatLiteralExpression(GenerationID pid,
                                                NodeID nid,
                                                const Source& src,
                                                double val,
diff --git a/src/tint/lang/wgsl/ast/float_literal_expression.h b/src/tint/lang/wgsl/ast/float_literal_expression.h
index e156505..70ef60b 100644
--- a/src/tint/lang/wgsl/ast/float_literal_expression.h
+++ b/src/tint/lang/wgsl/ast/float_literal_expression.h
@@ -41,7 +41,7 @@
     /// @param src the source of this node
     /// @param val the literal value
     /// @param suf the literal suffix
-    FloatLiteralExpression(ProgramID pid, NodeID nid, const Source& src, double val, Suffix suf);
+    FloatLiteralExpression(GenerationID pid, NodeID nid, const Source& src, double val, Suffix suf);
     ~FloatLiteralExpression() override;
 
     /// Clones this node and all transitive child nodes using the `CloneContext`
diff --git a/src/tint/lang/wgsl/ast/for_loop_statement.cc b/src/tint/lang/wgsl/ast/for_loop_statement.cc
index 9cb66f7..72282df 100644
--- a/src/tint/lang/wgsl/ast/for_loop_statement.cc
+++ b/src/tint/lang/wgsl/ast/for_loop_statement.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-ForLoopStatement::ForLoopStatement(ProgramID pid,
+ForLoopStatement::ForLoopStatement(GenerationID pid,
                                    NodeID nid,
                                    const Source& src,
                                    const Statement* init,
@@ -38,13 +38,13 @@
       attributes(std::move(attrs)) {
     TINT_ASSERT(AST, body);
 
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, initializer, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, continuing, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, initializer, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, condition, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, continuing, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/for_loop_statement.h b/src/tint/lang/wgsl/ast/for_loop_statement.h
index 9156143..e389c41 100644
--- a/src/tint/lang/wgsl/ast/for_loop_statement.h
+++ b/src/tint/lang/wgsl/ast/for_loop_statement.h
@@ -33,7 +33,7 @@
     /// @param continuing the optional continuing statement
     /// @param body the loop body
     /// @param attributes the while statement attributes
-    ForLoopStatement(ProgramID pid,
+    ForLoopStatement(GenerationID pid,
                      NodeID nid,
                      const Source& source,
                      const Statement* initializer,
diff --git a/src/tint/lang/wgsl/ast/for_loop_statement_test.cc b/src/tint/lang/wgsl/ast/for_loop_statement_test.cc
index f6f145c..e1e03e2 100644
--- a/src/tint/lang/wgsl/ast/for_loop_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/for_loop_statement_test.cc
@@ -69,7 +69,7 @@
         "internal compiler error");
 }
 
-TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Initializer) {
+TEST_F(ForLoopStatementTest, Assert_DifferentGenerationID_Initializer) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -79,7 +79,7 @@
         "internal compiler error");
 }
 
-TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Condition) {
+TEST_F(ForLoopStatementTest, Assert_DifferentGenerationID_Condition) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -89,7 +89,7 @@
         "internal compiler error");
 }
 
-TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Continuing) {
+TEST_F(ForLoopStatementTest, Assert_DifferentGenerationID_Continuing) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -99,7 +99,7 @@
         "internal compiler error");
 }
 
-TEST_F(ForLoopStatementTest, Assert_DifferentProgramID_Body) {
+TEST_F(ForLoopStatementTest, Assert_DifferentGenerationID_Body) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/function.cc b/src/tint/lang/wgsl/ast/function.cc
index c0c3d7d..db445bd 100644
--- a/src/tint/lang/wgsl/ast/function.cc
+++ b/src/tint/lang/wgsl/ast/function.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Function::Function(ProgramID pid,
+Function::Function(GenerationID pid,
                    NodeID nid,
                    const Source& src,
                    const Identifier* n,
@@ -42,18 +42,18 @@
     if (name) {
         TINT_ASSERT(AST, !name->Is<TemplatedIdentifier>());
     }
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, return_ty, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, name, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, return_ty, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
     for (auto* param : params) {
         TINT_ASSERT(AST, tint::Is<Parameter>(param));
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, param, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, param, generation_id);
     }
     for (auto* attr : attributes) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
     for (auto* attr : return_type_attributes) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/function.h b/src/tint/lang/wgsl/ast/function.h
index 02c4876..2a8efc4 100644
--- a/src/tint/lang/wgsl/ast/function.h
+++ b/src/tint/lang/wgsl/ast/function.h
@@ -50,7 +50,7 @@
     /// @param body the function body
     /// @param attributes the function attributes
     /// @param return_type_attributes the return type attributes
-    Function(ProgramID pid,
+    Function(GenerationID pid,
              NodeID nid,
              const Source& source,
              const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/function_test.cc b/src/tint/lang/wgsl/ast/function_test.cc
index c48e87a..65aefc1 100644
--- a/src/tint/lang/wgsl/ast/function_test.cc
+++ b/src/tint/lang/wgsl/ast/function_test.cc
@@ -129,7 +129,7 @@
         "internal compiler error");
 }
 
-TEST_F(FunctionTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(FunctionTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -139,7 +139,7 @@
         "internal compiler error");
 }
 
-TEST_F(FunctionTest, Assert_DifferentProgramID_Param) {
+TEST_F(FunctionTest, Assert_DifferentGenerationID_Param) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -153,7 +153,7 @@
         "internal compiler error");
 }
 
-TEST_F(FunctionTest, Assert_DifferentProgramID_Attr) {
+TEST_F(FunctionTest, Assert_DifferentGenerationID_Attr) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -166,7 +166,7 @@
         "internal compiler error");
 }
 
-TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnType) {
+TEST_F(FunctionTest, Assert_DifferentGenerationID_ReturnType) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -176,7 +176,7 @@
         "internal compiler error");
 }
 
-TEST_F(FunctionTest, Assert_DifferentProgramID_ReturnAttr) {
+TEST_F(FunctionTest, Assert_DifferentGenerationID_ReturnAttr) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/group_attribute.cc b/src/tint/lang/wgsl/ast/group_attribute.cc
index e3d5d72..30da424 100644
--- a/src/tint/lang/wgsl/ast/group_attribute.cc
+++ b/src/tint/lang/wgsl/ast/group_attribute.cc
@@ -22,7 +22,10 @@
 
 namespace tint::ast {
 
-GroupAttribute::GroupAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* exp)
+GroupAttribute::GroupAttribute(GenerationID pid,
+                               NodeID nid,
+                               const Source& src,
+                               const Expression* exp)
     : Base(pid, nid, src), expr(exp) {}
 
 GroupAttribute::~GroupAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/group_attribute.h b/src/tint/lang/wgsl/ast/group_attribute.h
index ea45ea7..9f96824 100644
--- a/src/tint/lang/wgsl/ast/group_attribute.h
+++ b/src/tint/lang/wgsl/ast/group_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the group expression
-    GroupAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    GroupAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* expr);
     ~GroupAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/id_attribute.cc b/src/tint/lang/wgsl/ast/id_attribute.cc
index 8d580a0..007b92b 100644
--- a/src/tint/lang/wgsl/ast/id_attribute.cc
+++ b/src/tint/lang/wgsl/ast/id_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-IdAttribute::IdAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* exp)
+IdAttribute::IdAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* exp)
     : Base(pid, nid, src), expr(exp) {}
 
 IdAttribute::~IdAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/id_attribute.h b/src/tint/lang/wgsl/ast/id_attribute.h
index 119494a..939ecd9 100644
--- a/src/tint/lang/wgsl/ast/id_attribute.h
+++ b/src/tint/lang/wgsl/ast/id_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the numeric id expression
-    IdAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    IdAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* expr);
     ~IdAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/identifier.cc b/src/tint/lang/wgsl/ast/identifier.cc
index 86f7d98..d31b9ad 100644
--- a/src/tint/lang/wgsl/ast/identifier.cc
+++ b/src/tint/lang/wgsl/ast/identifier.cc
@@ -20,9 +20,9 @@
 
 namespace tint::ast {
 
-Identifier::Identifier(ProgramID pid, NodeID nid, const Source& src, Symbol sym)
+Identifier::Identifier(GenerationID pid, NodeID nid, const Source& src, Symbol sym)
     : Base(pid, nid, src), symbol(sym) {
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, symbol, generation_id);
     TINT_ASSERT(AST, symbol.IsValid());
 }
 
diff --git a/src/tint/lang/wgsl/ast/identifier.h b/src/tint/lang/wgsl/ast/identifier.h
index 7a4a6eb..54eff33 100644
--- a/src/tint/lang/wgsl/ast/identifier.h
+++ b/src/tint/lang/wgsl/ast/identifier.h
@@ -27,7 +27,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param sym the symbol for the identifier
-    Identifier(ProgramID pid, NodeID nid, const Source& src, Symbol sym);
+    Identifier(GenerationID pid, NodeID nid, const Source& src, Symbol sym);
 
     /// Destructor
     ~Identifier() override;
diff --git a/src/tint/lang/wgsl/ast/identifier_expression.cc b/src/tint/lang/wgsl/ast/identifier_expression.cc
index 5f23d15..8666a10 100644
--- a/src/tint/lang/wgsl/ast/identifier_expression.cc
+++ b/src/tint/lang/wgsl/ast/identifier_expression.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-IdentifierExpression::IdentifierExpression(ProgramID pid,
+IdentifierExpression::IdentifierExpression(GenerationID pid,
                                            NodeID nid,
                                            const Source& src,
                                            const Identifier* ident)
     : Base(pid, nid, src), identifier(ident) {
     TINT_ASSERT(AST, identifier != nullptr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL(AST, identifier, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL(AST, identifier, generation_id);
 }
 
 IdentifierExpression::~IdentifierExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/identifier_expression.h b/src/tint/lang/wgsl/ast/identifier_expression.h
index a62e4b3..2666961 100644
--- a/src/tint/lang/wgsl/ast/identifier_expression.h
+++ b/src/tint/lang/wgsl/ast/identifier_expression.h
@@ -32,7 +32,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param identifier the identifier
-    IdentifierExpression(ProgramID pid,
+    IdentifierExpression(GenerationID pid,
                          NodeID nid,
                          const Source& src,
                          const Identifier* identifier);
diff --git a/src/tint/lang/wgsl/ast/identifier_expression_test.cc b/src/tint/lang/wgsl/ast/identifier_expression_test.cc
index 5fc21df..a37f6c2 100644
--- a/src/tint/lang/wgsl/ast/identifier_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/identifier_expression_test.cc
@@ -53,7 +53,7 @@
         "internal compiler error");
 }
 
-TEST_F(IdentifierExpressionTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(IdentifierExpressionTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/identifier_test.cc b/src/tint/lang/wgsl/ast/identifier_test.cc
index 45e6760..e1771d1 100644
--- a/src/tint/lang/wgsl/ast/identifier_test.cc
+++ b/src/tint/lang/wgsl/ast/identifier_test.cc
@@ -48,7 +48,7 @@
         "internal compiler error");
 }
 
-TEST_F(IdentifierTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(IdentifierTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/if_statement.cc b/src/tint/lang/wgsl/ast/if_statement.cc
index 161dccc..dae50c4 100644
--- a/src/tint/lang/wgsl/ast/if_statement.cc
+++ b/src/tint/lang/wgsl/ast/if_statement.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-IfStatement::IfStatement(ProgramID pid,
+IfStatement::IfStatement(GenerationID pid,
                          NodeID nid,
                          const Source& src,
                          const Expression* cond,
@@ -33,16 +33,16 @@
       else_statement(else_stmt),
       attributes(std::move(attrs)) {
     TINT_ASSERT(AST, condition);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, condition, generation_id);
     TINT_ASSERT(AST, body);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
     if (else_statement) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, else_statement, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, else_statement, generation_id);
         TINT_ASSERT(AST, (else_statement->IsAnyOf<IfStatement, BlockStatement>()));
     }
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/if_statement.h b/src/tint/lang/wgsl/ast/if_statement.h
index 70bd758..1f5c678 100644
--- a/src/tint/lang/wgsl/ast/if_statement.h
+++ b/src/tint/lang/wgsl/ast/if_statement.h
@@ -33,7 +33,7 @@
     /// @param body the if body
     /// @param else_stmt the else statement, or nullptr
     /// @param attributes the if statement attributes
-    IfStatement(ProgramID pid,
+    IfStatement(GenerationID pid,
                 NodeID nid,
                 const Source& src,
                 const Expression* condition,
diff --git a/src/tint/lang/wgsl/ast/if_statement_test.cc b/src/tint/lang/wgsl/ast/if_statement_test.cc
index e231f1c..957ae7f 100644
--- a/src/tint/lang/wgsl/ast/if_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/if_statement_test.cc
@@ -73,7 +73,7 @@
         "internal compiler error");
 }
 
-TEST_F(IfStatementTest, Assert_DifferentProgramID_Cond) {
+TEST_F(IfStatementTest, Assert_DifferentGenerationID_Cond) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -83,7 +83,7 @@
         "internal compiler error");
 }
 
-TEST_F(IfStatementTest, Assert_DifferentProgramID_Body) {
+TEST_F(IfStatementTest, Assert_DifferentGenerationID_Body) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -93,7 +93,7 @@
         "internal compiler error");
 }
 
-TEST_F(IfStatementTest, Assert_DifferentProgramID_ElseStatement) {
+TEST_F(IfStatementTest, Assert_DifferentGenerationID_ElseStatement) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/increment_decrement_statement.cc b/src/tint/lang/wgsl/ast/increment_decrement_statement.cc
index ddba98f..fc0bc29 100644
--- a/src/tint/lang/wgsl/ast/increment_decrement_statement.cc
+++ b/src/tint/lang/wgsl/ast/increment_decrement_statement.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-IncrementDecrementStatement::IncrementDecrementStatement(ProgramID pid,
+IncrementDecrementStatement::IncrementDecrementStatement(GenerationID pid,
                                                          NodeID nid,
                                                          const Source& src,
                                                          const Expression* l,
                                                          bool inc)
     : Base(pid, nid, src), lhs(l), increment(inc) {
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, lhs, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, lhs, generation_id);
 }
 
 IncrementDecrementStatement::~IncrementDecrementStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/increment_decrement_statement.h b/src/tint/lang/wgsl/ast/increment_decrement_statement.h
index d920528..b1b4d66 100644
--- a/src/tint/lang/wgsl/ast/increment_decrement_statement.h
+++ b/src/tint/lang/wgsl/ast/increment_decrement_statement.h
@@ -30,7 +30,7 @@
     /// @param src the source of this node
     /// @param lhs the LHS expression
     /// @param inc `true` for increment, `false` for decrement
-    IncrementDecrementStatement(ProgramID pid,
+    IncrementDecrementStatement(GenerationID pid,
                                 NodeID nid,
                                 const Source& src,
                                 const Expression* lhs,
diff --git a/src/tint/lang/wgsl/ast/increment_decrement_statement_test.cc b/src/tint/lang/wgsl/ast/increment_decrement_statement_test.cc
index fa6f61d..d94ea9f 100644
--- a/src/tint/lang/wgsl/ast/increment_decrement_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/increment_decrement_statement_test.cc
@@ -53,7 +53,7 @@
     EXPECT_FALSE(i->increment);
 }
 
-TEST_F(IncrementDecrementStatementTest, Assert_DifferentProgramID_Expr) {
+TEST_F(IncrementDecrementStatementTest, Assert_DifferentGenerationID_Expr) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/index_accessor_expression.cc b/src/tint/lang/wgsl/ast/index_accessor_expression.cc
index c245f22..456f635 100644
--- a/src/tint/lang/wgsl/ast/index_accessor_expression.cc
+++ b/src/tint/lang/wgsl/ast/index_accessor_expression.cc
@@ -20,14 +20,14 @@
 
 namespace tint::ast {
 
-IndexAccessorExpression::IndexAccessorExpression(ProgramID pid,
+IndexAccessorExpression::IndexAccessorExpression(GenerationID pid,
                                                  NodeID nid,
                                                  const Source& src,
                                                  const Expression* obj,
                                                  const Expression* idx)
     : Base(pid, nid, src, obj), index(idx) {
     TINT_ASSERT(AST, idx);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, idx, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, idx, generation_id);
 }
 
 IndexAccessorExpression::~IndexAccessorExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/index_accessor_expression.h b/src/tint/lang/wgsl/ast/index_accessor_expression.h
index 20ff4bd..f1d58e0 100644
--- a/src/tint/lang/wgsl/ast/index_accessor_expression.h
+++ b/src/tint/lang/wgsl/ast/index_accessor_expression.h
@@ -29,7 +29,7 @@
     /// @param source the index accessor source
     /// @param obj the object
     /// @param idx the index expression
-    IndexAccessorExpression(ProgramID pid,
+    IndexAccessorExpression(GenerationID pid,
                             NodeID nid,
                             const Source& source,
                             const Expression* obj,
diff --git a/src/tint/lang/wgsl/ast/index_accessor_expression_test.cc b/src/tint/lang/wgsl/ast/index_accessor_expression_test.cc
index 8177109..649ec3f 100644
--- a/src/tint/lang/wgsl/ast/index_accessor_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/index_accessor_expression_test.cc
@@ -65,7 +65,7 @@
         "internal compiler error");
 }
 
-TEST_F(IndexAccessorExpressionTest, Assert_DifferentProgramID_Array) {
+TEST_F(IndexAccessorExpressionTest, Assert_DifferentGenerationID_Array) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -75,7 +75,7 @@
         "internal compiler error");
 }
 
-TEST_F(IndexAccessorExpressionTest, Assert_DifferentProgramID_Index) {
+TEST_F(IndexAccessorExpressionTest, Assert_DifferentGenerationID_Index) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/index_attribute.cc b/src/tint/lang/wgsl/ast/index_attribute.cc
index ade0786..1d45c6e 100644
--- a/src/tint/lang/wgsl/ast/index_attribute.cc
+++ b/src/tint/lang/wgsl/ast/index_attribute.cc
@@ -22,7 +22,10 @@
 
 namespace tint::ast {
 
-IndexAttribute::IndexAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* exp)
+IndexAttribute::IndexAttribute(GenerationID pid,
+                               NodeID nid,
+                               const Source& src,
+                               const Expression* exp)
     : Base(pid, nid, src), expr(exp) {}
 
 IndexAttribute::~IndexAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/index_attribute.h b/src/tint/lang/wgsl/ast/index_attribute.h
index 8c8863b..5e5b8d0 100644
--- a/src/tint/lang/wgsl/ast/index_attribute.h
+++ b/src/tint/lang/wgsl/ast/index_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the numeric id expression
-    IndexAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    IndexAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* expr);
     ~IndexAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/int_literal_expression.cc b/src/tint/lang/wgsl/ast/int_literal_expression.cc
index bc26965..40100f2 100644
--- a/src/tint/lang/wgsl/ast/int_literal_expression.cc
+++ b/src/tint/lang/wgsl/ast/int_literal_expression.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-IntLiteralExpression::IntLiteralExpression(ProgramID pid,
+IntLiteralExpression::IntLiteralExpression(GenerationID pid,
                                            NodeID nid,
                                            const Source& src,
                                            int64_t val,
diff --git a/src/tint/lang/wgsl/ast/int_literal_expression.h b/src/tint/lang/wgsl/ast/int_literal_expression.h
index 28e0c75..c694305 100644
--- a/src/tint/lang/wgsl/ast/int_literal_expression.h
+++ b/src/tint/lang/wgsl/ast/int_literal_expression.h
@@ -38,7 +38,7 @@
     /// @param src the source of this node
     /// @param val the literal value
     /// @param suf the literal suffix
-    IntLiteralExpression(ProgramID pid, NodeID nid, const Source& src, int64_t val, Suffix suf);
+    IntLiteralExpression(GenerationID pid, NodeID nid, const Source& src, int64_t val, Suffix suf);
 
     ~IntLiteralExpression() override;
 
diff --git a/src/tint/lang/wgsl/ast/internal_attribute.cc b/src/tint/lang/wgsl/ast/internal_attribute.cc
index 72a6249..785d883 100644
--- a/src/tint/lang/wgsl/ast/internal_attribute.cc
+++ b/src/tint/lang/wgsl/ast/internal_attribute.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-InternalAttribute::InternalAttribute(ProgramID pid,
+InternalAttribute::InternalAttribute(GenerationID pid,
                                      NodeID nid,
                                      utils::VectorRef<const IdentifierExpression*> deps)
     : Base(pid, nid, Source{}), dependencies(std::move(deps)) {}
diff --git a/src/tint/lang/wgsl/ast/internal_attribute.h b/src/tint/lang/wgsl/ast/internal_attribute.h
index 8915a52..5005714 100644
--- a/src/tint/lang/wgsl/ast/internal_attribute.h
+++ b/src/tint/lang/wgsl/ast/internal_attribute.h
@@ -33,10 +33,10 @@
 class InternalAttribute : public utils::Castable<InternalAttribute, Attribute> {
   public:
     /// Constructor
-    /// @param program_id the identifier of the program that owns this node
+    /// @param generation_id the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param deps a list of identifiers that this attribute is dependent on
-    InternalAttribute(ProgramID program_id,
+    InternalAttribute(GenerationID generation_id,
                       NodeID nid,
                       utils::VectorRef<const IdentifierExpression*> deps);
 
diff --git a/src/tint/lang/wgsl/ast/interpolate_attribute.cc b/src/tint/lang/wgsl/ast/interpolate_attribute.cc
index d717828..e927fa6 100644
--- a/src/tint/lang/wgsl/ast/interpolate_attribute.cc
+++ b/src/tint/lang/wgsl/ast/interpolate_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-InterpolateAttribute::InterpolateAttribute(ProgramID pid,
+InterpolateAttribute::InterpolateAttribute(GenerationID pid,
                                            NodeID nid,
                                            const Source& src,
                                            const Expression* ty,
diff --git a/src/tint/lang/wgsl/ast/interpolate_attribute.h b/src/tint/lang/wgsl/ast/interpolate_attribute.h
index e8c1475..e7ad97d 100644
--- a/src/tint/lang/wgsl/ast/interpolate_attribute.h
+++ b/src/tint/lang/wgsl/ast/interpolate_attribute.h
@@ -35,7 +35,7 @@
     /// @param src the source of this node
     /// @param type the interpolation type
     /// @param sampling the interpolation sampling
-    InterpolateAttribute(ProgramID pid,
+    InterpolateAttribute(GenerationID pid,
                          NodeID nid,
                          const Source& src,
                          const Expression* type,
diff --git a/src/tint/lang/wgsl/ast/invariant_attribute.cc b/src/tint/lang/wgsl/ast/invariant_attribute.cc
index ab9b071..6581fed 100644
--- a/src/tint/lang/wgsl/ast/invariant_attribute.cc
+++ b/src/tint/lang/wgsl/ast/invariant_attribute.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-InvariantAttribute::InvariantAttribute(ProgramID pid, NodeID nid, const Source& src)
+InvariantAttribute::InvariantAttribute(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 InvariantAttribute::~InvariantAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/invariant_attribute.h b/src/tint/lang/wgsl/ast/invariant_attribute.h
index c8bdb4f..b893f65 100644
--- a/src/tint/lang/wgsl/ast/invariant_attribute.h
+++ b/src/tint/lang/wgsl/ast/invariant_attribute.h
@@ -28,7 +28,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    InvariantAttribute(ProgramID pid, NodeID nid, const Source& src);
+    InvariantAttribute(GenerationID pid, NodeID nid, const Source& src);
     ~InvariantAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/let.cc b/src/tint/lang/wgsl/ast/let.cc
index a23c098..ab2becf 100644
--- a/src/tint/lang/wgsl/ast/let.cc
+++ b/src/tint/lang/wgsl/ast/let.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Let::Let(ProgramID pid,
+Let::Let(GenerationID pid,
          NodeID nid,
          const Source& src,
          const Identifier* n,
diff --git a/src/tint/lang/wgsl/ast/let.h b/src/tint/lang/wgsl/ast/let.h
index ecc119d..45c0f35 100644
--- a/src/tint/lang/wgsl/ast/let.h
+++ b/src/tint/lang/wgsl/ast/let.h
@@ -37,7 +37,7 @@
     /// @param type the declared variable type
     /// @param initializer the initializer expression
     /// @param attributes the variable attributes
-    Let(ProgramID pid,
+    Let(GenerationID pid,
         NodeID nid,
         const Source& source,
         const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/literal_expression.cc b/src/tint/lang/wgsl/ast/literal_expression.cc
index df85321..5b72b37 100644
--- a/src/tint/lang/wgsl/ast/literal_expression.cc
+++ b/src/tint/lang/wgsl/ast/literal_expression.cc
@@ -18,7 +18,7 @@
 
 namespace tint::ast {
 
-LiteralExpression::LiteralExpression(ProgramID pid, NodeID nid, const Source& src)
+LiteralExpression::LiteralExpression(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 LiteralExpression::~LiteralExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/literal_expression.h b/src/tint/lang/wgsl/ast/literal_expression.h
index 9036f9d..03dbcc2 100644
--- a/src/tint/lang/wgsl/ast/literal_expression.h
+++ b/src/tint/lang/wgsl/ast/literal_expression.h
@@ -31,7 +31,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the input source
-    LiteralExpression(ProgramID pid, NodeID nid, const Source& src);
+    LiteralExpression(GenerationID pid, NodeID nid, const Source& src);
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/location_attribute.cc b/src/tint/lang/wgsl/ast/location_attribute.cc
index da991d0..708884f 100644
--- a/src/tint/lang/wgsl/ast/location_attribute.cc
+++ b/src/tint/lang/wgsl/ast/location_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-LocationAttribute::LocationAttribute(ProgramID pid,
+LocationAttribute::LocationAttribute(GenerationID pid,
                                      NodeID nid,
                                      const Source& src,
                                      const Expression* exp)
diff --git a/src/tint/lang/wgsl/ast/location_attribute.h b/src/tint/lang/wgsl/ast/location_attribute.h
index 949e2a6..5316b8a 100644
--- a/src/tint/lang/wgsl/ast/location_attribute.h
+++ b/src/tint/lang/wgsl/ast/location_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the location expression
-    LocationAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    LocationAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* expr);
     ~LocationAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/loop_statement.cc b/src/tint/lang/wgsl/ast/loop_statement.cc
index 8743743..4928eb9 100644
--- a/src/tint/lang/wgsl/ast/loop_statement.cc
+++ b/src/tint/lang/wgsl/ast/loop_statement.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-LoopStatement::LoopStatement(ProgramID pid,
+LoopStatement::LoopStatement(GenerationID pid,
                              NodeID nid,
                              const Source& src,
                              const BlockStatement* b,
@@ -30,11 +30,11 @@
                              utils::VectorRef<const ast::Attribute*> attrs)
     : Base(pid, nid, src), body(b), continuing(cont), attributes(std::move(attrs)) {
     TINT_ASSERT(AST, body);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, continuing, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, continuing, generation_id);
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/loop_statement.h b/src/tint/lang/wgsl/ast/loop_statement.h
index 083c38e..491b14e 100644
--- a/src/tint/lang/wgsl/ast/loop_statement.h
+++ b/src/tint/lang/wgsl/ast/loop_statement.h
@@ -29,7 +29,7 @@
     /// @param body the body statements
     /// @param continuing the continuing statements
     /// @param attributes the while statement attributes
-    LoopStatement(ProgramID pid,
+    LoopStatement(GenerationID pid,
                   NodeID nid,
                   const Source& source,
                   const BlockStatement* body,
diff --git a/src/tint/lang/wgsl/ast/loop_statement_test.cc b/src/tint/lang/wgsl/ast/loop_statement_test.cc
index 2ca171d..2fc6c51 100644
--- a/src/tint/lang/wgsl/ast/loop_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/loop_statement_test.cc
@@ -90,7 +90,7 @@
         "internal compiler error");
 }
 
-TEST_F(LoopStatementTest, Assert_DifferentProgramID_Body) {
+TEST_F(LoopStatementTest, Assert_DifferentGenerationID_Body) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -100,7 +100,7 @@
         "internal compiler error");
 }
 
-TEST_F(LoopStatementTest, Assert_DifferentProgramID_Continuing) {
+TEST_F(LoopStatementTest, Assert_DifferentGenerationID_Continuing) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/member_accessor_expression.cc b/src/tint/lang/wgsl/ast/member_accessor_expression.cc
index 7b10005..4fc6f21 100644
--- a/src/tint/lang/wgsl/ast/member_accessor_expression.cc
+++ b/src/tint/lang/wgsl/ast/member_accessor_expression.cc
@@ -20,14 +20,14 @@
 
 namespace tint::ast {
 
-MemberAccessorExpression::MemberAccessorExpression(ProgramID pid,
+MemberAccessorExpression::MemberAccessorExpression(GenerationID pid,
                                                    NodeID nid,
                                                    const Source& src,
                                                    const Expression* obj,
                                                    const Identifier* mem)
     : Base(pid, nid, src, obj), member(mem) {
     TINT_ASSERT(AST, member);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, member, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, member, generation_id);
 
     // It is currently invalid for a structure to hold a templated member
     if (member) {
diff --git a/src/tint/lang/wgsl/ast/member_accessor_expression.h b/src/tint/lang/wgsl/ast/member_accessor_expression.h
index 4d34fb1..75bf153 100644
--- a/src/tint/lang/wgsl/ast/member_accessor_expression.h
+++ b/src/tint/lang/wgsl/ast/member_accessor_expression.h
@@ -30,7 +30,7 @@
     /// @param source the member accessor expression source
     /// @param object the object
     /// @param member the member
-    MemberAccessorExpression(ProgramID pid,
+    MemberAccessorExpression(GenerationID pid,
                              NodeID nid,
                              const Source& source,
                              const Expression* object,
diff --git a/src/tint/lang/wgsl/ast/member_accessor_expression_test.cc b/src/tint/lang/wgsl/ast/member_accessor_expression_test.cc
index 3f1a4bf..ab3dca9 100644
--- a/src/tint/lang/wgsl/ast/member_accessor_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/member_accessor_expression_test.cc
@@ -60,7 +60,7 @@
         "internal compiler error");
 }
 
-TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Struct) {
+TEST_F(MemberAccessorExpressionTest, Assert_DifferentGenerationID_Struct) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -70,7 +70,7 @@
         "internal compiler error");
 }
 
-TEST_F(MemberAccessorExpressionTest, Assert_DifferentProgramID_Member) {
+TEST_F(MemberAccessorExpressionTest, Assert_DifferentGenerationID_Member) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/module.cc b/src/tint/lang/wgsl/ast/module.cc
index 3253354..1a51b59 100644
--- a/src/tint/lang/wgsl/ast/module.cc
+++ b/src/tint/lang/wgsl/ast/module.cc
@@ -24,9 +24,9 @@
 
 namespace tint::ast {
 
-Module::Module(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
+Module::Module(GenerationID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
 
-Module::Module(ProgramID pid,
+Module::Module(GenerationID pid,
                NodeID nid,
                const Source& src,
                utils::VectorRef<const Node*> global_decls)
@@ -61,27 +61,27 @@
     Switch(
         decl,  //
         [&](const TypeDecl* type) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, type, generation_id);
             type_decls_.Push(type);
         },
         [&](const Function* func) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, func, generation_id);
             functions_.Push(func);
         },
         [&](const Variable* var) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, var, generation_id);
             global_variables_.Push(var);
         },
         [&](const DiagnosticDirective* diagnostic) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, diagnostic, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, diagnostic, generation_id);
             diagnostic_directives_.Push(diagnostic);
         },
         [&](const Enable* enable) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, enable, generation_id);
             enables_.Push(enable);
         },
         [&](const ConstAssert* assertion) {
-            TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
+            TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, assertion, generation_id);
             const_asserts_.Push(assertion);
         },
         [&](Default) { TINT_ICE(AST, diags) << "Unknown global declaration type"; });
@@ -89,42 +89,42 @@
 
 void Module::AddDiagnosticDirective(const DiagnosticDirective* directive) {
     TINT_ASSERT(AST, directive);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, directive, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, directive, generation_id);
     global_declarations_.Push(directive);
     diagnostic_directives_.Push(directive);
 }
 
 void Module::AddEnable(const Enable* enable) {
     TINT_ASSERT(AST, enable);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, enable, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, enable, generation_id);
     global_declarations_.Push(enable);
     enables_.Push(enable);
 }
 
 void Module::AddGlobalVariable(const Variable* var) {
     TINT_ASSERT(AST, var);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, var, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, var, generation_id);
     global_variables_.Push(var);
     global_declarations_.Push(var);
 }
 
 void Module::AddConstAssert(const ConstAssert* assertion) {
     TINT_ASSERT(AST, assertion);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, assertion, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, assertion, generation_id);
     const_asserts_.Push(assertion);
     global_declarations_.Push(assertion);
 }
 
 void Module::AddTypeDecl(const TypeDecl* type) {
     TINT_ASSERT(AST, type);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, type, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, type, generation_id);
     type_decls_.Push(type);
     global_declarations_.Push(type);
 }
 
 void Module::AddFunction(const Function* func) {
     TINT_ASSERT(AST, func);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, func, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, func, generation_id);
     functions_.Push(func);
     global_declarations_.Push(func);
 }
diff --git a/src/tint/lang/wgsl/ast/module.h b/src/tint/lang/wgsl/ast/module.h
index ef838d6..09633df 100644
--- a/src/tint/lang/wgsl/ast/module.h
+++ b/src/tint/lang/wgsl/ast/module.h
@@ -35,7 +35,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    Module(ProgramID pid, NodeID nid, const Source& src);
+    Module(GenerationID pid, NodeID nid, const Source& src);
 
     /// Constructor
     /// @param pid the identifier of the program that owns this node
@@ -43,7 +43,7 @@
     /// @param src the source of this node
     /// @param global_decls the list of global types, functions, and variables, in
     /// the order they were declared in the source program
-    Module(ProgramID pid,
+    Module(GenerationID pid,
            NodeID nid,
            const Source& src,
            utils::VectorRef<const Node*> global_decls);
diff --git a/src/tint/lang/wgsl/ast/module_test.cc b/src/tint/lang/wgsl/ast/module_test.cc
index 855eac1..6bf3b7d 100644
--- a/src/tint/lang/wgsl/ast/module_test.cc
+++ b/src/tint/lang/wgsl/ast/module_test.cc
@@ -56,7 +56,7 @@
         "internal compiler error");
 }
 
-TEST_F(ModuleTest, Assert_DifferentProgramID_Function) {
+TEST_F(ModuleTest, Assert_DifferentGenerationID_Function) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -67,7 +67,7 @@
         "internal compiler error");
 }
 
-TEST_F(ModuleTest, Assert_DifferentProgramID_GlobalVariable) {
+TEST_F(ModuleTest, Assert_DifferentGenerationID_GlobalVariable) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/must_use_attribute.cc b/src/tint/lang/wgsl/ast/must_use_attribute.cc
index 0506e96..35b4fdb 100644
--- a/src/tint/lang/wgsl/ast/must_use_attribute.cc
+++ b/src/tint/lang/wgsl/ast/must_use_attribute.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-MustUseAttribute::MustUseAttribute(ProgramID pid, NodeID nid, const Source& src)
+MustUseAttribute::MustUseAttribute(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 MustUseAttribute::~MustUseAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/must_use_attribute.h b/src/tint/lang/wgsl/ast/must_use_attribute.h
index 6cc0124..6a2bbd2 100644
--- a/src/tint/lang/wgsl/ast/must_use_attribute.h
+++ b/src/tint/lang/wgsl/ast/must_use_attribute.h
@@ -28,7 +28,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    MustUseAttribute(ProgramID pid, NodeID nid, const Source& src);
+    MustUseAttribute(GenerationID pid, NodeID nid, const Source& src);
     ~MustUseAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/node.cc b/src/tint/lang/wgsl/ast/node.cc
index 3384682..afba2fb 100644
--- a/src/tint/lang/wgsl/ast/node.cc
+++ b/src/tint/lang/wgsl/ast/node.cc
@@ -18,8 +18,8 @@
 
 namespace tint::ast {
 
-Node::Node(ProgramID pid, NodeID nid, const Source& src)
-    : program_id(pid), node_id(nid), source(src) {}
+Node::Node(GenerationID pid, NodeID nid, const Source& src)
+    : generation_id(pid), node_id(nid), source(src) {}
 
 Node::~Node() = default;
 
diff --git a/src/tint/lang/wgsl/ast/node.h b/src/tint/lang/wgsl/ast/node.h
index b812e13..e281a07 100644
--- a/src/tint/lang/wgsl/ast/node.h
+++ b/src/tint/lang/wgsl/ast/node.h
@@ -28,7 +28,7 @@
     ~Node() override;
 
     /// The identifier of the program that owns this node
-    const ProgramID program_id;
+    const GenerationID generation_id;
 
     /// The node identifier, unique for the program.
     const NodeID node_id;
@@ -41,7 +41,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the input source for the node
-    Node(ProgramID pid, NodeID nid, const Source& src);
+    Node(GenerationID pid, NodeID nid, const Source& src);
 
   private:
     Node(const Node&) = delete;
@@ -53,9 +53,9 @@
 namespace tint {
 
 /// @param node a pointer to an AST node
-/// @returns the ProgramID of the given AST node.
-inline ProgramID ProgramIDOf(const ast::Node* node) {
-    return node ? node->program_id : ProgramID();
+/// @returns the GenerationID of the given AST node.
+inline GenerationID GenerationIDOf(const ast::Node* node) {
+    return node ? node->generation_id : GenerationID();
 }
 
 }  // namespace tint
diff --git a/src/tint/lang/wgsl/ast/override.cc b/src/tint/lang/wgsl/ast/override.cc
index 09dcd08..89dd165 100644
--- a/src/tint/lang/wgsl/ast/override.cc
+++ b/src/tint/lang/wgsl/ast/override.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Override::Override(ProgramID pid,
+Override::Override(GenerationID pid,
                    NodeID nid,
                    const Source& src,
                    const Identifier* n,
diff --git a/src/tint/lang/wgsl/ast/override.h b/src/tint/lang/wgsl/ast/override.h
index bcedfbd..04b2213 100644
--- a/src/tint/lang/wgsl/ast/override.h
+++ b/src/tint/lang/wgsl/ast/override.h
@@ -40,7 +40,7 @@
     /// @param type the declared variable type
     /// @param initializer the initializer expression
     /// @param attributes the variable attributes
-    Override(ProgramID pid,
+    Override(GenerationID pid,
              NodeID nid,
              const Source& source,
              const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/parameter.cc b/src/tint/lang/wgsl/ast/parameter.cc
index 46120ac..0307de6 100644
--- a/src/tint/lang/wgsl/ast/parameter.cc
+++ b/src/tint/lang/wgsl/ast/parameter.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Parameter::Parameter(ProgramID pid,
+Parameter::Parameter(GenerationID pid,
                      NodeID nid,
                      const Source& src,
                      const Identifier* n,
diff --git a/src/tint/lang/wgsl/ast/parameter.h b/src/tint/lang/wgsl/ast/parameter.h
index 4ebe26b..f64ad4a 100644
--- a/src/tint/lang/wgsl/ast/parameter.h
+++ b/src/tint/lang/wgsl/ast/parameter.h
@@ -40,7 +40,7 @@
     /// @param name the variable name
     /// @param type the declared variable type
     /// @param attributes the variable attributes
-    Parameter(ProgramID pid,
+    Parameter(GenerationID pid,
               NodeID nid,
               const Source& source,
               const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/phony_expression.cc b/src/tint/lang/wgsl/ast/phony_expression.cc
index aced532..13205fc 100644
--- a/src/tint/lang/wgsl/ast/phony_expression.cc
+++ b/src/tint/lang/wgsl/ast/phony_expression.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-PhonyExpression::PhonyExpression(ProgramID pid, NodeID nid, const Source& src)
+PhonyExpression::PhonyExpression(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src) {}
 
 PhonyExpression::~PhonyExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/phony_expression.h b/src/tint/lang/wgsl/ast/phony_expression.h
index 067e237..6fc140d 100644
--- a/src/tint/lang/wgsl/ast/phony_expression.h
+++ b/src/tint/lang/wgsl/ast/phony_expression.h
@@ -27,7 +27,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    PhonyExpression(ProgramID pid, NodeID nid, const Source& src);
+    PhonyExpression(GenerationID pid, NodeID nid, const Source& src);
 
     /// Destructor
     ~PhonyExpression() override;
diff --git a/src/tint/lang/wgsl/ast/return_statement.cc b/src/tint/lang/wgsl/ast/return_statement.cc
index 8346695..ec3122e 100644
--- a/src/tint/lang/wgsl/ast/return_statement.cc
+++ b/src/tint/lang/wgsl/ast/return_statement.cc
@@ -20,15 +20,15 @@
 
 namespace tint::ast {
 
-ReturnStatement::ReturnStatement(ProgramID pid, NodeID nid, const Source& src)
+ReturnStatement::ReturnStatement(GenerationID pid, NodeID nid, const Source& src)
     : Base(pid, nid, src), value(nullptr) {}
 
-ReturnStatement::ReturnStatement(ProgramID pid,
+ReturnStatement::ReturnStatement(GenerationID pid,
                                  NodeID nid,
                                  const Source& src,
                                  const Expression* val)
     : Base(pid, nid, src), value(val) {
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, value, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, value, generation_id);
 }
 
 ReturnStatement::~ReturnStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/return_statement.h b/src/tint/lang/wgsl/ast/return_statement.h
index d5d3e40..05f19f8 100644
--- a/src/tint/lang/wgsl/ast/return_statement.h
+++ b/src/tint/lang/wgsl/ast/return_statement.h
@@ -27,14 +27,14 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
-    ReturnStatement(ProgramID pid, NodeID nid, const Source& src);
+    ReturnStatement(GenerationID pid, NodeID nid, const Source& src);
 
     /// Constructor
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param value the return value
-    ReturnStatement(ProgramID pid, NodeID nid, const Source& src, const Expression* value);
+    ReturnStatement(GenerationID pid, NodeID nid, const Source& src, const Expression* value);
 
     /// Destructor
     ~ReturnStatement() override;
diff --git a/src/tint/lang/wgsl/ast/return_statement_test.cc b/src/tint/lang/wgsl/ast/return_statement_test.cc
index 7e00c3b..b369a43 100644
--- a/src/tint/lang/wgsl/ast/return_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/return_statement_test.cc
@@ -52,7 +52,7 @@
     EXPECT_NE(r->value, nullptr);
 }
 
-TEST_F(ReturnStatementTest, Assert_DifferentProgramID_Expr) {
+TEST_F(ReturnStatementTest, Assert_DifferentGenerationID_Expr) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/stage_attribute.cc b/src/tint/lang/wgsl/ast/stage_attribute.cc
index 5ece799..fbec3f1 100644
--- a/src/tint/lang/wgsl/ast/stage_attribute.cc
+++ b/src/tint/lang/wgsl/ast/stage_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-StageAttribute::StageAttribute(ProgramID pid, NodeID nid, const Source& src, PipelineStage s)
+StageAttribute::StageAttribute(GenerationID pid, NodeID nid, const Source& src, PipelineStage s)
     : Base(pid, nid, src), stage(s) {}
 
 StageAttribute::~StageAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/stage_attribute.h b/src/tint/lang/wgsl/ast/stage_attribute.h
index 708e850..2f3d96b 100644
--- a/src/tint/lang/wgsl/ast/stage_attribute.h
+++ b/src/tint/lang/wgsl/ast/stage_attribute.h
@@ -30,7 +30,7 @@
     /// @param nid the unique node identifier
     /// @param stage the pipeline stage
     /// @param source the source of this attribute
-    StageAttribute(ProgramID pid, NodeID nid, const Source& source, PipelineStage stage);
+    StageAttribute(GenerationID pid, NodeID nid, const Source& source, PipelineStage stage);
     ~StageAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/statement.cc b/src/tint/lang/wgsl/ast/statement.cc
index 91bbc2f..840d00e 100644
--- a/src/tint/lang/wgsl/ast/statement.cc
+++ b/src/tint/lang/wgsl/ast/statement.cc
@@ -29,7 +29,7 @@
 
 namespace tint::ast {
 
-Statement::Statement(ProgramID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
+Statement::Statement(GenerationID pid, NodeID nid, const Source& src) : Base(pid, nid, src) {}
 
 Statement::~Statement() = default;
 
diff --git a/src/tint/lang/wgsl/ast/statement.h b/src/tint/lang/wgsl/ast/statement.h
index 9318fd0..d121469 100644
--- a/src/tint/lang/wgsl/ast/statement.h
+++ b/src/tint/lang/wgsl/ast/statement.h
@@ -34,7 +34,7 @@
     /// @param pid the identifier of the program that owns this node
     /// @param nid the unique node identifier
     /// @param src the source of the expression
-    Statement(ProgramID pid, NodeID nid, const Source& src);
+    Statement(GenerationID pid, NodeID nid, const Source& src);
 };
 
 }  // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/stride_attribute.cc b/src/tint/lang/wgsl/ast/stride_attribute.cc
index 54c5082..1414bc9 100644
--- a/src/tint/lang/wgsl/ast/stride_attribute.cc
+++ b/src/tint/lang/wgsl/ast/stride_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-StrideAttribute::StrideAttribute(ProgramID pid, NodeID nid, const Source& src, uint32_t s)
+StrideAttribute::StrideAttribute(GenerationID pid, NodeID nid, const Source& src, uint32_t s)
     : Base(pid, nid, src), stride(s) {}
 
 StrideAttribute::~StrideAttribute() = default;
diff --git a/src/tint/lang/wgsl/ast/stride_attribute.h b/src/tint/lang/wgsl/ast/stride_attribute.h
index d7875d8..27ff92c 100644
--- a/src/tint/lang/wgsl/ast/stride_attribute.h
+++ b/src/tint/lang/wgsl/ast/stride_attribute.h
@@ -31,7 +31,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param stride the stride value
-    StrideAttribute(ProgramID pid, NodeID nid, const Source& src, uint32_t stride);
+    StrideAttribute(GenerationID pid, NodeID nid, const Source& src, uint32_t stride);
     ~StrideAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/struct.cc b/src/tint/lang/wgsl/ast/struct.cc
index f7e0282..88b6b43 100644
--- a/src/tint/lang/wgsl/ast/struct.cc
+++ b/src/tint/lang/wgsl/ast/struct.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-Struct::Struct(ProgramID pid,
+Struct::Struct(GenerationID pid,
                NodeID nid,
                const Source& src,
                const Identifier* n,
@@ -31,11 +31,11 @@
     : Base(pid, nid, src, n), members(std::move(m)), attributes(std::move(attrs)) {
     for (auto* mem : members) {
         TINT_ASSERT(AST, mem);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, mem, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, mem, generation_id);
     }
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/struct.h b/src/tint/lang/wgsl/ast/struct.h
index 2da597e..74c0c31 100644
--- a/src/tint/lang/wgsl/ast/struct.h
+++ b/src/tint/lang/wgsl/ast/struct.h
@@ -35,7 +35,7 @@
     /// @param name The name of the structure
     /// @param members The struct members
     /// @param attributes The struct attributes
-    Struct(ProgramID pid,
+    Struct(GenerationID pid,
            NodeID nid,
            const Source& src,
            const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/struct_member.cc b/src/tint/lang/wgsl/ast/struct_member.cc
index c27401e..72fa6d2 100644
--- a/src/tint/lang/wgsl/ast/struct_member.cc
+++ b/src/tint/lang/wgsl/ast/struct_member.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-StructMember::StructMember(ProgramID pid,
+StructMember::StructMember(GenerationID pid,
                            NodeID nid,
                            const Source& src,
                            const Identifier* n,
@@ -35,7 +35,7 @@
     TINT_ASSERT(AST, type);
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/struct_member.h b/src/tint/lang/wgsl/ast/struct_member.h
index f8efe8b..5248219 100644
--- a/src/tint/lang/wgsl/ast/struct_member.h
+++ b/src/tint/lang/wgsl/ast/struct_member.h
@@ -37,7 +37,7 @@
     /// @param name The struct member name
     /// @param type The struct member type
     /// @param attributes The struct member attributes
-    StructMember(ProgramID pid,
+    StructMember(GenerationID pid,
                  NodeID nid,
                  const Source& src,
                  const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/struct_member_align_attribute.cc b/src/tint/lang/wgsl/ast/struct_member_align_attribute.cc
index e1c3bf1..0d29db1 100644
--- a/src/tint/lang/wgsl/ast/struct_member_align_attribute.cc
+++ b/src/tint/lang/wgsl/ast/struct_member_align_attribute.cc
@@ -23,7 +23,7 @@
 
 namespace tint::ast {
 
-StructMemberAlignAttribute::StructMemberAlignAttribute(ProgramID pid,
+StructMemberAlignAttribute::StructMemberAlignAttribute(GenerationID pid,
                                                        NodeID nid,
                                                        const Source& src,
                                                        const Expression* a)
diff --git a/src/tint/lang/wgsl/ast/struct_member_align_attribute.h b/src/tint/lang/wgsl/ast/struct_member_align_attribute.h
index 34e0f48..c396124 100644
--- a/src/tint/lang/wgsl/ast/struct_member_align_attribute.h
+++ b/src/tint/lang/wgsl/ast/struct_member_align_attribute.h
@@ -32,7 +32,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param align the align expression
-    StructMemberAlignAttribute(ProgramID pid,
+    StructMemberAlignAttribute(GenerationID pid,
                                NodeID nid,
                                const Source& src,
                                const Expression* align);
diff --git a/src/tint/lang/wgsl/ast/struct_member_offset_attribute.cc b/src/tint/lang/wgsl/ast/struct_member_offset_attribute.cc
index f060133..1317cfc 100644
--- a/src/tint/lang/wgsl/ast/struct_member_offset_attribute.cc
+++ b/src/tint/lang/wgsl/ast/struct_member_offset_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-StructMemberOffsetAttribute::StructMemberOffsetAttribute(ProgramID pid,
+StructMemberOffsetAttribute::StructMemberOffsetAttribute(GenerationID pid,
                                                          NodeID nid,
                                                          const Source& src,
                                                          const Expression* exp)
diff --git a/src/tint/lang/wgsl/ast/struct_member_offset_attribute.h b/src/tint/lang/wgsl/ast/struct_member_offset_attribute.h
index 2b9f2d9..8635cda 100644
--- a/src/tint/lang/wgsl/ast/struct_member_offset_attribute.h
+++ b/src/tint/lang/wgsl/ast/struct_member_offset_attribute.h
@@ -40,7 +40,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the offset expression
-    StructMemberOffsetAttribute(ProgramID pid,
+    StructMemberOffsetAttribute(GenerationID pid,
                                 NodeID nid,
                                 const Source& src,
                                 const Expression* expr);
diff --git a/src/tint/lang/wgsl/ast/struct_member_size_attribute.cc b/src/tint/lang/wgsl/ast/struct_member_size_attribute.cc
index 3306a35..154270c 100644
--- a/src/tint/lang/wgsl/ast/struct_member_size_attribute.cc
+++ b/src/tint/lang/wgsl/ast/struct_member_size_attribute.cc
@@ -23,7 +23,7 @@
 
 namespace tint::ast {
 
-StructMemberSizeAttribute::StructMemberSizeAttribute(ProgramID pid,
+StructMemberSizeAttribute::StructMemberSizeAttribute(GenerationID pid,
                                                      NodeID nid,
                                                      const Source& src,
                                                      const Expression* exp)
diff --git a/src/tint/lang/wgsl/ast/struct_member_size_attribute.h b/src/tint/lang/wgsl/ast/struct_member_size_attribute.h
index 5b818a2..ea23701 100644
--- a/src/tint/lang/wgsl/ast/struct_member_size_attribute.h
+++ b/src/tint/lang/wgsl/ast/struct_member_size_attribute.h
@@ -32,7 +32,10 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node
     /// @param expr the size expression
-    StructMemberSizeAttribute(ProgramID pid, NodeID nid, const Source& src, const Expression* expr);
+    StructMemberSizeAttribute(GenerationID pid,
+                              NodeID nid,
+                              const Source& src,
+                              const Expression* expr);
     ~StructMemberSizeAttribute() override;
 
     /// @returns the WGSL name for the attribute
diff --git a/src/tint/lang/wgsl/ast/struct_member_test.cc b/src/tint/lang/wgsl/ast/struct_member_test.cc
index 2b82094..564bb5a 100644
--- a/src/tint/lang/wgsl/ast/struct_member_test.cc
+++ b/src/tint/lang/wgsl/ast/struct_member_test.cc
@@ -72,7 +72,7 @@
         "internal compiler error");
 }
 
-TEST_F(StructMemberTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(StructMemberTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -82,7 +82,7 @@
         "internal compiler error");
 }
 
-TEST_F(StructMemberTest, Assert_DifferentProgramID_Attribute) {
+TEST_F(StructMemberTest, Assert_DifferentGenerationID_Attribute) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/struct_test.cc b/src/tint/lang/wgsl/ast/struct_test.cc
index 499723b..9e3472f 100644
--- a/src/tint/lang/wgsl/ast/struct_test.cc
+++ b/src/tint/lang/wgsl/ast/struct_test.cc
@@ -88,7 +88,7 @@
         "internal compiler error");
 }
 
-TEST_F(AstStructTest, Assert_DifferentProgramID_StructMember) {
+TEST_F(AstStructTest, Assert_DifferentGenerationID_StructMember) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -98,7 +98,7 @@
         "internal compiler error");
 }
 
-TEST_F(AstStructTest, Assert_DifferentProgramID_Attribute) {
+TEST_F(AstStructTest, Assert_DifferentGenerationID_Attribute) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/switch_statement.cc b/src/tint/lang/wgsl/ast/switch_statement.cc
index f7908ba..8646509 100644
--- a/src/tint/lang/wgsl/ast/switch_statement.cc
+++ b/src/tint/lang/wgsl/ast/switch_statement.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-SwitchStatement::SwitchStatement(ProgramID pid,
+SwitchStatement::SwitchStatement(GenerationID pid,
                                  NodeID nid,
                                  const Source& src,
                                  const Expression* cond,
@@ -35,18 +35,18 @@
       attributes(std::move(stmt_attrs)),
       body_attributes(std::move(body_attrs)) {
     TINT_ASSERT(AST, condition);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, condition, generation_id);
     for (auto* stmt : body) {
         TINT_ASSERT(AST, stmt);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, stmt, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, stmt, generation_id);
     }
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
     for (auto* attr : body_attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/switch_statement.h b/src/tint/lang/wgsl/ast/switch_statement.h
index ca958c5..c412cd2 100644
--- a/src/tint/lang/wgsl/ast/switch_statement.h
+++ b/src/tint/lang/wgsl/ast/switch_statement.h
@@ -31,7 +31,7 @@
     /// @param body the switch body
     /// @param stmt_attributes the switch statement attributes
     /// @param body_attributes the switch body attributes
-    SwitchStatement(ProgramID pid,
+    SwitchStatement(GenerationID pid,
                     NodeID nid,
                     const Source& src,
                     const Expression* condition,
diff --git a/src/tint/lang/wgsl/ast/switch_statement_test.cc b/src/tint/lang/wgsl/ast/switch_statement_test.cc
index a3846dc..5acf7c3 100644
--- a/src/tint/lang/wgsl/ast/switch_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/switch_statement_test.cc
@@ -98,7 +98,7 @@
         "internal compiler error");
 }
 
-TEST_F(SwitchStatementTest, Assert_DifferentProgramID_Condition) {
+TEST_F(SwitchStatementTest, Assert_DifferentGenerationID_Condition) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -116,7 +116,7 @@
         "internal compiler error");
 }
 
-TEST_F(SwitchStatementTest, Assert_DifferentProgramID_CaseStatement) {
+TEST_F(SwitchStatementTest, Assert_DifferentGenerationID_CaseStatement) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/templated_identifier.cc b/src/tint/lang/wgsl/ast/templated_identifier.cc
index 7155859..5f25b3f 100644
--- a/src/tint/lang/wgsl/ast/templated_identifier.cc
+++ b/src/tint/lang/wgsl/ast/templated_identifier.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-TemplatedIdentifier::TemplatedIdentifier(ProgramID pid,
+TemplatedIdentifier::TemplatedIdentifier(GenerationID pid,
                                          NodeID nid,
                                          const Source& src,
                                          const Symbol& sym,
@@ -31,10 +31,10 @@
     : Base(pid, nid, src, sym), arguments(std::move(args)), attributes(std::move(attrs)) {
     TINT_ASSERT(AST, !arguments.IsEmpty());  // Should have been an Identifier if this fires.
     for (auto* arg : arguments) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL(AST, arg, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL(AST, arg, generation_id);
     }
     for (auto* attr : attributes) {
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/templated_identifier.h b/src/tint/lang/wgsl/ast/templated_identifier.h
index 086e2cd..b29cea6 100644
--- a/src/tint/lang/wgsl/ast/templated_identifier.h
+++ b/src/tint/lang/wgsl/ast/templated_identifier.h
@@ -35,7 +35,7 @@
     /// @param sym the symbol for the identifier
     /// @param args the template arguments
     /// @param attrs the identifier attributes
-    TemplatedIdentifier(ProgramID pid,
+    TemplatedIdentifier(GenerationID pid,
                         NodeID nid,
                         const Source& src,
                         const Symbol& sym,
diff --git a/src/tint/lang/wgsl/ast/templated_identifier_test.cc b/src/tint/lang/wgsl/ast/templated_identifier_test.cc
index 01f243f..0431d66 100644
--- a/src/tint/lang/wgsl/ast/templated_identifier_test.cc
+++ b/src/tint/lang/wgsl/ast/templated_identifier_test.cc
@@ -60,7 +60,7 @@
         "internal compiler error");
 }
 
-TEST_F(TemplatedIdentifierTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(TemplatedIdentifierTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -70,7 +70,7 @@
         "internal compiler error");
 }
 
-TEST_F(TemplatedIdentifierTest, Assert_DifferentProgramID_TemplateArg) {
+TEST_F(TemplatedIdentifierTest, Assert_DifferentGenerationID_TemplateArg) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/transform/add_block_attribute.cc b/src/tint/lang/wgsl/ast/transform/add_block_attribute.cc
index 2301d95..39a04f6 100644
--- a/src/tint/lang/wgsl/ast/transform/add_block_attribute.cc
+++ b/src/tint/lang/wgsl/ast/transform/add_block_attribute.cc
@@ -101,7 +101,7 @@
     return Program(std::move(b));
 }
 
-AddBlockAttribute::BlockAttribute::BlockAttribute(ProgramID pid, NodeID nid)
+AddBlockAttribute::BlockAttribute::BlockAttribute(GenerationID pid, NodeID nid)
     : Base(pid, nid, utils::Empty) {}
 AddBlockAttribute::BlockAttribute::~BlockAttribute() = default;
 std::string AddBlockAttribute::BlockAttribute::InternalName() const {
diff --git a/src/tint/lang/wgsl/ast/transform/add_block_attribute.h b/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
index e083b6d..13708d4 100644
--- a/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
+++ b/src/tint/lang/wgsl/ast/transform/add_block_attribute.h
@@ -31,9 +31,9 @@
     class BlockAttribute final : public utils::Castable<BlockAttribute, InternalAttribute> {
       public:
         /// Constructor
-        /// @param program_id the identifier of the program that owns this node
+        /// @param generation_id the identifier of the program that owns this node
         /// @param nid the unique node identifier
-        BlockAttribute(ProgramID program_id, NodeID nid);
+        BlockAttribute(GenerationID generation_id, NodeID nid);
         /// Destructor
         ~BlockAttribute() override;
 
diff --git a/src/tint/lang/wgsl/ast/transform/calculate_array_length.cc b/src/tint/lang/wgsl/ast/transform/calculate_array_length.cc
index b7bd5ae..e3e3e65 100644
--- a/src/tint/lang/wgsl/ast/transform/calculate_array_length.cc
+++ b/src/tint/lang/wgsl/ast/transform/calculate_array_length.cc
@@ -71,7 +71,7 @@
 
 }  // namespace
 
-CalculateArrayLength::BufferSizeIntrinsic::BufferSizeIntrinsic(ProgramID pid, NodeID nid)
+CalculateArrayLength::BufferSizeIntrinsic::BufferSizeIntrinsic(GenerationID pid, NodeID nid)
     : Base(pid, nid, utils::Empty) {}
 CalculateArrayLength::BufferSizeIntrinsic::~BufferSizeIntrinsic() = default;
 std::string CalculateArrayLength::BufferSizeIntrinsic::InternalName() const {
diff --git a/src/tint/lang/wgsl/ast/transform/calculate_array_length.h b/src/tint/lang/wgsl/ast/transform/calculate_array_length.h
index c9139ff..3e4819b 100644
--- a/src/tint/lang/wgsl/ast/transform/calculate_array_length.h
+++ b/src/tint/lang/wgsl/ast/transform/calculate_array_length.h
@@ -40,9 +40,9 @@
         : public utils::Castable<BufferSizeIntrinsic, InternalAttribute> {
       public:
         /// Constructor
-        /// @param program_id the identifier of the program that owns this node
+        /// @param generation_id the identifier of the program that owns this node
         /// @param nid the unique node identifier
-        BufferSizeIntrinsic(ProgramID program_id, NodeID nid);
+        BufferSizeIntrinsic(GenerationID generation_id, NodeID nid);
         /// Destructor
         ~BufferSizeIntrinsic() override;
 
diff --git a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
index a7244a7..7683b11 100644
--- a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
@@ -180,7 +180,7 @@
     /// @param attr the input attribute
     /// @returns the builtin value of the attribute
     builtin::BuiltinValue BuiltinOf(const BuiltinAttribute* attr) {
-        if (attr->program_id == ctx.dst->ID()) {
+        if (attr->generation_id == ctx.dst->ID()) {
             // attr belongs to the target program.
             // Obtain the builtin value from #builtin_attrs.
             if (auto b = builtin_attrs.Get(attr)) {
diff --git a/src/tint/lang/wgsl/ast/transform/decompose_memory_access.cc b/src/tint/lang/wgsl/ast/transform/decompose_memory_access.cc
index 3968782..2f8ff1b 100644
--- a/src/tint/lang/wgsl/ast/transform/decompose_memory_access.cc
+++ b/src/tint/lang/wgsl/ast/transform/decompose_memory_access.cc
@@ -669,7 +669,7 @@
     }
 };
 
-DecomposeMemoryAccess::Intrinsic::Intrinsic(ProgramID pid,
+DecomposeMemoryAccess::Intrinsic::Intrinsic(GenerationID pid,
                                             NodeID nid,
                                             Op o,
                                             DataType ty,
diff --git a/src/tint/lang/wgsl/ast/transform/decompose_memory_access.h b/src/tint/lang/wgsl/ast/transform/decompose_memory_access.h
index 9b02195..0b5b940 100644
--- a/src/tint/lang/wgsl/ast/transform/decompose_memory_access.h
+++ b/src/tint/lang/wgsl/ast/transform/decompose_memory_access.h
@@ -81,7 +81,7 @@
         /// @param type the data type of the intrinsic
         /// @param address_space the address space of the buffer
         /// @param buffer the storage or uniform buffer identifier
-        Intrinsic(ProgramID pid,
+        Intrinsic(GenerationID pid,
                   NodeID nid,
                   Op o,
                   DataType type,
diff --git a/src/tint/lang/wgsl/ast/transform/spirv_atomic.cc b/src/tint/lang/wgsl/ast/transform/spirv_atomic.cc
index 2d66845..3c6601a 100644
--- a/src/tint/lang/wgsl/ast/transform/spirv_atomic.cc
+++ b/src/tint/lang/wgsl/ast/transform/spirv_atomic.cc
@@ -293,7 +293,7 @@
 SpirvAtomic::SpirvAtomic() = default;
 SpirvAtomic::~SpirvAtomic() = default;
 
-SpirvAtomic::Stub::Stub(ProgramID pid, NodeID nid, builtin::Function b)
+SpirvAtomic::Stub::Stub(GenerationID pid, NodeID nid, builtin::Function b)
     : Base(pid, nid, utils::Empty), builtin(b) {}
 SpirvAtomic::Stub::~Stub() = default;
 std::string SpirvAtomic::Stub::InternalName() const {
diff --git a/src/tint/lang/wgsl/ast/transform/spirv_atomic.h b/src/tint/lang/wgsl/ast/transform/spirv_atomic.h
index f5e9105..69d4bcd 100644
--- a/src/tint/lang/wgsl/ast/transform/spirv_atomic.h
+++ b/src/tint/lang/wgsl/ast/transform/spirv_atomic.h
@@ -46,7 +46,7 @@
         /// @param pid the identifier of the program that owns this node
         /// @param nid the unique node identifier
         /// @param builtin the atomic builtin this stub represents
-        Stub(ProgramID pid, NodeID nid, builtin::Function builtin);
+        Stub(GenerationID pid, NodeID nid, builtin::Function builtin);
         /// Destructor
         ~Stub() override;
 
diff --git a/src/tint/lang/wgsl/ast/transform/std140.cc b/src/tint/lang/wgsl/ast/transform/std140.cc
index beadeb8..2d8d17d 100644
--- a/src/tint/lang/wgsl/ast/transform/std140.cc
+++ b/src/tint/lang/wgsl/ast/transform/std140.cc
@@ -328,7 +328,7 @@
                 if (fork_std140) {
                     // Clone any members that have not already been cloned.
                     for (auto& member : members) {
-                        if (member->program_id == src->ID()) {
+                        if (member->generation_id == src->ID()) {
                             member = ctx.Clone(member);
                         }
                     }
diff --git a/src/tint/lang/wgsl/ast/type.cc b/src/tint/lang/wgsl/ast/type.cc
index 69d28eb..95e896a 100644
--- a/src/tint/lang/wgsl/ast/type.cc
+++ b/src/tint/lang/wgsl/ast/type.cc
@@ -17,8 +17,8 @@
 
 namespace tint {
 
-ProgramID ProgramIDOf(ast::Type type) {
-    return ProgramIDOf(type.expr);
+GenerationID GenerationIDOf(ast::Type type) {
+    return GenerationIDOf(type.expr);
 }
 
 }  // namespace tint
diff --git a/src/tint/lang/wgsl/ast/type.h b/src/tint/lang/wgsl/ast/type.h
index 4015081..bb6705e 100644
--- a/src/tint/lang/wgsl/ast/type.h
+++ b/src/tint/lang/wgsl/ast/type.h
@@ -15,7 +15,7 @@
 #ifndef SRC_TINT_LANG_WGSL_AST_TYPE_H_
 #define SRC_TINT_LANG_WGSL_AST_TYPE_H_
 
-#include "src/tint/program_id.h"
+#include "src/tint/utils/generation_id.h"
 
 // Forward declarations
 namespace tint::ast {
@@ -44,8 +44,8 @@
 namespace tint {
 
 /// @param type an AST type
-/// @returns the ProgramID of the given AST type.
-ProgramID ProgramIDOf(ast::Type type);
+/// @returns the GenerationID of the given AST type.
+GenerationID GenerationIDOf(ast::Type type);
 
 }  // namespace tint
 
diff --git a/src/tint/lang/wgsl/ast/type_decl.cc b/src/tint/lang/wgsl/ast/type_decl.cc
index 5bd9d26..0581f85 100644
--- a/src/tint/lang/wgsl/ast/type_decl.cc
+++ b/src/tint/lang/wgsl/ast/type_decl.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-TypeDecl::TypeDecl(ProgramID pid, NodeID nid, const Source& src, const Identifier* n)
+TypeDecl::TypeDecl(GenerationID pid, NodeID nid, const Source& src, const Identifier* n)
     : Base(pid, nid, src), name(n) {
     TINT_ASSERT(AST, name);
     if (name) {
diff --git a/src/tint/lang/wgsl/ast/type_decl.h b/src/tint/lang/wgsl/ast/type_decl.h
index 1414370..d270c00 100644
--- a/src/tint/lang/wgsl/ast/type_decl.h
+++ b/src/tint/lang/wgsl/ast/type_decl.h
@@ -32,7 +32,7 @@
     /// @param nid the unique node identifier
     /// @param src the source of this node for the import statement
     /// @param name The name of the type
-    TypeDecl(ProgramID pid, NodeID nid, const Source& src, const Identifier* name);
+    TypeDecl(GenerationID pid, NodeID nid, const Source& src, const Identifier* name);
 
     /// Destructor
     ~TypeDecl() override;
diff --git a/src/tint/lang/wgsl/ast/unary_op_expression.cc b/src/tint/lang/wgsl/ast/unary_op_expression.cc
index 15af482..9defa6b 100644
--- a/src/tint/lang/wgsl/ast/unary_op_expression.cc
+++ b/src/tint/lang/wgsl/ast/unary_op_expression.cc
@@ -20,14 +20,14 @@
 
 namespace tint::ast {
 
-UnaryOpExpression::UnaryOpExpression(ProgramID pid,
+UnaryOpExpression::UnaryOpExpression(GenerationID pid,
                                      NodeID nid,
                                      const Source& src,
                                      UnaryOp o,
                                      const Expression* e)
     : Base(pid, nid, src), op(o), expr(e) {
     TINT_ASSERT(AST, expr);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, expr, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, expr, generation_id);
 }
 
 UnaryOpExpression::~UnaryOpExpression() = default;
diff --git a/src/tint/lang/wgsl/ast/unary_op_expression.h b/src/tint/lang/wgsl/ast/unary_op_expression.h
index 22d70f5..2880928 100644
--- a/src/tint/lang/wgsl/ast/unary_op_expression.h
+++ b/src/tint/lang/wgsl/ast/unary_op_expression.h
@@ -29,7 +29,7 @@
     /// @param source the unary op expression source
     /// @param op the op
     /// @param expr the expr
-    UnaryOpExpression(ProgramID pid,
+    UnaryOpExpression(GenerationID pid,
                       NodeID nid,
                       const Source& source,
                       UnaryOp op,
diff --git a/src/tint/lang/wgsl/ast/unary_op_expression_test.cc b/src/tint/lang/wgsl/ast/unary_op_expression_test.cc
index 82b9764..b23a894 100644
--- a/src/tint/lang/wgsl/ast/unary_op_expression_test.cc
+++ b/src/tint/lang/wgsl/ast/unary_op_expression_test.cc
@@ -53,7 +53,7 @@
         "internal compiler error");
 }
 
-TEST_F(UnaryOpExpressionTest, Assert_DifferentProgramID_Expression) {
+TEST_F(UnaryOpExpressionTest, Assert_DifferentGenerationID_Expression) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/var.cc b/src/tint/lang/wgsl/ast/var.cc
index f86e88d..c953aae 100644
--- a/src/tint/lang/wgsl/ast/var.cc
+++ b/src/tint/lang/wgsl/ast/var.cc
@@ -20,7 +20,7 @@
 
 namespace tint::ast {
 
-Var::Var(ProgramID pid,
+Var::Var(GenerationID pid,
          NodeID nid,
          const Source& src,
          const Identifier* n,
diff --git a/src/tint/lang/wgsl/ast/var.h b/src/tint/lang/wgsl/ast/var.h
index d7a6770..87c94e5 100644
--- a/src/tint/lang/wgsl/ast/var.h
+++ b/src/tint/lang/wgsl/ast/var.h
@@ -51,7 +51,7 @@
     /// @param declared_access the declared access control
     /// @param initializer the initializer expression
     /// @param attributes the variable attributes
-    Var(ProgramID pid,
+    Var(GenerationID pid,
         NodeID nid,
         const Source& source,
         const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/variable.cc b/src/tint/lang/wgsl/ast/variable.cc
index d0eb80d..2bc8550 100644
--- a/src/tint/lang/wgsl/ast/variable.cc
+++ b/src/tint/lang/wgsl/ast/variable.cc
@@ -21,7 +21,7 @@
 
 namespace tint::ast {
 
-Variable::Variable(ProgramID pid,
+Variable::Variable(GenerationID pid,
                    NodeID nid,
                    const Source& src,
                    const Identifier* n,
@@ -33,7 +33,7 @@
     if (name) {
         TINT_ASSERT(AST, !name->Is<TemplatedIdentifier>());
     }
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, initializer, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, initializer, generation_id);
 }
 
 Variable::~Variable() = default;
diff --git a/src/tint/lang/wgsl/ast/variable.h b/src/tint/lang/wgsl/ast/variable.h
index 3d0b620..31e6a64 100644
--- a/src/tint/lang/wgsl/ast/variable.h
+++ b/src/tint/lang/wgsl/ast/variable.h
@@ -50,7 +50,7 @@
     /// @param type the declared variable type
     /// @param initializer the initializer expression
     /// @param attributes the variable attributes
-    Variable(ProgramID pid,
+    Variable(GenerationID pid,
              NodeID nid,
              const Source& src,
              const Identifier* name,
diff --git a/src/tint/lang/wgsl/ast/variable_decl_statement.cc b/src/tint/lang/wgsl/ast/variable_decl_statement.cc
index d2cc633..1f830e3 100644
--- a/src/tint/lang/wgsl/ast/variable_decl_statement.cc
+++ b/src/tint/lang/wgsl/ast/variable_decl_statement.cc
@@ -20,13 +20,13 @@
 
 namespace tint::ast {
 
-VariableDeclStatement::VariableDeclStatement(ProgramID pid,
+VariableDeclStatement::VariableDeclStatement(GenerationID pid,
                                              NodeID nid,
                                              const Source& src,
                                              const Variable* var)
     : Base(pid, nid, src), variable(var) {
     TINT_ASSERT(AST, variable);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, variable, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, variable, generation_id);
 }
 
 VariableDeclStatement::~VariableDeclStatement() = default;
diff --git a/src/tint/lang/wgsl/ast/variable_decl_statement.h b/src/tint/lang/wgsl/ast/variable_decl_statement.h
index e9b796d..f76622e 100644
--- a/src/tint/lang/wgsl/ast/variable_decl_statement.h
+++ b/src/tint/lang/wgsl/ast/variable_decl_statement.h
@@ -28,7 +28,7 @@
     /// @param nid the unique node identifier
     /// @param source the variable statement source
     /// @param variable the variable
-    VariableDeclStatement(ProgramID pid,
+    VariableDeclStatement(GenerationID pid,
                           NodeID nid,
                           const Source& source,
                           const Variable* variable);
diff --git a/src/tint/lang/wgsl/ast/variable_decl_statement_test.cc b/src/tint/lang/wgsl/ast/variable_decl_statement_test.cc
index df8a033..ae80f12 100644
--- a/src/tint/lang/wgsl/ast/variable_decl_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/variable_decl_statement_test.cc
@@ -54,7 +54,7 @@
         "internal compiler error");
 }
 
-TEST_F(VariableDeclStatementTest, Assert_DifferentProgramID_Variable) {
+TEST_F(VariableDeclStatementTest, Assert_DifferentGenerationID_Variable) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/variable_test.cc b/src/tint/lang/wgsl/ast/variable_test.cc
index 54c5c14..6981b61 100644
--- a/src/tint/lang/wgsl/ast/variable_test.cc
+++ b/src/tint/lang/wgsl/ast/variable_test.cc
@@ -73,7 +73,7 @@
         "internal compiler error");
 }
 
-TEST_F(VariableTest, Assert_DifferentProgramID_Symbol) {
+TEST_F(VariableTest, Assert_DifferentGenerationID_Symbol) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -83,7 +83,7 @@
         "internal compiler error");
 }
 
-TEST_F(VariableTest, Assert_DifferentProgramID_Initializer) {
+TEST_F(VariableTest, Assert_DifferentGenerationID_Initializer) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/while_statement.cc b/src/tint/lang/wgsl/ast/while_statement.cc
index ac1bd0a..25b736c 100644
--- a/src/tint/lang/wgsl/ast/while_statement.cc
+++ b/src/tint/lang/wgsl/ast/while_statement.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-WhileStatement::WhileStatement(ProgramID pid,
+WhileStatement::WhileStatement(GenerationID pid,
                                NodeID nid,
                                const Source& src,
                                const Expression* cond,
@@ -32,11 +32,11 @@
     TINT_ASSERT(AST, cond);
     TINT_ASSERT(AST, body);
 
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, condition, program_id);
-    TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, condition, generation_id);
+    TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, body, generation_id);
     for (auto* attr : attributes) {
         TINT_ASSERT(AST, attr);
-        TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id);
+        TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(AST, attr, generation_id);
     }
 }
 
diff --git a/src/tint/lang/wgsl/ast/while_statement.h b/src/tint/lang/wgsl/ast/while_statement.h
index 9d824c7..d87bdb6 100644
--- a/src/tint/lang/wgsl/ast/while_statement.h
+++ b/src/tint/lang/wgsl/ast/while_statement.h
@@ -31,7 +31,7 @@
     /// @param condition the optional loop condition expression
     /// @param body the loop body
     /// @param attributes the while statement attributes
-    WhileStatement(ProgramID pid,
+    WhileStatement(GenerationID pid,
                    NodeID nid,
                    const Source& source,
                    const Expression* condition,
diff --git a/src/tint/lang/wgsl/ast/while_statement_test.cc b/src/tint/lang/wgsl/ast/while_statement_test.cc
index f22edc9..59b55cc 100644
--- a/src/tint/lang/wgsl/ast/while_statement_test.cc
+++ b/src/tint/lang/wgsl/ast/while_statement_test.cc
@@ -72,7 +72,7 @@
         "internal compiler error");
 }
 
-TEST_F(WhileStatementTest, Assert_DifferentProgramID_Condition) {
+TEST_F(WhileStatementTest, Assert_DifferentGenerationID_Condition) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
@@ -82,7 +82,7 @@
         "internal compiler error");
 }
 
-TEST_F(WhileStatementTest, Assert_DifferentProgramID_Body) {
+TEST_F(WhileStatementTest, Assert_DifferentGenerationID_Body) {
     EXPECT_FATAL_FAILURE(
         {
             ProgramBuilder b1;
diff --git a/src/tint/lang/wgsl/ast/workgroup_attribute.cc b/src/tint/lang/wgsl/ast/workgroup_attribute.cc
index a0747d0..dbbc45a 100644
--- a/src/tint/lang/wgsl/ast/workgroup_attribute.cc
+++ b/src/tint/lang/wgsl/ast/workgroup_attribute.cc
@@ -22,7 +22,7 @@
 
 namespace tint::ast {
 
-WorkgroupAttribute::WorkgroupAttribute(ProgramID pid,
+WorkgroupAttribute::WorkgroupAttribute(GenerationID pid,
                                        NodeID nid,
                                        const Source& src,
                                        const Expression* x_,
diff --git a/src/tint/lang/wgsl/ast/workgroup_attribute.h b/src/tint/lang/wgsl/ast/workgroup_attribute.h
index 593a6bc..a90bb5f 100644
--- a/src/tint/lang/wgsl/ast/workgroup_attribute.h
+++ b/src/tint/lang/wgsl/ast/workgroup_attribute.h
@@ -37,7 +37,7 @@
     /// @param x the workgroup x dimension expression
     /// @param y the optional workgroup y dimension expression
     /// @param z the optional workgroup z dimension expression
-    WorkgroupAttribute(ProgramID pid,
+    WorkgroupAttribute(GenerationID pid,
                        NodeID nid,
                        const Source& src,
                        const Expression* x,
diff --git a/src/tint/lang/wgsl/program/program.h b/src/tint/lang/wgsl/program/program.h
index 52b672d..1067cea 100644
--- a/src/tint/lang/wgsl/program/program.h
+++ b/src/tint/lang/wgsl/program/program.h
@@ -22,7 +22,7 @@
 #include "src/tint/lang/core/type/manager.h"
 #include "src/tint/lang/wgsl/ast/function.h"
 #include "src/tint/lang/wgsl/sem/info.h"
-#include "src/tint/program_id.h"
+#include "src/tint/utils/generation_id.h"
 #include "src/tint/utils/text/symbol_table.h"
 
 // Forward Declarations
@@ -64,7 +64,7 @@
     Program& operator=(Program&& rhs);
 
     /// @returns the unique identifier for this program
-    ProgramID ID() const { return id_; }
+    GenerationID ID() const { return id_; }
 
     /// @returns the last allocated (numerically highest) AST node identifier.
     ast::NodeID HighestASTNodeID() const { return highest_node_id_; }
@@ -166,7 +166,7 @@
     /// Asserts that the program has not been moved.
     void AssertNotMoved() const;
 
-    ProgramID id_;
+    GenerationID id_;
     ast::NodeID highest_node_id_;
     constant::Manager constants_;
     ASTNodeAllocator ast_nodes_;
@@ -180,8 +180,8 @@
 };
 
 /// @param program the Program
-/// @returns the ProgramID of the Program
-inline ProgramID ProgramIDOf(const Program* program) {
+/// @returns the GenerationID of the Program
+inline GenerationID GenerationIDOf(const Program* program) {
     return program->ID();
 }
 
diff --git a/src/tint/lang/wgsl/program/program_builder.cc b/src/tint/lang/wgsl/program/program_builder.cc
index 8269434..86d13d9 100644
--- a/src/tint/lang/wgsl/program/program_builder.cc
+++ b/src/tint/lang/wgsl/program/program_builder.cc
@@ -34,7 +34,7 @@
 ProgramBuilder::OverrideOptions::~OverrideOptions() = default;
 
 ProgramBuilder::ProgramBuilder()
-    : id_(ProgramID::New()),
+    : id_(GenerationID::New()),
       ast_(ast_nodes_.Create<ast::Module>(id_, AllocateNodeID(), Source{})) {}
 
 ProgramBuilder::ProgramBuilder(ProgramBuilder&& rhs)
diff --git a/src/tint/lang/wgsl/program/program_builder.h b/src/tint/lang/wgsl/program/program_builder.h
index 121f57a..c70ddbc 100644
--- a/src/tint/lang/wgsl/program/program_builder.h
+++ b/src/tint/lang/wgsl/program/program_builder.h
@@ -102,7 +102,7 @@
 #include "src/tint/lang/wgsl/program/program.h"
 #include "src/tint/lang/wgsl/sem/array_count.h"
 #include "src/tint/lang/wgsl/sem/struct.h"
-#include "src/tint/program_id.h"
+#include "src/tint/utils/generation_id.h"
 #include "src/tint/utils/text/string.h"
 
 #ifdef CURRENTLY_IN_TINT_PUBLIC_HEADER
@@ -329,7 +329,7 @@
     static ProgramBuilder Wrap(const Program* program);
 
     /// @returns the unique identifier for this program
-    ProgramID ID() const { return id_; }
+    GenerationID ID() const { return id_; }
 
     /// @returns a reference to the program's types
     type::Manager& Types() {
@@ -3612,7 +3612,7 @@
     void AssertNotMoved() const;
 
   private:
-    ProgramID id_;
+    GenerationID id_;
     ast::NodeID last_ast_node_id_ = ast::NodeID{static_cast<decltype(ast::NodeID::value)>(0) - 1};
     ASTNodeAllocator ast_nodes_;
     SemNodeAllocator sem_nodes_;
@@ -3688,8 +3688,8 @@
 //! @endcond
 
 /// @param builder the ProgramBuilder
-/// @returns the ProgramID of the ProgramBuilder
-inline ProgramID ProgramIDOf(const ProgramBuilder* builder) {
+/// @returns the GenerationID of the ProgramBuilder
+inline GenerationID GenerationIDOf(const ProgramBuilder* builder) {
     return builder->ID();
 }
 
diff --git a/src/tint/lang/wgsl/resolver/attribute_validation_test.cc b/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
index d7f4e83..66dea38 100644
--- a/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/attribute_validation_test.cc
@@ -2302,7 +2302,7 @@
 
 class TestAttribute : public utils::Castable<TestAttribute, ast::InternalAttribute> {
   public:
-    TestAttribute(ProgramID pid, ast::NodeID nid, const ast::IdentifierExpression* dep)
+    TestAttribute(GenerationID pid, ast::NodeID nid, const ast::IdentifierExpression* dep)
         : Base(pid, nid, utils::Vector{dep}) {}
     std::string InternalName() const override { return "test_attribute"; }
     const Cloneable* Clone(CloneContext*) const override { return nullptr; }
diff --git a/src/tint/lang/wgsl/resolver/validation_test.cc b/src/tint/lang/wgsl/resolver/validation_test.cc
index b8675f2..84c2764 100644
--- a/src/tint/lang/wgsl/resolver/validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/validation_test.cc
@@ -52,13 +52,13 @@
 
 class FakeStmt final : public utils::Castable<FakeStmt, ast::Statement> {
   public:
-    FakeStmt(ProgramID pid, ast::NodeID nid, Source src) : Base(pid, nid, src) {}
+    FakeStmt(GenerationID pid, ast::NodeID nid, Source src) : Base(pid, nid, src) {}
     FakeStmt* Clone(CloneContext*) const override { return nullptr; }
 };
 
 class FakeExpr final : public utils::Castable<FakeExpr, ast::Expression> {
   public:
-    FakeExpr(ProgramID pid, ast::NodeID nid, Source src) : Base(pid, nid, src) {}
+    FakeExpr(GenerationID pid, ast::NodeID nid, Source src) : Base(pid, nid, src) {}
     FakeExpr* Clone(CloneContext*) const override { return nullptr; }
 };