Program: Remove deprecated symbol methods

Fixup all usages

Bug: tint:390
Change-Id: If861b044eae006af2fd86d348de6ba62f448bc6a
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/38549
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/ast/builder.cc b/src/ast/builder.cc
index d929a02..de757c1 100644
--- a/src/ast/builder.cc
+++ b/src/ast/builder.cc
@@ -40,7 +40,7 @@
                        type::Type* type,
                        Expression* constructor,
                        VariableDecorationList decorations) {
-  auto* var = create<Variable>(program->RegisterSymbol(name), storage, type,
+  auto* var = create<Variable>(program->Symbols().Register(name), storage, type,
                                false, constructor, decorations);
   OnVariableBuilt(var);
   return var;
@@ -52,8 +52,8 @@
                        type::Type* type,
                        Expression* constructor,
                        VariableDecorationList decorations) {
-  auto* var = create<Variable>(source, program->RegisterSymbol(name), storage,
-                               type, false, constructor, decorations);
+  auto* var = create<Variable>(source, program->Symbols().Register(name),
+                               storage, type, false, constructor, decorations);
   OnVariableBuilt(var);
   return var;
 }
@@ -69,7 +69,7 @@
                          type::Type* type,
                          Expression* constructor,
                          VariableDecorationList decorations) {
-  auto* var = create<Variable>(program->RegisterSymbol(name), storage, type,
+  auto* var = create<Variable>(program->Symbols().Register(name), storage, type,
                                true, constructor, decorations);
   OnVariableBuilt(var);
   return var;
@@ -81,8 +81,8 @@
                          type::Type* type,
                          Expression* constructor,
                          VariableDecorationList decorations) {
-  auto* var = create<Variable>(source, program->RegisterSymbol(name), storage,
-                               type, true, constructor, decorations);
+  auto* var = create<Variable>(source, program->Symbols().Register(name),
+                               storage, type, true, constructor, decorations);
   OnVariableBuilt(var);
   return var;
 }
diff --git a/src/ast/builder.h b/src/ast/builder.h
index 62462ac..ed5baeb 100644
--- a/src/ast/builder.h
+++ b/src/ast/builder.h
@@ -166,7 +166,8 @@
   /// @param type the alias type
   /// @returns the alias pointer
   type::Alias* alias(const std::string& name, type::Type* type) const {
-    return program_->create<type::Alias>(program_->RegisterSymbol(name), type);
+    return program_->create<type::Alias>(program_->Symbols().Register(name),
+                                         type);
   }
 
   /// @return the tint AST pointer to type `T` with the given StorageClass.
@@ -180,7 +181,8 @@
   /// @param impl the struct implementation
   /// @returns a struct pointer
   type::Struct* struct_(const std::string& name, ast::Struct* impl) const {
-    return program_->create<type::Struct>(program_->RegisterSymbol(name), impl);
+    return program_->create<type::Struct>(program_->Symbols().Register(name),
+                                          impl);
   }
 
  private:
@@ -227,20 +229,21 @@
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
   IdentifierExpression* Expr(const std::string& name) {
-    return create<IdentifierExpression>(program->RegisterSymbol(name));
+    return create<IdentifierExpression>(program->Symbols().Register(name));
   }
 
   /// @param source the source information
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
   IdentifierExpression* Expr(const Source& source, const std::string& name) {
-    return create<IdentifierExpression>(source, program->RegisterSymbol(name));
+    return create<IdentifierExpression>(source,
+                                        program->Symbols().Register(name));
   }
 
   /// @param name the identifier name
   /// @return an IdentifierExpression with the given name
   IdentifierExpression* Expr(const char* name) {
-    return create<IdentifierExpression>(program->RegisterSymbol(name));
+    return create<IdentifierExpression>(program->Symbols().Register(name));
   }
 
   /// @param value the boolean value
@@ -620,7 +623,7 @@
                  ast::StatementList body,
                  ast::FunctionDecorationList decorations) {
     return program->create<ast::Function>(
-        source, program->RegisterSymbol(name), params, type,
+        source, program->Symbols().Register(name), params, type,
         create<ast::BlockStatement>(body), decorations);
   }
 
@@ -636,8 +639,8 @@
                  type::Type* type,
                  ast::StatementList body,
                  ast::FunctionDecorationList decorations) {
-    return create<ast::Function>(program->RegisterSymbol(name), params, type,
-                                 create<ast::BlockStatement>(body),
+    return create<ast::Function>(program->Symbols().Register(name), params,
+                                 type, create<ast::BlockStatement>(body),
                                  decorations);
   }
 
@@ -649,7 +652,8 @@
   StructMember* Member(const Source& source,
                        const std::string& name,
                        type::Type* type) {
-    return program->create<StructMember>(source, program->RegisterSymbol(name),
+    return program->create<StructMember>(source,
+                                         program->Symbols().Register(name),
                                          type, StructMemberDecorationList{});
   }
 
@@ -658,7 +662,8 @@
   /// @param type the struct member type
   /// @returns the struct member pointer
   StructMember* Member(const std::string& name, type::Type* type) {
-    return program->create<StructMember>(source_, program->RegisterSymbol(name),
+    return program->create<StructMember>(source_,
+                                         program->Symbols().Register(name),
                                          type, StructMemberDecorationList{});
   }
 
@@ -670,8 +675,8 @@
   StructMember* Member(const std::string& name,
                        type::Type* type,
                        StructMemberDecorationList decos) {
-    return program->create<StructMember>(source_, program->RegisterSymbol(name),
-                                         type, decos);
+    return program->create<StructMember>(
+        source_, program->Symbols().Register(name), type, decos);
   }
 
   /// Creates a new Node owned by the Module, with the explicit Source.
diff --git a/src/ast/function_test.cc b/src/ast/function_test.cc
index a2aeb5d..d5beabd 100644
--- a/src/ast/function_test.cc
+++ b/src/ast/function_test.cc
@@ -36,7 +36,7 @@
 
   auto* f =
       Func("func", params, ty.void_, StatementList{}, FunctionDecorationList{});
-  EXPECT_EQ(f->symbol(), mod->RegisterSymbol("func"));
+  EXPECT_EQ(f->symbol(), mod->Symbols().Register("func"));
   ASSERT_EQ(f->params().size(), 1u);
   EXPECT_EQ(f->return_type(), ty.void_);
   EXPECT_EQ(f->params()[0], var);
@@ -151,7 +151,7 @@
   auto* f = Func("func", VariableList{}, ty.void_, StatementList{},
                  FunctionDecorationList{});
 
-  auto main_sym = mod->RegisterSymbol("main");
+  auto main_sym = mod->Symbols().Register("main");
   f->add_ancestor_entry_point(main_sym);
   ASSERT_EQ(1u, f->ancestor_entry_points().size());
   EXPECT_EQ(main_sym, f->ancestor_entry_points()[0]);
@@ -364,12 +364,12 @@
                     ast::FunctionDecorationList{});
   FunctionList list;
   list.Add(func);
-  EXPECT_EQ(func, list.Find(mod->RegisterSymbol("main")));
+  EXPECT_EQ(func, list.Find(mod->Symbols().Register("main")));
 }
 
 TEST_F(FunctionListTest, FindSymbolMissing) {
   FunctionList list;
-  EXPECT_EQ(nullptr, list.Find(mod->RegisterSymbol("Missing")));
+  EXPECT_EQ(nullptr, list.Find(mod->Symbols().Register("Missing")));
 }
 
 TEST_F(FunctionListTest, FindSymbolStage) {
@@ -384,9 +384,10 @@
   FunctionList list;
   list.Add(fs);
   list.Add(vs);
-  EXPECT_EQ(fs,
-            list.Find(mod->RegisterSymbol("main"), PipelineStage::kFragment));
-  EXPECT_EQ(vs, list.Find(mod->RegisterSymbol("main"), PipelineStage::kVertex));
+  EXPECT_EQ(
+      fs, list.Find(mod->Symbols().Register("main"), PipelineStage::kFragment));
+  EXPECT_EQ(vs,
+            list.Find(mod->Symbols().Register("main"), PipelineStage::kVertex));
 }
 
 TEST_F(FunctionListTest, FindSymbolStageMissing) {
@@ -396,7 +397,7 @@
                     create<ast::StageDecoration>(PipelineStage::kFragment),
                 }));
   EXPECT_EQ(nullptr,
-            list.Find(mod->RegisterSymbol("main"), PipelineStage::kVertex));
+            list.Find(mod->Symbols().Register("main"), PipelineStage::kVertex));
 }
 
 TEST_F(FunctionListTest, HasStage) {
diff --git a/src/clone_context.cc b/src/clone_context.cc
index f986244..b5866cb 100644
--- a/src/clone_context.cc
+++ b/src/clone_context.cc
@@ -23,7 +23,7 @@
 CloneContext::~CloneContext() = default;
 
 Symbol CloneContext::Clone(const Symbol& s) const {
-  return dst->RegisterSymbol(src->SymbolToName(s));
+  return dst->Symbols().Register(src->Symbols().NameFor(s));
 }
 
 void CloneContext::Clone() {
diff --git a/src/demangler.cc b/src/demangler.cc
index 9296d11..252af1b 100644
--- a/src/demangler.cc
+++ b/src/demangler.cc
@@ -46,7 +46,7 @@
     auto id = ret.substr(start_idx, len);
 
     Symbol sym(std::stoi(id));
-    auto name = program.SymbolToName(sym);
+    auto name = program.Symbols().NameFor(sym);
     ret.replace(idx, end_idx - idx, name);
 
     pos = idx + name.length();
diff --git a/src/demangler_test.cc b/src/demangler_test.cc
index 9e83fb4..3c41285 100644
--- a/src/demangler_test.cc
+++ b/src/demangler_test.cc
@@ -24,7 +24,7 @@
 
 TEST_F(DemanglerTest, NoSymbols) {
   Program m;
-  m.RegisterSymbol("sym1");
+  m.Symbols().Register("sym1");
 
   Demangler d;
   EXPECT_EQ("test str", d.Demangle(m, "test str"));
@@ -32,7 +32,7 @@
 
 TEST_F(DemanglerTest, Symbol) {
   Program m;
-  m.RegisterSymbol("sym1");
+  m.Symbols().Register("sym1");
 
   Demangler d;
   EXPECT_EQ("test sym1 str", d.Demangle(m, "test tint_symbol_1 str"));
@@ -40,8 +40,8 @@
 
 TEST_F(DemanglerTest, MultipleSymbols) {
   Program m;
-  m.RegisterSymbol("sym1");
-  m.RegisterSymbol("sym2");
+  m.Symbols().Register("sym1");
+  m.Symbols().Register("sym2");
 
   Demangler d;
   EXPECT_EQ(
diff --git a/src/inspector/inspector.cc b/src/inspector/inspector.cc
index bdd89a8..4919970 100644
--- a/src/inspector/inspector.cc
+++ b/src/inspector/inspector.cc
@@ -56,14 +56,14 @@
     }
 
     EntryPoint entry_point;
-    entry_point.name = program_.SymbolToName(func->symbol());
-    entry_point.remapped_name = program_.SymbolToName(func->symbol());
+    entry_point.name = program_.Symbols().NameFor(func->symbol());
+    entry_point.remapped_name = program_.Symbols().NameFor(func->symbol());
     entry_point.stage = func->pipeline_stage();
     std::tie(entry_point.workgroup_size_x, entry_point.workgroup_size_y,
              entry_point.workgroup_size_z) = func->workgroup_size();
 
     for (auto* var : func->referenced_module_variables()) {
-      auto name = program_.SymbolToName(var->symbol());
+      auto name = program_.Symbols().NameFor(var->symbol());
       if (var->HasBuiltinDecoration()) {
         continue;
       }
@@ -283,7 +283,7 @@
 }
 
 ast::Function* Inspector::FindEntryPointByName(const std::string& name) {
-  auto* func = program_.AST().Functions().Find(program_.GetSymbol(name));
+  auto* func = program_.AST().Functions().Find(program_.Symbols().Get(name));
   if (!func) {
     error_ += name + " was not found!";
     return nullptr;
diff --git a/src/program.cc b/src/program.cc
index 07fa1d5..d5a86cf 100644
--- a/src/program.cc
+++ b/src/program.cc
@@ -47,18 +47,6 @@
   }
 }
 
-Symbol Program::RegisterSymbol(const std::string& name) {
-  return symbols_.Register(name);
-}
-
-Symbol Program::GetSymbol(const std::string& name) const {
-  return symbols_.Get(name);
-}
-
-std::string Program::SymbolToName(const Symbol sym) const {
-  return symbols_.NameFor(sym);
-}
-
 bool Program::IsValid() const {
   return ast_->IsValid();
 }
diff --git a/src/program.h b/src/program.h
index 0fe0bb6..d6cc6d4 100644
--- a/src/program.h
+++ b/src/program.h
@@ -118,25 +118,6 @@
     return types_.Get<T>(std::forward<ARGS>(args)...);
   }
 
-  /// Registers `name` as a symbol
-  /// @param name the name to register
-  /// @returns the symbol for the `name`. If `name` is already registered the
-  /// previously generated symbol will be returned.
-  /// [DEPRECATED]: Use Symbols().Register()
-  Symbol RegisterSymbol(const std::string& name);
-
-  /// Returns the symbol for `name`
-  /// @param name the name to lookup
-  /// @returns the symbol for name or symbol::kInvalid
-  /// [DEPRECATED]: Use Symbols().Get()
-  Symbol GetSymbol(const std::string& name) const;
-
-  /// Returns the `name` for `sym`
-  /// @param sym the symbol to retrieve the name for
-  /// @returns the use provided `name` for the symbol or "" if not found
-  /// [DEPRECATED]: Use Symbols().NameFor()
-  std::string SymbolToName(const Symbol sym) const;
-
  private:
   Program(const Program&) = delete;
 
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index b88f982..419a87e 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -786,7 +786,7 @@
   const auto& top = statements_stack_.back();
 
   auto* cond = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(guard_name));
+      Source{}, program_.Symbols().Register(guard_name));
   auto* builder = AddStatementBuilder<IfStatementBuilder>(cond);
 
   PushNewStatementBlock(
@@ -859,9 +859,10 @@
 
   auto& statements = statements_stack_[0].GetStatements();
   auto* body = create<ast::BlockStatement>(Source{}, statements);
-  program_.AST().Functions().Add(create<ast::Function>(
-      decl.source, program_.RegisterSymbol(decl.name), std::move(decl.params),
-      decl.return_type, body, std::move(decl.decorations)));
+  program_.AST().Functions().Add(
+      create<ast::Function>(decl.source, program_.Symbols().Register(decl.name),
+                            std::move(decl.params), decl.return_type, body,
+                            std::move(decl.decorations)));
 
   // Maintain the invariant by repopulating the one and only element.
   statements_stack_.clear();
@@ -2012,7 +2013,7 @@
     return TypedExpression{
         parser_impl_.ConvertType(def_use_mgr_->GetDef(id)->type_id()),
         create<ast::IdentifierExpression>(Source{},
-                                          program_.RegisterSymbol(name))};
+                                          program_.Symbols().Register(name))};
   }
   if (singly_used_values_.count(id)) {
     auto expr = std::move(singly_used_values_[id]);
@@ -2034,7 +2035,7 @@
       auto name = namer_.Name(inst->result_id());
       return TypedExpression{parser_impl_.ConvertType(inst->type_id()),
                              create<ast::IdentifierExpression>(
-                                 Source{}, program_.RegisterSymbol(name))};
+                                 Source{}, program_.Symbols().Register(name))};
     }
     default:
       break;
@@ -2263,14 +2264,14 @@
   const std::string guard_name = block_info.flow_guard_name;
   if (!guard_name.empty()) {
     // Declare the guard variable just before the "if", initialized to true.
-    auto* guard_var =
-        create<ast::Variable>(Source{},                             // source
-                              program_.RegisterSymbol(guard_name),  // symbol
-                              ast::StorageClass::kFunction,    // storage_class
-                              parser_impl_.Bool(),             // type
-                              false,                           // is_const
-                              MakeTrue(Source{}),              // constructor
-                              ast::VariableDecorationList{});  // decorations
+    auto* guard_var = create<ast::Variable>(
+        Source{},                                 // source
+        program_.Symbols().Register(guard_name),  // symbol
+        ast::StorageClass::kFunction,             // storage_class
+        parser_impl_.Bool(),                      // type
+        false,                                    // is_const
+        MakeTrue(Source{}),                       // constructor
+        ast::VariableDecorationList{});           // decorations
     auto* guard_decl = create<ast::VariableDeclStatement>(Source{}, guard_var);
     AddStatement(guard_decl);
   }
@@ -2672,7 +2673,7 @@
         return create<ast::AssignmentStatement>(
             Source{},
             create<ast::IdentifierExpression>(
-                Source{}, program_.RegisterSymbol(flow_guard)),
+                Source{}, program_.Symbols().Register(flow_guard)),
             MakeFalse(Source{}));
       }
 
@@ -2793,7 +2794,7 @@
     assert(!phi_var_name.empty());
     auto* var = create<ast::Variable>(
         Source{},                                       // source
-        program_.RegisterSymbol(phi_var_name),          // symbol
+        program_.Symbols().Register(phi_var_name),      // symbol
         ast::StorageClass::kFunction,                   // storage_class
         parser_impl_.ConvertType(def_inst->type_id()),  // type
         false,                                          // is_const
@@ -2831,8 +2832,8 @@
       auto expr = MakeExpression(assignment.value);
       AddStatement(create<ast::AssignmentStatement>(
           Source{},
-          create<ast::IdentifierExpression>(Source{},
-                                            program_.RegisterSymbol(var_name)),
+          create<ast::IdentifierExpression>(
+              Source{}, program_.Symbols().Register(var_name)),
           expr.expr));
     }
   }
@@ -2870,7 +2871,7 @@
     AddStatement(create<ast::AssignmentStatement>(
         Source{},
         create<ast::IdentifierExpression>(Source{},
-                                          program_.RegisterSymbol(name)),
+                                          program_.Symbols().Register(name)),
         ast_expr.expr));
     return true;
   }
@@ -3009,7 +3010,7 @@
       TypedExpression expr{
           parser_impl_.ConvertType(inst.type_id()),
           create<ast::IdentifierExpression>(
-              Source{}, program_.RegisterSymbol(def_info->phi_var))};
+              Source{}, program_.Symbols().Register(def_info->phi_var))};
       return EmitConstDefOrWriteToHoistedVar(inst, expr);
     }
 
@@ -3072,7 +3073,7 @@
             create<ast::CallExpression>(
                 Source{},
                 create<ast::IdentifierExpression>(
-                    Source{}, program_.RegisterSymbol(unary_builtin_name)),
+                    Source{}, program_.Symbols().Register(unary_builtin_name)),
                 std::move(params))};
   }
 
@@ -3177,8 +3178,8 @@
     return {};
   }
 
-  auto* func = create<ast::IdentifierExpression>(Source{},
-                                                 program_.RegisterSymbol(name));
+  auto* func = create<ast::IdentifierExpression>(
+      Source{}, program_.Symbols().Register(name));
   ast::ExpressionList operands;
   type::Type* first_operand_type = nullptr;
   // All parameters to GLSL.std.450 extended instructions are IDs.
@@ -3204,20 +3205,20 @@
   }
   const char* names[] = {"x", "y", "z", "w"};
   return create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(names[i & 3]));
+      Source{}, program_.Symbols().Register(names[i & 3]));
 }
 
 ast::IdentifierExpression* FunctionEmitter::PrefixSwizzle(uint32_t n) {
   switch (n) {
     case 1:
-      return create<ast::IdentifierExpression>(Source{},
-                                               program_.RegisterSymbol("x"));
+      return create<ast::IdentifierExpression>(
+          Source{}, program_.Symbols().Register("x"));
     case 2:
-      return create<ast::IdentifierExpression>(Source{},
-                                               program_.RegisterSymbol("xy"));
+      return create<ast::IdentifierExpression>(
+          Source{}, program_.Symbols().Register("xy"));
     case 3:
-      return create<ast::IdentifierExpression>(Source{},
-                                               program_.RegisterSymbol("xyz"));
+      return create<ast::IdentifierExpression>(
+          Source{}, program_.Symbols().Register("xyz"));
     default:
       break;
   }
@@ -3312,7 +3313,7 @@
 
       auto name = namer_.Name(base_id);
       current_expr.expr = create<ast::IdentifierExpression>(
-          Source{}, program_.RegisterSymbol(name));
+          Source{}, program_.Symbols().Register(name));
       current_expr.type = parser_impl_.ConvertType(ptr_ty_id);
     }
   }
@@ -3405,7 +3406,7 @@
         auto name =
             namer_.GetMemberName(pointee_type_id, uint32_t(index_const_val));
         auto* member_access = create<ast::IdentifierExpression>(
-            Source{}, program_.RegisterSymbol(name));
+            Source{}, program_.Symbols().Register(name));
 
         next_expr = create<ast::MemberAccessorExpression>(
             Source{}, current_expr.expr, member_access);
@@ -3526,7 +3527,7 @@
         }
         auto name = namer_.GetMemberName(current_type_id, uint32_t(index_val));
         auto* member_access = create<ast::IdentifierExpression>(
-            Source{}, program_.RegisterSymbol(name));
+            Source{}, program_.Symbols().Register(name));
 
         next_expr = create<ast::MemberAccessorExpression>(
             Source{}, current_expr.expr, member_access);
@@ -3931,7 +3932,7 @@
   // We ignore function attributes such as Inline, DontInline, Pure, Const.
   auto name = namer_.Name(inst.GetSingleWordInOperand(0));
   auto* function = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(name));
+      Source{}, program_.Symbols().Register(name));
 
   ast::ExpressionList params;
   for (uint32_t iarg = 1; iarg < inst.NumInOperands(); ++iarg) {
@@ -3960,7 +3961,7 @@
   ss << intrinsic;
   auto name = ss.str();
   auto* ident = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(name));
+      Source{}, program_.Symbols().Register(name));
   ident->set_intrinsic(intrinsic);
 
   ast::ExpressionList params;
@@ -4003,11 +4004,12 @@
     params.push_back(operand2.expr);
     // The condition goes last.
     params.push_back(condition.expr);
-    return {operand1.type, create<ast::CallExpression>(
-                               Source{},
-                               create<ast::IdentifierExpression>(
-                                   Source{}, program_.RegisterSymbol("select")),
-                               std::move(params))};
+    return {operand1.type,
+            create<ast::CallExpression>(
+                Source{},
+                create<ast::IdentifierExpression>(
+                    Source{}, program_.Symbols().Register("select")),
+                std::move(params))};
   }
   return {};
 }
@@ -4056,7 +4058,7 @@
   }
   auto name = namer_.Name(image->result_id());
   return create<ast::IdentifierExpression>(GetSourceForInst(inst),
-                                           program_.RegisterSymbol(name));
+                                           program_.Symbols().Register(name));
 }
 
 ast::Expression* FunctionEmitter::GetSamplerExpression(
@@ -4072,7 +4074,7 @@
   }
   auto name = namer_.Name(image->result_id());
   return create<ast::IdentifierExpression>(GetSourceForInst(inst),
-                                           program_.RegisterSymbol(name));
+                                           program_.Symbols().Register(name));
 }
 
 bool FunctionEmitter::EmitImageAccess(const spvtools::opt::Instruction& inst) {
@@ -4259,7 +4261,7 @@
   }
 
   auto* ident = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(builtin_name));
+      Source{}, program_.Symbols().Register(builtin_name));
   auto* call_expr =
       create<ast::CallExpression>(Source{}, ident, std::move(params));
 
@@ -4567,14 +4569,14 @@
   }
 
   auto* member_ident = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(field_name));
+      Source{}, program_.Symbols().Register(field_name));
   auto* member_access = create<ast::MemberAccessorExpression>(
       Source{}, MakeExpression(struct_ptr_id).expr, member_ident);
 
   // Generate the intrinsic function call.
   std::string call_ident_str = "arrayLength";
   auto* call_ident = create<ast::IdentifierExpression>(
-      Source{}, program_.RegisterSymbol(call_ident_str));
+      Source{}, program_.Symbols().Register(call_ident_str));
   call_ident->set_intrinsic(ast::Intrinsic::kArrayLength);
 
   ast::ExpressionList params{member_access};
diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc
index e49152c..a13b77b 100644
--- a/src/reader/spirv/parser_impl.cc
+++ b/src/reader/spirv/parser_impl.cc
@@ -947,7 +947,7 @@
     }
     const auto member_name = namer_.GetMemberName(type_id, member_index);
     auto* ast_struct_member = create<ast::StructMember>(
-        Source{}, program_.RegisterSymbol(member_name), ast_member_ty,
+        Source{}, program_.Symbols().Register(member_name), ast_member_ty,
         std::move(ast_member_decorations));
     ast_members.push_back(ast_struct_member);
   }
@@ -963,8 +963,8 @@
   namer_.SuggestSanitizedName(type_id, "S");
 
   auto name = namer_.GetName(type_id);
-  auto* result =
-      program_.create<type::Struct>(program_.RegisterSymbol(name), ast_struct);
+  auto* result = program_.create<type::Struct>(
+      program_.Symbols().Register(name), ast_struct);
   id_to_type_[type_id] = result;
   if (num_non_writable_members == members.size()) {
     read_only_struct_types_.insert(result);
@@ -1130,7 +1130,7 @@
   }
   const auto name = namer_.GetName(type_id);
   auto* ast_alias_type = program_.create<type::Alias>(
-      program_.RegisterSymbol(name), ast_underlying_type);
+      program_.Symbols().Register(name), ast_underlying_type);
   // Record this new alias as the AST type for this SPIR-V ID.
   id_to_type_[type_id] = ast_alias_type;
   program_.AST().AddConstructedType(ast_alias_type);
@@ -1306,13 +1306,13 @@
   }
 
   std::string name = namer_.Name(id);
-  return create<ast::Variable>(Source{},                       // source
-                               program_.RegisterSymbol(name),  // symbol
-                               sc,                             // storage_class
-                               type,                           // type
-                               is_const,                       // is_const
-                               constructor,                    // constructor
-                               decorations);                   // decorations
+  return create<ast::Variable>(Source{},                           // source
+                               program_.Symbols().Register(name),  // symbol
+                               sc,            // storage_class
+                               type,          // type
+                               is_const,      // is_const
+                               constructor,   // constructor
+                               decorations);  // decorations
 }
 
 TypedExpression ParserImpl::MakeConstantExpression(uint32_t id) {
diff --git a/src/reader/spirv/parser_impl_function_decl_test.cc b/src/reader/spirv/parser_impl_function_decl_test.cc
index 5c6f1d5..897b740 100644
--- a/src/reader/spirv/parser_impl_function_decl_test.cc
+++ b/src/reader/spirv/parser_impl_function_decl_test.cc
@@ -81,7 +81,7 @@
   ASSERT_TRUE(p->error().empty()) << p->error();
   const auto program_ast = p->get_program().to_str();
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("main").to_str() +
+  Function )" + p->get_program().Symbols().Get("main").to_str() +
                                      R"( -> __void
   StageDecoration{vertex}
   ()
@@ -101,7 +101,7 @@
   ASSERT_TRUE(p->error().empty()) << p->error();
   const auto program_ast = p->get_program().to_str();
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("main").to_str() +
+  Function )" + p->get_program().Symbols().Get("main").to_str() +
                                      R"( -> __void
   StageDecoration{fragment}
   ()
@@ -121,7 +121,7 @@
   ASSERT_TRUE(p->error().empty()) << p->error();
   const auto program_ast = p->get_program().to_str();
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("main").to_str() +
+  Function )" + p->get_program().Symbols().Get("main").to_str() +
                                      R"( -> __void
   StageDecoration{compute}
   ()
@@ -143,13 +143,13 @@
   ASSERT_TRUE(p->error().empty()) << p->error();
   const auto program_ast = p->get_program().to_str();
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("frag_main").to_str() +
+  Function )" + p->get_program().Symbols().Get("frag_main").to_str() +
                                      R"( -> __void
   StageDecoration{fragment}
   ()
   {)"));
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("comp_main").to_str() +
+  Function )" + p->get_program().Symbols().Get("comp_main").to_str() +
                                      R"( -> __void
   StageDecoration{compute}
   ()
@@ -167,7 +167,7 @@
   EXPECT_TRUE(p->error().empty());
   const auto program_ast = p->get_program().to_str();
   EXPECT_THAT(program_ast, HasSubstr(R"(
-  Function )" + p->get_program().GetSymbol("main").to_str() +
+  Function )" + p->get_program().Symbols().Get("main").to_str() +
                                      R"( -> __void
   ()
   {)"));
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index dc15e04..1270924 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -361,7 +361,7 @@
 
       auto* type = str.value;
       register_constructed(
-          program_.SymbolToName(type->As<type::Struct>()->symbol()), type);
+          program_.Symbols().NameFor(type->As<type::Struct>()->symbol()), type);
       program_.AST().AddConstructedType(type);
       return true;
     }
@@ -435,13 +435,14 @@
     constructor = expr.value;
   }
 
-  return create<ast::Variable>(decl->source,                         // source
-                               program_.RegisterSymbol(decl->name),  // symbol
-                               decl->storage_class,          // storage_class
-                               decl->type,                   // type
-                               false,                        // is_const
-                               constructor,                  // constructor
-                               std::move(var_decos.value));  // decorations
+  return create<ast::Variable>(
+      decl->source,                             // source
+      program_.Symbols().Register(decl->name),  // symbol
+      decl->storage_class,                      // storage_class
+      decl->type,                               // type
+      false,                                    // is_const
+      constructor,                              // constructor
+      std::move(var_decos.value));              // decorations
 }
 
 // global_constant_decl
@@ -463,13 +464,14 @@
   if (init.errored)
     return Failure::kErrored;
 
-  return create<ast::Variable>(decl->source,                         // source
-                               program_.RegisterSymbol(decl->name),  // symbol
-                               ast::StorageClass::kNone,        // storage_class
-                               decl->type,                      // type
-                               true,                            // is_const
-                               init.value,                      // constructor
-                               ast::VariableDecorationList{});  // decorations
+  return create<ast::Variable>(
+      decl->source,                             // source
+      program_.Symbols().Register(decl->name),  // symbol
+      ast::StorageClass::kNone,                 // storage_class
+      decl->type,                               // type
+      true,                                     // is_const
+      init.value,                               // constructor
+      ast::VariableDecorationList{});           // decorations
 }
 
 // variable_decl
@@ -974,7 +976,7 @@
     return add_error(peek(), "invalid type alias");
 
   auto* alias = program_.create<type::Alias>(
-      program_.RegisterSymbol(name.value), type.value);
+      program_.Symbols().Register(name.value), type.value);
   register_constructed(name.value, alias);
 
   return alias;
@@ -1227,7 +1229,7 @@
     return Failure::kErrored;
 
   return create<type::Struct>(
-      program_.RegisterSymbol(name.value),
+      program_.Symbols().Register(name.value),
       create<ast::Struct>(source, std::move(body.value),
                           std::move(struct_decos.value)));
 }
@@ -1282,7 +1284,7 @@
     return Failure::kErrored;
 
   return create<ast::StructMember>(decl->source,
-                                   program_.RegisterSymbol(decl->name),
+                                   program_.Symbols().Register(decl->name),
                                    decl->type, std::move(member_decos.value));
 }
 
@@ -1319,7 +1321,7 @@
     return Failure::kErrored;
 
   return create<ast::Function>(
-      header->source, program_.RegisterSymbol(header->name), header->params,
+      header->source, program_.Symbols().Register(header->name), header->params,
       header->return_type, body.value, func_decos.value);
 }
 
@@ -1387,14 +1389,14 @@
 
   ast::VariableList ret;
   for (;;) {
-    auto* var =
-        create<ast::Variable>(decl->source,                         // source
-                              program_.RegisterSymbol(decl->name),  // symbol
-                              ast::StorageClass::kNone,        // storage_class
-                              decl->type,                      // type
-                              true,                            // is_const
-                              nullptr,                         // constructor
-                              ast::VariableDecorationList{});  // decorations
+    auto* var = create<ast::Variable>(
+        decl->source,                             // source
+        program_.Symbols().Register(decl->name),  // symbol
+        ast::StorageClass::kNone,                 // storage_class
+        decl->type,                               // type
+        true,                                     // is_const
+        nullptr,                                  // constructor
+        ast::VariableDecorationList{});           // decorations
     // Formal parameters are treated like a const declaration where the
     // initializer value is provided by the call's argument.  The key point is
     // that it's not updatable after intially set.  This is unlike C or GLSL
@@ -1658,14 +1660,14 @@
     if (!constructor.matched)
       return add_error(peek(), "missing constructor for const declaration");
 
-    auto* var =
-        create<ast::Variable>(decl->source,                         // source
-                              program_.RegisterSymbol(decl->name),  // symbol
-                              ast::StorageClass::kNone,        // storage_class
-                              decl->type,                      // type
-                              true,                            // is_const
-                              constructor.value,               // constructor
-                              ast::VariableDecorationList{});  // decorations
+    auto* var = create<ast::Variable>(
+        decl->source,                             // source
+        program_.Symbols().Register(decl->name),  // symbol
+        ast::StorageClass::kNone,                 // storage_class
+        decl->type,                               // type
+        true,                                     // is_const
+        constructor.value,                        // constructor
+        ast::VariableDecorationList{});           // decorations
 
     return create<ast::VariableDeclStatement>(decl->source, var);
   }
@@ -1688,8 +1690,8 @@
   }
 
   auto* var =
-      create<ast::Variable>(decl->source,                         // source
-                            program_.RegisterSymbol(decl->name),  // symbol
+      create<ast::Variable>(decl->source,                             // source
+                            program_.Symbols().Register(decl->name),  // symbol
                             decl->storage_class,             // storage_class
                             decl->type,                      // type
                             false,                           // is_const
@@ -2088,11 +2090,11 @@
     return Failure::kErrored;
 
   return create<ast::CallStatement>(
-      Source{},
-      create<ast::CallExpression>(source,
-                                  create<ast::IdentifierExpression>(
-                                      source, program_.RegisterSymbol(name)),
-                                  std::move(params)));
+      Source{}, create<ast::CallExpression>(
+                    source,
+                    create<ast::IdentifierExpression>(
+                        source, program_.Symbols().Register(name)),
+                    std::move(params)));
 }
 
 // break_stmt
@@ -2164,7 +2166,7 @@
 
   if (match(Token::Type::kIdentifier))
     return create<ast::IdentifierExpression>(
-        t.source(), program_.RegisterSymbol(t.to_str()));
+        t.source(), program_.Symbols().Register(t.to_str()));
 
   auto type = type_decl();
   if (type.errored)
@@ -2240,7 +2242,7 @@
     return postfix_expr(create<ast::MemberAccessorExpression>(
         ident.source, prefix,
         create<ast::IdentifierExpression>(
-            ident.source, program_.RegisterSymbol(ident.value))));
+            ident.source, program_.Symbols().Register(ident.value))));
   }
 
   return prefix;
diff --git a/src/reader/wgsl/parser_impl_additive_expression_test.cc b/src/reader/wgsl/parser_impl_additive_expression_test.cc
index f7fc99b..e3b3e6a 100644
--- a/src/reader/wgsl/parser_impl_additive_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_additive_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -62,7 +62,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_and_expression_test.cc b/src/reader/wgsl/parser_impl_and_expression_test.cc
index 68979f9..5f5b20a 100644
--- a/src/reader/wgsl/parser_impl_and_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_and_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_assignment_stmt_test.cc b/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
index 5234057..26ca7d0 100644
--- a/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_assignment_stmt_test.cc
@@ -42,7 +42,7 @@
 
   ASSERT_TRUE(e->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = e->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(e->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(e->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -77,7 +77,7 @@
 
   ASSERT_TRUE(mem->member()->Is<ast::IdentifierExpression>());
   auto* ident = mem->member()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("d"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("d"));
 
   ASSERT_TRUE(mem->structure()->Is<ast::ArrayAccessorExpression>());
   auto* ary = mem->structure()->As<ast::ArrayAccessorExpression>();
@@ -93,18 +93,18 @@
   mem = ary->array()->As<ast::MemberAccessorExpression>();
   ASSERT_TRUE(mem->member()->Is<ast::IdentifierExpression>());
   ident = mem->member()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("c"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("c"));
 
   ASSERT_TRUE(mem->structure()->Is<ast::MemberAccessorExpression>());
   mem = mem->structure()->As<ast::MemberAccessorExpression>();
 
   ASSERT_TRUE(mem->structure()->Is<ast::IdentifierExpression>());
   ident = mem->structure()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(mem->member()->Is<ast::IdentifierExpression>());
   ident = mem->member()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("b"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("b"));
 }
 
 TEST_F(ParserImplTest, AssignmentStmt_MissingEqual) {
diff --git a/src/reader/wgsl/parser_impl_call_stmt_test.cc b/src/reader/wgsl/parser_impl_call_stmt_test.cc
index a8f3850..9b2a445 100644
--- a/src/reader/wgsl/parser_impl_call_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_call_stmt_test.cc
@@ -38,7 +38,7 @@
 
   ASSERT_TRUE(c->func()->Is<ast::IdentifierExpression>());
   auto* ident = c->func()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   EXPECT_EQ(c->params().size(), 0u);
 }
@@ -56,7 +56,7 @@
 
   ASSERT_TRUE(c->func()->Is<ast::IdentifierExpression>());
   auto* ident = c->func()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   EXPECT_EQ(c->params().size(), 3u);
   EXPECT_TRUE(c->params()[0]->Is<ast::ConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_equality_expression_test.cc b/src/reader/wgsl/parser_impl_equality_expression_test.cc
index 89600cb..9edab2a 100644
--- a/src/reader/wgsl/parser_impl_equality_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_equality_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -62,7 +62,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc b/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
index cf821bf..79d19bb 100644
--- a/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_exclusive_or_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_function_decl_test.cc b/src/reader/wgsl/parser_impl_function_decl_test.cc
index 4a58b0c..ab76197 100644
--- a/src/reader/wgsl/parser_impl_function_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_function_decl_test.cc
@@ -37,13 +37,13 @@
   EXPECT_TRUE(f.matched);
   ASSERT_NE(f.value, nullptr);
 
-  EXPECT_EQ(f->symbol(), p->get_program().RegisterSymbol("main"));
+  EXPECT_EQ(f->symbol(), p->get_program().Symbols().Register("main"));
   ASSERT_NE(f->return_type(), nullptr);
   EXPECT_TRUE(f->return_type()->Is<type::Void>());
 
   ASSERT_EQ(f->params().size(), 2u);
-  EXPECT_EQ(f->params()[0]->symbol(), p->get_program().RegisterSymbol("a"));
-  EXPECT_EQ(f->params()[1]->symbol(), p->get_program().RegisterSymbol("b"));
+  EXPECT_EQ(f->params()[0]->symbol(), p->get_program().Symbols().Register("a"));
+  EXPECT_EQ(f->params()[1]->symbol(), p->get_program().Symbols().Register("b"));
 
   ASSERT_NE(f->return_type(), nullptr);
   EXPECT_TRUE(f->return_type()->Is<type::Void>());
@@ -65,7 +65,7 @@
   EXPECT_TRUE(f.matched);
   ASSERT_NE(f.value, nullptr);
 
-  EXPECT_EQ(f->symbol(), p->get_program().RegisterSymbol("main"));
+  EXPECT_EQ(f->symbol(), p->get_program().Symbols().Register("main"));
   ASSERT_NE(f->return_type(), nullptr);
   EXPECT_TRUE(f->return_type()->Is<type::Void>());
   ASSERT_EQ(f->params().size(), 0u);
@@ -103,7 +103,7 @@
   EXPECT_TRUE(f.matched);
   ASSERT_NE(f.value, nullptr);
 
-  EXPECT_EQ(f->symbol(), p->get_program().RegisterSymbol("main"));
+  EXPECT_EQ(f->symbol(), p->get_program().Symbols().Register("main"));
   ASSERT_NE(f->return_type(), nullptr);
   EXPECT_TRUE(f->return_type()->Is<type::Void>());
   ASSERT_EQ(f->params().size(), 0u);
@@ -148,7 +148,7 @@
   EXPECT_TRUE(f.matched);
   ASSERT_NE(f.value, nullptr);
 
-  EXPECT_EQ(f->symbol(), p->get_program().RegisterSymbol("main"));
+  EXPECT_EQ(f->symbol(), p->get_program().Symbols().Register("main"));
   ASSERT_NE(f->return_type(), nullptr);
   EXPECT_TRUE(f->return_type()->Is<type::Void>());
   ASSERT_EQ(f->params().size(), 0u);
diff --git a/src/reader/wgsl/parser_impl_function_header_test.cc b/src/reader/wgsl/parser_impl_function_header_test.cc
index 0b7fd8e..9b8a813 100644
--- a/src/reader/wgsl/parser_impl_function_header_test.cc
+++ b/src/reader/wgsl/parser_impl_function_header_test.cc
@@ -33,8 +33,8 @@
 
   EXPECT_EQ(f->name, "main");
   ASSERT_EQ(f->params.size(), 2u);
-  EXPECT_EQ(f->params[0]->symbol(), p->get_program().RegisterSymbol("a"));
-  EXPECT_EQ(f->params[1]->symbol(), p->get_program().RegisterSymbol("b"));
+  EXPECT_EQ(f->params[0]->symbol(), p->get_program().Symbols().Register("a"));
+  EXPECT_EQ(f->params[1]->symbol(), p->get_program().Symbols().Register("b"));
   EXPECT_TRUE(f->return_type->Is<type::Void>());
 }
 
diff --git a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
index 9bb96e3..991f3c7 100644
--- a/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_constant_decl_test.cc
@@ -33,7 +33,7 @@
   ASSERT_NE(e.value, nullptr);
 
   EXPECT_TRUE(e->is_const());
-  EXPECT_EQ(e->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->symbol(), p->get_program().Symbols().Register("a"));
   ASSERT_NE(e->type(), nullptr);
   EXPECT_TRUE(e->type()->Is<type::F32>());
 
diff --git a/src/reader/wgsl/parser_impl_global_decl_test.cc b/src/reader/wgsl/parser_impl_global_decl_test.cc
index 022b34d..3e10ea3 100644
--- a/src/reader/wgsl/parser_impl_global_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_decl_test.cc
@@ -38,7 +38,7 @@
   ASSERT_EQ(m.AST().GlobalVariables().size(), 1u);
 
   auto* v = m.AST().GlobalVariables()[0];
-  EXPECT_EQ(v->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(v->symbol(), p->get_program().Symbols().Register("a"));
 }
 
 TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Invalid) {
@@ -64,7 +64,7 @@
   ASSERT_EQ(m.AST().GlobalVariables().size(), 1u);
 
   auto* v = m.AST().GlobalVariables()[0];
-  EXPECT_EQ(v->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(v->symbol(), p->get_program().Symbols().Register("a"));
 }
 
 TEST_F(ParserImplTest, GlobalDecl_GlobalConstant_Invalid) {
@@ -89,7 +89,7 @@
   auto& m = p->get_program();
   ASSERT_EQ(m.AST().ConstructedTypes().size(), 1u);
   ASSERT_TRUE(m.AST().ConstructedTypes()[0]->Is<type::Alias>());
-  EXPECT_EQ(m.SymbolToName(
+  EXPECT_EQ(m.Symbols().NameFor(
                 m.AST().ConstructedTypes()[0]->As<type::Alias>()->symbol()),
             "A");
 }
@@ -107,11 +107,11 @@
   ASSERT_EQ(m.AST().ConstructedTypes().size(), 2u);
   ASSERT_TRUE(m.AST().ConstructedTypes()[0]->Is<type::Struct>());
   auto* str = m.AST().ConstructedTypes()[0]->As<type::Struct>();
-  EXPECT_EQ(str->symbol(), p->get_program().RegisterSymbol("A"));
+  EXPECT_EQ(str->symbol(), p->get_program().Symbols().Register("A"));
 
   ASSERT_TRUE(m.AST().ConstructedTypes()[1]->Is<type::Alias>());
   auto* alias = m.AST().ConstructedTypes()[1]->As<type::Alias>();
-  EXPECT_EQ(alias->symbol(), p->get_program().RegisterSymbol("B"));
+  EXPECT_EQ(alias->symbol(), p->get_program().Symbols().Register("B"));
   EXPECT_EQ(alias->type(), str);
 }
 
@@ -136,7 +136,7 @@
 
   auto& m = p->get_program();
   ASSERT_EQ(m.AST().Functions().size(), 1u);
-  EXPECT_EQ(m.SymbolToName(m.AST().Functions()[0]->symbol()), "main");
+  EXPECT_EQ(m.Symbols().NameFor(m.AST().Functions()[0]->symbol()), "main");
 }
 
 TEST_F(ParserImplTest, GlobalDecl_Function_WithDecoration) {
@@ -146,7 +146,7 @@
 
   auto& m = p->get_program();
   ASSERT_EQ(m.AST().Functions().size(), 1u);
-  EXPECT_EQ(m.SymbolToName(m.AST().Functions()[0]->symbol()), "main");
+  EXPECT_EQ(m.Symbols().NameFor(m.AST().Functions()[0]->symbol()), "main");
 }
 
 TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) {
@@ -169,7 +169,7 @@
   ASSERT_TRUE(t->Is<type::Struct>());
 
   auto* str = t->As<type::Struct>();
-  EXPECT_EQ(str->symbol(), p->get_program().RegisterSymbol("A"));
+  EXPECT_EQ(str->symbol(), p->get_program().Symbols().Register("A"));
   EXPECT_EQ(str->impl()->members().size(), 2u);
 }
 
@@ -188,7 +188,7 @@
   ASSERT_TRUE(t->Is<type::Struct>());
 
   auto* str = t->As<type::Struct>();
-  EXPECT_EQ(str->symbol(), p->get_program().RegisterSymbol("A"));
+  EXPECT_EQ(str->symbol(), p->get_program().Symbols().Register("A"));
   EXPECT_EQ(str->impl()->members().size(), 1u);
   EXPECT_FALSE(str->IsBlockDecorated());
 
@@ -212,7 +212,7 @@
   ASSERT_TRUE(t->Is<type::Struct>());
 
   auto* str = t->As<type::Struct>();
-  EXPECT_EQ(str->symbol(), p->get_program().RegisterSymbol("A"));
+  EXPECT_EQ(str->symbol(), p->get_program().Symbols().Register("A"));
   EXPECT_EQ(str->impl()->members().size(), 1u);
   EXPECT_TRUE(str->IsBlockDecorated());
 }
diff --git a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
index 28146d8..f6929e3 100644
--- a/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_global_variable_decl_test.cc
@@ -36,7 +36,7 @@
   EXPECT_FALSE(e.errored);
   ASSERT_NE(e.value, nullptr);
 
-  EXPECT_EQ(e->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_TRUE(e->type()->Is<type::F32>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
@@ -59,7 +59,7 @@
   EXPECT_FALSE(e.errored);
   ASSERT_NE(e.value, nullptr);
 
-  EXPECT_EQ(e->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_TRUE(e->type()->Is<type::F32>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
 
@@ -84,7 +84,7 @@
   EXPECT_FALSE(e.errored);
   ASSERT_NE(e.value, nullptr);
 
-  EXPECT_EQ(e->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->symbol(), p->get_program().Symbols().Register("a"));
   ASSERT_NE(e->type(), nullptr);
   EXPECT_TRUE(e->type()->Is<type::F32>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
@@ -114,7 +114,7 @@
   EXPECT_FALSE(e.errored);
   ASSERT_NE(e.value, nullptr);
 
-  EXPECT_EQ(e->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->symbol(), p->get_program().Symbols().Register("a"));
   ASSERT_NE(e->type(), nullptr);
   EXPECT_TRUE(e->type()->Is<type::F32>());
   EXPECT_EQ(e->storage_class(), ast::StorageClass::kOutput);
diff --git a/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc b/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
index b900de9..9a23a38 100644
--- a/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_inclusive_or_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_logical_and_expression_test.cc b/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
index 0a392b9..2a91303 100644
--- a/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_logical_and_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_logical_or_expression_test.cc b/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
index 921d9ca..63e8a77 100644
--- a/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_logical_or_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc b/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
index c0b547c..d989caa 100644
--- a/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_multiplicative_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -62,7 +62,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -85,7 +85,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_param_list_test.cc b/src/reader/wgsl/parser_impl_param_list_test.cc
index fb87002..5b65e69 100644
--- a/src/reader/wgsl/parser_impl_param_list_test.cc
+++ b/src/reader/wgsl/parser_impl_param_list_test.cc
@@ -38,7 +38,7 @@
   ASSERT_FALSE(e.errored);
   EXPECT_EQ(e.value.size(), 1u);
 
-  EXPECT_EQ(e.value[0]->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e.value[0]->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(e.value[0]->type(), i32);
   EXPECT_TRUE(e.value[0]->is_const());
 
@@ -61,7 +61,7 @@
   ASSERT_FALSE(e.errored);
   EXPECT_EQ(e.value.size(), 3u);
 
-  EXPECT_EQ(e.value[0]->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e.value[0]->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(e.value[0]->type(), i32);
   EXPECT_TRUE(e.value[0]->is_const());
 
@@ -70,7 +70,7 @@
   ASSERT_EQ(e.value[0]->source().range.end.line, 1u);
   ASSERT_EQ(e.value[0]->source().range.end.column, 2u);
 
-  EXPECT_EQ(e.value[1]->symbol(), p->get_program().RegisterSymbol("b"));
+  EXPECT_EQ(e.value[1]->symbol(), p->get_program().Symbols().Register("b"));
   EXPECT_EQ(e.value[1]->type(), f32);
   EXPECT_TRUE(e.value[1]->is_const());
 
@@ -79,7 +79,7 @@
   ASSERT_EQ(e.value[1]->source().range.end.line, 1u);
   ASSERT_EQ(e.value[1]->source().range.end.column, 11u);
 
-  EXPECT_EQ(e.value[2]->symbol(), p->get_program().RegisterSymbol("c"));
+  EXPECT_EQ(e.value[2]->symbol(), p->get_program().Symbols().Register("c"));
   EXPECT_EQ(e.value[2]->type(), vec2);
   EXPECT_TRUE(e.value[2]->is_const());
 
diff --git a/src/reader/wgsl/parser_impl_postfix_expression_test.cc b/src/reader/wgsl/parser_impl_postfix_expression_test.cc
index e03eed2..fc88cbe 100644
--- a/src/reader/wgsl/parser_impl_postfix_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_postfix_expression_test.cc
@@ -42,7 +42,7 @@
 
   ASSERT_TRUE(ary->array()->Is<ast::IdentifierExpression>());
   auto* ident = ary->array()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(ary->idx_expr()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(ary->idx_expr()->Is<ast::ScalarConstructorExpression>());
@@ -64,7 +64,7 @@
 
   ASSERT_TRUE(ary->array()->Is<ast::IdentifierExpression>());
   auto* ident = ary->array()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(ary->idx_expr()->Is<ast::BinaryExpression>());
 }
@@ -112,7 +112,7 @@
 
   ASSERT_TRUE(c->func()->Is<ast::IdentifierExpression>());
   auto* func = c->func()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(func->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(func->symbol(), p->get_program().Symbols().Register("a"));
 
   EXPECT_EQ(c->params().size(), 0u);
 }
@@ -130,7 +130,7 @@
 
   ASSERT_TRUE(c->func()->Is<ast::IdentifierExpression>());
   auto* func = c->func()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(func->symbol(), p->get_program().RegisterSymbol("test"));
+  EXPECT_EQ(func->symbol(), p->get_program().Symbols().Register("test"));
 
   EXPECT_EQ(c->params().size(), 3u);
   EXPECT_TRUE(c->params()[0]->Is<ast::ConstructorExpression>());
@@ -180,11 +180,11 @@
   auto* m = e->As<ast::MemberAccessorExpression>();
   ASSERT_TRUE(m->structure()->Is<ast::IdentifierExpression>());
   EXPECT_EQ(m->structure()->As<ast::IdentifierExpression>()->symbol(),
-            p->get_program().RegisterSymbol("a"));
+            p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(m->member()->Is<ast::IdentifierExpression>());
   EXPECT_EQ(m->member()->As<ast::IdentifierExpression>()->symbol(),
-            p->get_program().RegisterSymbol("b"));
+            p->get_program().Symbols().Register("b"));
 }
 
 TEST_F(ParserImplTest, PostfixExpression_MemberAccesssor_InvalidIdent) {
diff --git a/src/reader/wgsl/parser_impl_primary_expression_test.cc b/src/reader/wgsl/parser_impl_primary_expression_test.cc
index 072ade2..9dd8b6e 100644
--- a/src/reader/wgsl/parser_impl_primary_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_primary_expression_test.cc
@@ -41,7 +41,7 @@
   ASSERT_NE(e.value, nullptr);
   ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
   auto* ident = e->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 }
 
 TEST_F(ParserImplTest, PrimaryExpression_TypeDecl) {
diff --git a/src/reader/wgsl/parser_impl_relational_expression_test.cc b/src/reader/wgsl/parser_impl_relational_expression_test.cc
index 57315db..1f9f0db 100644
--- a/src/reader/wgsl/parser_impl_relational_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_relational_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -62,7 +62,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -85,7 +85,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -108,7 +108,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_shift_expression_test.cc b/src/reader/wgsl/parser_impl_shift_expression_test.cc
index 5bdb2f0..e7fe8ea 100644
--- a/src/reader/wgsl/parser_impl_shift_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_shift_expression_test.cc
@@ -39,7 +39,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
@@ -62,7 +62,7 @@
 
   ASSERT_TRUE(rel->lhs()->Is<ast::IdentifierExpression>());
   auto* ident = rel->lhs()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(rel->rhs()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(rel->rhs()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
index 5c4e0cf..c89efcc 100644
--- a/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_body_decl_test.cc
@@ -34,7 +34,7 @@
   ASSERT_EQ(m.value.size(), 1u);
 
   const auto* mem = m.value[0];
-  EXPECT_EQ(mem->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(mem->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(mem->type(), i32);
   EXPECT_EQ(mem->decorations().size(), 0u);
 }
diff --git a/src/reader/wgsl/parser_impl_struct_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decl_test.cc
index ccaaddb..879d0b6 100644
--- a/src/reader/wgsl/parser_impl_struct_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_decl_test.cc
@@ -39,12 +39,12 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->get_program().RegisterSymbol("S"));
+  ASSERT_EQ(s->symbol(), p->get_program().Symbols().Register("S"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
-            p->get_program().RegisterSymbol("a"));
+            p->get_program().Symbols().Register("a"));
   EXPECT_EQ(s->impl()->members()[1]->symbol(),
-            p->get_program().RegisterSymbol("b"));
+            p->get_program().Symbols().Register("b"));
 }
 
 TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
@@ -63,12 +63,12 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->get_program().RegisterSymbol("B"));
+  ASSERT_EQ(s->symbol(), p->get_program().Symbols().Register("B"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
-            p->get_program().RegisterSymbol("a"));
+            p->get_program().Symbols().Register("a"));
   EXPECT_EQ(s->impl()->members()[1]->symbol(),
-            p->get_program().RegisterSymbol("b"));
+            p->get_program().Symbols().Register("b"));
   ASSERT_EQ(s->impl()->decorations().size(), 1u);
   EXPECT_TRUE(s->impl()->decorations()[0]->Is<ast::StructBlockDecoration>());
 }
@@ -90,12 +90,12 @@
   EXPECT_FALSE(s.errored);
   EXPECT_TRUE(s.matched);
   ASSERT_NE(s.value, nullptr);
-  ASSERT_EQ(s->symbol(), p->get_program().RegisterSymbol("S"));
+  ASSERT_EQ(s->symbol(), p->get_program().Symbols().Register("S"));
   ASSERT_EQ(s->impl()->members().size(), 2u);
   EXPECT_EQ(s->impl()->members()[0]->symbol(),
-            p->get_program().RegisterSymbol("a"));
+            p->get_program().Symbols().Register("a"));
   EXPECT_EQ(s->impl()->members()[1]->symbol(),
-            p->get_program().RegisterSymbol("b"));
+            p->get_program().Symbols().Register("b"));
   ASSERT_EQ(s->impl()->decorations().size(), 2u);
   EXPECT_TRUE(s->impl()->decorations()[0]->Is<ast::StructBlockDecoration>());
   EXPECT_TRUE(s->impl()->decorations()[1]->Is<ast::StructBlockDecoration>());
diff --git a/src/reader/wgsl/parser_impl_struct_member_test.cc b/src/reader/wgsl/parser_impl_struct_member_test.cc
index 0460b80..4cbab37 100644
--- a/src/reader/wgsl/parser_impl_struct_member_test.cc
+++ b/src/reader/wgsl/parser_impl_struct_member_test.cc
@@ -39,7 +39,7 @@
   ASSERT_FALSE(m.errored);
   ASSERT_NE(m.value, nullptr);
 
-  EXPECT_EQ(m->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(m->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(m->type(), i32);
   EXPECT_EQ(m->decorations().size(), 0u);
 
@@ -65,7 +65,7 @@
   ASSERT_FALSE(m.errored);
   ASSERT_NE(m.value, nullptr);
 
-  EXPECT_EQ(m->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(m->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(m->type(), i32);
   EXPECT_EQ(m->decorations().size(), 1u);
   EXPECT_TRUE(m->decorations()[0]->Is<ast::StructMemberOffsetDecoration>());
@@ -96,7 +96,7 @@
   ASSERT_FALSE(m.errored);
   ASSERT_NE(m.value, nullptr);
 
-  EXPECT_EQ(m->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(m->symbol(), p->get_program().Symbols().Register("a"));
   EXPECT_EQ(m->type(), i32);
   EXPECT_EQ(m->decorations().size(), 2u);
   EXPECT_TRUE(m->decorations()[0]->Is<ast::StructMemberOffsetDecoration>());
diff --git a/src/reader/wgsl/parser_impl_type_alias_test.cc b/src/reader/wgsl/parser_impl_type_alias_test.cc
index 414714b..a3e877b 100644
--- a/src/reader/wgsl/parser_impl_type_alias_test.cc
+++ b/src/reader/wgsl/parser_impl_type_alias_test.cc
@@ -45,7 +45,7 @@
 TEST_F(ParserImplTest, TypeDecl_ParsesStruct_Ident) {
   auto p = parser("type a = B");
 
-  type::Struct str(p->get_program().RegisterSymbol("B"), {});
+  type::Struct str(p->get_program().Symbols().Register("B"), {});
   p->register_constructed("B", &str);
 
   auto t = p->type_alias();
@@ -55,12 +55,12 @@
   ASSERT_NE(t.value, nullptr);
   ASSERT_TRUE(t->Is<type::Alias>());
   auto* alias = t->As<type::Alias>();
-  EXPECT_EQ(p->get_program().SymbolToName(alias->symbol()), "a");
+  EXPECT_EQ(p->get_program().Symbols().NameFor(alias->symbol()), "a");
   ASSERT_TRUE(alias->type()->Is<type::Struct>());
 
   auto* s = alias->type()->As<type::Struct>();
-  EXPECT_EQ(s->symbol(), p->get_program().RegisterSymbol("B"));
-  EXPECT_EQ(s->symbol(), p->get_program().RegisterSymbol("B"));
+  EXPECT_EQ(s->symbol(), p->get_program().Symbols().Register("B"));
+  EXPECT_EQ(s->symbol(), p->get_program().Symbols().Register("B"));
 }
 
 TEST_F(ParserImplTest, TypeDecl_MissingIdent) {
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index 4164b9f..ae93e54 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -49,7 +49,8 @@
   auto& mod = p->get_program();
 
   auto* int_type = mod.create<type::I32>();
-  auto* alias_type = mod.create<type::Alias>(mod.RegisterSymbol("A"), int_type);
+  auto* alias_type =
+      mod.create<type::Alias>(mod.Symbols().Register("A"), int_type);
 
   p->register_constructed("A", alias_type);
 
@@ -61,7 +62,7 @@
   ASSERT_TRUE(t->Is<type::Alias>());
 
   auto* alias = t->As<type::Alias>();
-  EXPECT_EQ(p->get_program().SymbolToName(alias->symbol()), "A");
+  EXPECT_EQ(p->get_program().Symbols().NameFor(alias->symbol()), "A");
   EXPECT_EQ(alias->type(), int_type);
 }
 
diff --git a/src/reader/wgsl/parser_impl_unary_expression_test.cc b/src/reader/wgsl/parser_impl_unary_expression_test.cc
index c1f4f34..64e0288 100644
--- a/src/reader/wgsl/parser_impl_unary_expression_test.cc
+++ b/src/reader/wgsl/parser_impl_unary_expression_test.cc
@@ -38,7 +38,7 @@
   auto* ary = e->As<ast::ArrayAccessorExpression>();
   ASSERT_TRUE(ary->array()->Is<ast::IdentifierExpression>());
   auto* ident = ary->array()->As<ast::IdentifierExpression>();
-  EXPECT_EQ(ident->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(ident->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_TRUE(ary->idx_expr()->Is<ast::ConstructorExpression>());
   ASSERT_TRUE(ary->idx_expr()->Is<ast::ScalarConstructorExpression>());
diff --git a/src/reader/wgsl/parser_impl_variable_stmt_test.cc b/src/reader/wgsl/parser_impl_variable_stmt_test.cc
index 223c9dc..33ad0ae 100644
--- a/src/reader/wgsl/parser_impl_variable_stmt_test.cc
+++ b/src/reader/wgsl/parser_impl_variable_stmt_test.cc
@@ -32,7 +32,7 @@
   ASSERT_NE(e.value, nullptr);
   ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
   ASSERT_NE(e->variable(), nullptr);
-  EXPECT_EQ(e->variable()->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->variable()->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_EQ(e->source().range.begin.line, 1u);
   ASSERT_EQ(e->source().range.begin.column, 5u);
@@ -51,7 +51,7 @@
   ASSERT_NE(e.value, nullptr);
   ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
   ASSERT_NE(e->variable(), nullptr);
-  EXPECT_EQ(e->variable()->symbol(), p->get_program().RegisterSymbol("a"));
+  EXPECT_EQ(e->variable()->symbol(), p->get_program().Symbols().Register("a"));
 
   ASSERT_EQ(e->source().range.begin.line, 1u);
   ASSERT_EQ(e->source().range.begin.column, 5u);
diff --git a/src/transform/emit_vertex_point_size.cc b/src/transform/emit_vertex_point_size.cc
index d77f344..bbc8f95 100644
--- a/src/transform/emit_vertex_point_size.cc
+++ b/src/transform/emit_vertex_point_size.cc
@@ -51,12 +51,12 @@
 
   // Declare the pointsize builtin output variable.
   auto* pointsize_var = out.program.create<ast::Variable>(
-      Source{},                                   // source
-      out.program.RegisterSymbol(kPointSizeVar),  // symbol
-      ast::StorageClass::kOutput,                 // storage_class
-      f32,                                        // type
-      false,                                      // is_const
-      nullptr,                                    // constructor
+      Source{},                                       // source
+      out.program.Symbols().Register(kPointSizeVar),  // symbol
+      ast::StorageClass::kOutput,                     // storage_class
+      f32,                                            // type
+      false,                                          // is_const
+      nullptr,                                        // constructor
       ast::VariableDecorationList{
           // decorations
           out.program.create<ast::BuiltinDecoration>(Source{},
@@ -68,7 +68,7 @@
   auto* one = out.program.create<ast::ScalarConstructorExpression>(
       Source{}, out.program.create<ast::FloatLiteral>(Source{}, f32, 1.0f));
   auto* pointsize_ident = out.program.create<ast::IdentifierExpression>(
-      Source{}, out.program.RegisterSymbol(kPointSizeVar));
+      Source{}, out.program.Symbols().Register(kPointSizeVar));
   auto* pointsize_assign = out.program.create<ast::AssignmentStatement>(
       Source{}, pointsize_ident, one);
 
diff --git a/src/transform/first_index_offset.cc b/src/transform/first_index_offset.cc
index b2d83a5..d3137f4 100644
--- a/src/transform/first_index_offset.cc
+++ b/src/transform/first_index_offset.cc
@@ -65,13 +65,13 @@
                                             ast::Variable* in,
                                             std::string new_name) {
   return ctx->dst->create<ast::Variable>(
-      ctx->Clone(in->source()),            // source
-      ctx->dst->RegisterSymbol(new_name),  // symbol
-      in->storage_class(),                 // storage_class
-      ctx->Clone(in->type()),              // type
-      in->is_const(),                      // is_const
-      ctx->Clone(in->constructor()),       // constructor
-      ctx->Clone(in->decorations()));      // decorations
+      ctx->Clone(in->source()),                // source
+      ctx->dst->Symbols().Register(new_name),  // symbol
+      in->storage_class(),                     // storage_class
+      ctx->Clone(in->type()),                  // type
+      in->is_const(),                          // is_const
+      ctx->Clone(in->constructor()),           // constructor
+      ctx->Clone(in->decorations()));          // decorations
 }
 
 }  // namespace
@@ -85,7 +85,7 @@
   // First do a quick check to see if the transform has already been applied.
   for (ast::Variable* var : in->AST().GlobalVariables()) {
     if (auto* dec_var = var->As<ast::Variable>()) {
-      if (dec_var->symbol() == in->GetSymbol(kBufferName)) {
+      if (dec_var->symbol() == in->Symbols().Get(kBufferName)) {
         diag::Diagnostic err;
         err.message = "First index offset transform has already been applied.";
         err.severity = diag::Severity::Error;
@@ -137,13 +137,13 @@
               has_vertex_index_ = true;
               return clone_variable_with_new_name(
                   ctx, var,
-                  kIndexOffsetPrefix + in->SymbolToName(var->symbol()));
+                  kIndexOffsetPrefix + in->Symbols().NameFor(var->symbol()));
             } else if (blt_type == ast::Builtin::kInstanceIndex) {
               instance_index_sym = var->symbol();
               has_instance_index_ = true;
               return clone_variable_with_new_name(
                   ctx, var,
-                  kIndexOffsetPrefix + in->SymbolToName(var->symbol()));
+                  kIndexOffsetPrefix + in->Symbols().NameFor(var->symbol()));
             }
           }
         }
@@ -162,12 +162,12 @@
                  func->local_referenced_builtin_variables()) {
               if (data.second->value() == ast::Builtin::kVertexIndex) {
                 statements.emplace_back(CreateFirstIndexOffset(
-                    in->SymbolToName(vertex_index_sym), kFirstVertexName,
+                    in->Symbols().NameFor(vertex_index_sym), kFirstVertexName,
                     buffer_var, ctx->dst));
               } else if (data.second->value() == ast::Builtin::kInstanceIndex) {
                 statements.emplace_back(CreateFirstIndexOffset(
-                    in->SymbolToName(instance_index_sym), kFirstInstanceName,
-                    buffer_var, ctx->dst));
+                    in->Symbols().NameFor(instance_index_sym),
+                    kFirstInstanceName, buffer_var, ctx->dst));
               }
             }
             return CloneWithStatementsAtStart(ctx, func, statements);
@@ -204,7 +204,7 @@
     member_dec.push_back(
         dst->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
     members.push_back(dst->create<ast::StructMember>(
-        Source{}, dst->RegisterSymbol(kFirstVertexName), u32_type,
+        Source{}, dst->Symbols().Register(kFirstVertexName), u32_type,
         std::move(member_dec)));
     vertex_index_offset_ = offset;
     offset += 4;
@@ -215,7 +215,7 @@
     member_dec.push_back(
         dst->create<ast::StructMemberOffsetDecoration>(Source{}, offset));
     members.push_back(dst->create<ast::StructMember>(
-        Source{}, dst->RegisterSymbol(kFirstInstanceName), u32_type,
+        Source{}, dst->Symbols().Register(kFirstInstanceName), u32_type,
         std::move(member_dec)));
     instance_index_offset_ = offset;
     offset += 4;
@@ -225,16 +225,16 @@
   decos.push_back(dst->create<ast::StructBlockDecoration>(Source{}));
 
   auto* struct_type = dst->create<type::Struct>(
-      dst->RegisterSymbol(kStructName),
+      dst->Symbols().Register(kStructName),
       dst->create<ast::Struct>(Source{}, std::move(members), std::move(decos)));
 
   auto* idx_var = dst->create<ast::Variable>(
-      Source{},                          // source
-      dst->RegisterSymbol(kBufferName),  // symbol
-      ast::StorageClass::kUniform,       // storage_class
-      struct_type,                       // type
-      false,                             // is_const
-      nullptr,                           // constructor
+      Source{},                              // source
+      dst->Symbols().Register(kBufferName),  // symbol
+      ast::StorageClass::kUniform,           // storage_class
+      struct_type,                           // type
+      false,                                 // is_const
+      nullptr,                               // constructor
       ast::VariableDecorationList{
           dst->create<ast::BindingDecoration>(Source{}, binding_),
           dst->create<ast::GroupDecoration>(Source{}, group_),
@@ -259,19 +259,19 @@
   auto* constructor = dst->create<ast::BinaryExpression>(
       Source{}, ast::BinaryOp::kAdd,
       dst->create<ast::IdentifierExpression>(Source{},
-                                             dst->RegisterSymbol(lhs_name)),
+                                             dst->Symbols().Register(lhs_name)),
       dst->create<ast::MemberAccessorExpression>(
           Source{}, buffer,
           dst->create<ast::IdentifierExpression>(
-              Source{}, dst->RegisterSymbol(field_name))));
-  auto* var =
-      dst->create<ast::Variable>(Source{},                            // source
-                                 dst->RegisterSymbol(original_name),  // symbol
-                                 ast::StorageClass::kNone,  // storage_class
-                                 dst->create<type::U32>(),  // type
-                                 true,                      // is_const
-                                 constructor,               // constructor
-                                 ast::VariableDecorationList{});  // decorations
+              Source{}, dst->Symbols().Register(field_name))));
+  auto* var = dst->create<ast::Variable>(
+      Source{},                                // source
+      dst->Symbols().Register(original_name),  // symbol
+      ast::StorageClass::kNone,                // storage_class
+      dst->create<type::U32>(),                // type
+      true,                                    // is_const
+      constructor,                             // constructor
+      ast::VariableDecorationList{});          // decorations
   return dst->create<ast::VariableDeclStatement>(Source{}, var);
 }
 
diff --git a/src/transform/vertex_pulling.cc b/src/transform/vertex_pulling.cc
index 152d33d..081c8c9 100644
--- a/src/transform/vertex_pulling.cc
+++ b/src/transform/vertex_pulling.cc
@@ -85,8 +85,8 @@
   }
 
   // Find entry point
-  auto* func = in->AST().Functions().Find(in->GetSymbol(cfg.entry_point_name),
-                                          ast::PipelineStage::kVertex);
+  auto* func = in->AST().Functions().Find(
+      in->Symbols().Get(cfg.entry_point_name), ast::PipelineStage::kVertex);
   if (func == nullptr) {
     diag::Diagnostic err;
     err.severity = diag::Severity::Error;
@@ -158,7 +158,7 @@
     for (auto* d : v->decorations()) {
       if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
         if (builtin->value() == ast::Builtin::kVertexIndex) {
-          vertex_index_name = in->SymbolToName(v->symbol());
+          vertex_index_name = in->Symbols().NameFor(v->symbol());
           return;
         }
       }
@@ -169,12 +169,12 @@
   vertex_index_name = kDefaultVertexIndexName;
 
   auto* var = out->create<ast::Variable>(
-      Source{},                                // source
-      out->RegisterSymbol(vertex_index_name),  // symbol
-      ast::StorageClass::kInput,               // storage_class
-      GetI32Type(),                            // type
-      false,                                   // is_const
-      nullptr,                                 // constructor
+      Source{},                                    // source
+      out->Symbols().Register(vertex_index_name),  // symbol
+      ast::StorageClass::kInput,                   // storage_class
+      GetI32Type(),                                // type
+      false,                                       // is_const
+      nullptr,                                     // constructor
       ast::VariableDecorationList{
           // decorations
           out->create<ast::BuiltinDecoration>(Source{},
@@ -205,7 +205,7 @@
     for (auto* d : v->decorations()) {
       if (auto* builtin = d->As<ast::BuiltinDecoration>()) {
         if (builtin->value() == ast::Builtin::kInstanceIndex) {
-          instance_index_name = in->SymbolToName(v->symbol());
+          instance_index_name = in->Symbols().NameFor(v->symbol());
           return;
         }
       }
@@ -216,12 +216,12 @@
   instance_index_name = kDefaultInstanceIndexName;
 
   auto* var = out->create<ast::Variable>(
-      Source{},                                  // source
-      out->RegisterSymbol(instance_index_name),  // symbol
-      ast::StorageClass::kInput,                 // storage_class
-      GetI32Type(),                              // type
-      false,                                     // is_const
-      nullptr,                                   // constructor
+      Source{},                                      // source
+      out->Symbols().Register(instance_index_name),  // symbol
+      ast::StorageClass::kInput,                     // storage_class
+      GetI32Type(),                                  // type
+      false,                                         // is_const
+      nullptr,                                       // constructor
       ast::VariableDecorationList{
           // decorations
           out->create<ast::BuiltinDecoration>(Source{},
@@ -274,26 +274,26 @@
       out->create<ast::StructMemberOffsetDecoration>(Source{}, 0u));
 
   members.push_back(out->create<ast::StructMember>(
-      Source{}, out->RegisterSymbol(kStructBufferName), internal_array_type,
+      Source{}, out->Symbols().Register(kStructBufferName), internal_array_type,
       std::move(member_dec)));
 
   ast::StructDecorationList decos;
   decos.push_back(out->create<ast::StructBlockDecoration>(Source{}));
 
   auto* struct_type = out->create<type::Struct>(
-      out->RegisterSymbol(kStructName),
+      out->Symbols().Register(kStructName),
       out->create<ast::Struct>(Source{}, std::move(members), std::move(decos)));
 
   for (uint32_t i = 0; i < cfg.vertex_state.size(); ++i) {
     // The decorated variable with struct type
     std::string name = GetVertexBufferName(i);
     auto* var = out->create<ast::Variable>(
-        Source{},                     // source
-        out->RegisterSymbol(name),    // symbol
-        ast::StorageClass::kStorage,  // storage_class
-        struct_type,                  // type
-        false,                        // is_const
-        nullptr,                      // constructor
+        Source{},                       // source
+        out->Symbols().Register(name),  // symbol
+        ast::StorageClass::kStorage,    // storage_class
+        struct_type,                    // type
+        false,                          // is_const
+        nullptr,                        // constructor
         ast::VariableDecorationList{
             // decorations
             out->create<ast::BindingDecoration>(Source{}, i),
@@ -313,13 +313,13 @@
   // Declare the |kPullingPosVarName| variable in the shader
   auto* pos_declaration = out->create<ast::VariableDeclStatement>(
       Source{}, out->create<ast::Variable>(
-                    Source{},                                 // source
-                    out->RegisterSymbol(kPullingPosVarName),  // symbol
-                    ast::StorageClass::kFunction,             // storage_class
-                    GetI32Type(),                             // type
-                    false,                                    // is_const
-                    nullptr,                                  // constructor
-                    ast::VariableDecorationList{}));          // decorations
+                    Source{},                                     // source
+                    out->Symbols().Register(kPullingPosVarName),  // symbol
+                    ast::StorageClass::kFunction,     // storage_class
+                    GetI32Type(),                     // type
+                    false,                            // is_const
+                    nullptr,                          // constructor
+                    ast::VariableDecorationList{}));  // decorations
 
   // |kPullingPosVarName| refers to the byte location of the current read. We
   // declare a variable in the shader to avoid having to reuse Expression
@@ -342,7 +342,7 @@
                       : instance_index_name;
       // Identifier to index by
       auto* index_identifier = out->create<ast::IdentifierExpression>(
-          Source{}, out->RegisterSymbol(name));
+          Source{}, out->Symbols().Register(name));
 
       // An expression for the start of the read in the buffer in bytes
       auto* pos_value = out->create<ast::BinaryExpression>(
@@ -357,11 +357,11 @@
           Source{}, CreatePullingPositionIdent(), pos_value);
       stmts.emplace_back(set_pos_expr);
 
-      auto ident_name = in->SymbolToName(v->symbol());
+      auto ident_name = in->Symbols().NameFor(v->symbol());
       stmts.emplace_back(out->create<ast::AssignmentStatement>(
           Source{},
           out->create<ast::IdentifierExpression>(
-              Source{}, out->RegisterSymbol(ident_name)),
+              Source{}, out->Symbols().Register(ident_name)),
           AccessByFormat(i, attribute_desc.format)));
     }
   }
@@ -376,7 +376,7 @@
 
 ast::Expression* VertexPulling::State::CreatePullingPositionIdent() const {
   return out->create<ast::IdentifierExpression>(
-      Source{}, out->RegisterSymbol(kPullingPosVarName));
+      Source{}, out->Symbols().Register(kPullingPosVarName));
 }
 
 ast::Expression* VertexPulling::State::AccessByFormat(
@@ -420,9 +420,9 @@
       out->create<ast::MemberAccessorExpression>(
           Source{},
           out->create<ast::IdentifierExpression>(
-              Source{}, out->RegisterSymbol(vbuf_name)),
+              Source{}, out->Symbols().Register(vbuf_name)),
           out->create<ast::IdentifierExpression>(
-              Source{}, out->RegisterSymbol(kStructBufferName))),
+              Source{}, out->Symbols().Register(kStructBufferName))),
       out->create<ast::BinaryExpression>(Source{}, ast::BinaryOp::kDivide, pos,
                                          GenUint(4)));
 }
diff --git a/src/type_determiner.cc b/src/type_determiner.cc
index edbed10..6c323d8 100644
--- a/src/type_determiner.cc
+++ b/src/type_determiner.cc
@@ -407,7 +407,7 @@
         if (callee_func == nullptr) {
           set_error(expr->source(),
                     "unable to find called function: " +
-                        program_->SymbolToName(ident->symbol()));
+                        program_->Symbols().NameFor(ident->symbol()));
           return false;
         }
 
@@ -433,7 +433,7 @@
     auto func_sym = expr->func()->As<ast::IdentifierExpression>()->symbol();
     set_error(expr->source(),
               "v-0005: function must be declared before use: '" +
-                  program_->SymbolToName(func_sym) + "'");
+                  program_->Symbols().NameFor(func_sym) + "'");
     return false;
   }
 
@@ -519,8 +519,9 @@
                                         ast::CallExpression* expr) {
   if (ast::intrinsic::IsDerivative(ident->intrinsic())) {
     if (expr->params().size() != 1) {
-      set_error(expr->source(), "incorrect number of parameters for " +
-                                    program_->SymbolToName(ident->symbol()));
+      set_error(expr->source(),
+                "incorrect number of parameters for " +
+                    program_->Symbols().NameFor(ident->symbol()));
       return false;
     }
 
@@ -540,8 +541,9 @@
   }
   if (ast::intrinsic::IsFloatClassificationIntrinsic(ident->intrinsic())) {
     if (expr->params().size() != 1) {
-      set_error(expr->source(), "incorrect number of parameters for " +
-                                    program_->SymbolToName(ident->symbol()));
+      set_error(expr->source(),
+                "incorrect number of parameters for " +
+                    program_->Symbols().NameFor(ident->symbol()));
       return false;
     }
 
@@ -561,8 +563,9 @@
 
     auto* texture_param = expr->params()[0];
     if (!texture_param->result_type()->UnwrapAll()->Is<type::Texture>()) {
-      set_error(expr->source(), "invalid first argument for " +
-                                    program_->SymbolToName(ident->symbol()));
+      set_error(expr->source(),
+                "invalid first argument for " +
+                    program_->Symbols().NameFor(ident->symbol()));
       return false;
     }
     type::Texture* texture =
@@ -674,7 +677,7 @@
     if (expr->params().size() != param.count) {
       set_error(expr->source(),
                 "incorrect number of parameters for " +
-                    program_->SymbolToName(ident->symbol()) + ", got " +
+                    program_->Symbols().NameFor(ident->symbol()) + ", got " +
                     std::to_string(expr->params().size()) + " and expected " +
                     std::to_string(param.count));
       return false;
@@ -747,10 +750,10 @@
   }
   if (ident->intrinsic() == ast::Intrinsic::kSelect) {
     if (expr->params().size() != 3) {
-      set_error(expr->source(), "incorrect number of parameters for " +
-                                    program_->SymbolToName(ident->symbol()) +
-                                    " expected 3 got " +
-                                    std::to_string(expr->params().size()));
+      set_error(expr->source(),
+                "incorrect number of parameters for " +
+                    program_->Symbols().NameFor(ident->symbol()) +
+                    " expected 3 got " + std::to_string(expr->params().size()));
       return false;
     }
 
@@ -768,14 +771,14 @@
     }
   }
   if (data == nullptr) {
-    error_ =
-        "unable to find intrinsic " + program_->SymbolToName(ident->symbol());
+    error_ = "unable to find intrinsic " +
+             program_->Symbols().NameFor(ident->symbol());
     return false;
   }
 
   if (expr->params().size() != data->param_count) {
     set_error(expr->source(), "incorrect number of parameters for " +
-                                  program_->SymbolToName(ident->symbol()) +
+                                  program_->Symbols().NameFor(ident->symbol()) +
                                   ". Expected " +
                                   std::to_string(data->param_count) + " got " +
                                   std::to_string(expr->params().size()));
@@ -793,7 +796,7 @@
             !result_types.back()->is_integer_scalar_or_vector()) {
           set_error(expr->source(),
                     "incorrect type for " +
-                        program_->SymbolToName(ident->symbol()) + ". " +
+                        program_->Symbols().NameFor(ident->symbol()) + ". " +
                         "Requires float or int, scalar or vector values");
           return false;
         }
@@ -802,7 +805,7 @@
         if (!result_types.back()->is_float_scalar_or_vector()) {
           set_error(expr->source(),
                     "incorrect type for " +
-                        program_->SymbolToName(ident->symbol()) + ". " +
+                        program_->Symbols().NameFor(ident->symbol()) + ". " +
                         "Requires float scalar or float vector values");
           return false;
         }
@@ -812,7 +815,7 @@
         if (!result_types.back()->is_integer_scalar_or_vector()) {
           set_error(expr->source(),
                     "incorrect type for " +
-                        program_->SymbolToName(ident->symbol()) + ". " +
+                        program_->Symbols().NameFor(ident->symbol()) + ". " +
                         "Requires integer scalar or integer vector values");
           return false;
         }
@@ -821,7 +824,7 @@
         if (!result_types.back()->is_float_vector()) {
           set_error(expr->source(),
                     "incorrect type for " +
-                        program_->SymbolToName(ident->symbol()) + ". " +
+                        program_->Symbols().NameFor(ident->symbol()) + ". " +
                         "Requires float vector values");
           return false;
         }
@@ -830,7 +833,7 @@
                 data->vector_size) {
           set_error(expr->source(),
                     "incorrect vector size for " +
-                        program_->SymbolToName(ident->symbol()) + ". " +
+                        program_->Symbols().NameFor(ident->symbol()) + ". " +
                         "Requires " + std::to_string(data->vector_size) +
                         " elements");
           return false;
@@ -840,7 +843,7 @@
         if (!result_types.back()->Is<type::Matrix>()) {
           set_error(expr->source(),
                     "incorrect type for " +
-                        program_->SymbolToName(ident->symbol()) +
+                        program_->Symbols().NameFor(ident->symbol()) +
                         ". Requires matrix value");
           return false;
         }
@@ -851,8 +854,9 @@
   // Verify all the parameter types match
   for (size_t i = 1; i < data->param_count; ++i) {
     if (result_types[0] != result_types[i]) {
-      set_error(expr->source(), "mismatched parameter types for " +
-                                    program_->SymbolToName(ident->symbol()));
+      set_error(expr->source(),
+                "mismatched parameter types for " +
+                    program_->Symbols().NameFor(ident->symbol()));
       return false;
     }
   }
@@ -919,14 +923,14 @@
   if (!SetIntrinsicIfNeeded(expr)) {
     set_error(expr->source(),
               "v-0006: identifier must be declared before use: " +
-                  program_->SymbolToName(symbol));
+                  program_->Symbols().NameFor(symbol));
     return false;
   }
   return true;
 }
 
 bool TypeDeterminer::SetIntrinsicIfNeeded(ast::IdentifierExpression* ident) {
-  auto name = program_->SymbolToName(ident->symbol());
+  auto name = program_->Symbols().NameFor(ident->symbol());
   if (name == "abs") {
     ident->set_intrinsic(ast::Intrinsic::kAbs);
   } else if (name == "acos") {
@@ -1099,9 +1103,9 @@
     }
 
     if (ret == nullptr) {
-      set_error(
-          expr->source(),
-          "struct member " + program_->SymbolToName(symbol) + " not found");
+      set_error(expr->source(), "struct member " +
+                                    program_->Symbols().NameFor(symbol) +
+                                    " not found");
       return false;
     }
 
@@ -1112,7 +1116,7 @@
   } else if (auto* vec = data_type->As<type::Vector>()) {
     // TODO(dsinclair): Swizzle, record into the identifier experesion
 
-    auto size = program_->SymbolToName(expr->member()->symbol()).size();
+    auto size = program_->Symbols().NameFor(expr->member()->symbol()).size();
     if (size == 1) {
       // A single element swizzle is just the type of the vector.
       ret = vec->type();
diff --git a/src/type_determiner_test.cc b/src/type_determiner_test.cc
index e6b5705..8f7419a 100644
--- a/src/type_determiner_test.cc
+++ b/src/type_determiner_test.cc
@@ -2782,17 +2782,17 @@
 
   const auto& b_eps = func_b->ancestor_entry_points();
   ASSERT_EQ(2u, b_eps.size());
-  EXPECT_EQ(mod->RegisterSymbol("ep_1"), b_eps[0]);
-  EXPECT_EQ(mod->RegisterSymbol("ep_2"), b_eps[1]);
+  EXPECT_EQ(mod->Symbols().Register("ep_1"), b_eps[0]);
+  EXPECT_EQ(mod->Symbols().Register("ep_2"), b_eps[1]);
 
   const auto& a_eps = func_a->ancestor_entry_points();
   ASSERT_EQ(1u, a_eps.size());
-  EXPECT_EQ(mod->RegisterSymbol("ep_1"), a_eps[0]);
+  EXPECT_EQ(mod->Symbols().Register("ep_1"), a_eps[0]);
 
   const auto& c_eps = func_c->ancestor_entry_points();
   ASSERT_EQ(2u, c_eps.size());
-  EXPECT_EQ(mod->RegisterSymbol("ep_1"), c_eps[0]);
-  EXPECT_EQ(mod->RegisterSymbol("ep_2"), c_eps[1]);
+  EXPECT_EQ(mod->Symbols().Register("ep_1"), c_eps[0]);
+  EXPECT_EQ(mod->Symbols().Register("ep_2"), c_eps[1]);
 
   EXPECT_TRUE(ep_1->ancestor_entry_points().empty());
   EXPECT_TRUE(ep_2->ancestor_entry_points().empty());
diff --git a/src/validator/validator_impl.cc b/src/validator/validator_impl.cc
index 1df8e8a..0ce8526 100644
--- a/src/validator/validator_impl.cc
+++ b/src/validator/validator_impl.cc
@@ -99,7 +99,7 @@
               add_error(member->source(), "v-0031",
                         "a struct containing a runtime-sized array "
                         "must be in the 'storage' storage class: '" +
-                            program_->SymbolToName(st->symbol()) + "'");
+                            program_->Symbols().NameFor(st->symbol()) + "'");
               return false;
             }
           }
@@ -116,7 +116,7 @@
     if (variable_stack_.has(var->symbol())) {
       add_error(var->source(), "v-0011",
                 "redeclared global identifier '" +
-                    program_->SymbolToName(var->symbol()) + "'");
+                    program_->Symbols().NameFor(var->symbol()) + "'");
       return false;
     }
     if (!var->is_const() && var->storage_class() == ast::StorageClass::kNone) {
@@ -140,7 +140,7 @@
     if (function_stack_.has(func->symbol())) {
       add_error(func->source(), "v-0016",
                 "function names must be unique '" +
-                    program_->SymbolToName(func->symbol()) + "'");
+                    program_->Symbols().NameFor(func->symbol()) + "'");
       return false;
     }
 
@@ -163,14 +163,14 @@
       if (!func->params().empty()) {
         add_error(func->source(), "v-0023",
                   "Entry point function must accept no parameters: '" +
-                      program_->SymbolToName(func->symbol()) + "'");
+                      program_->Symbols().NameFor(func->symbol()) + "'");
         return false;
       }
 
       if (!func->return_type()->Is<type::Void>()) {
         add_error(func->source(), "v-0024",
                   "Entry point function must return void: '" +
-                      program_->SymbolToName(func->symbol()) + "'");
+                      program_->Symbols().NameFor(func->symbol()) + "'");
         return false;
       }
       auto stage_deco_count = 0;
@@ -274,8 +274,9 @@
     if (is_global) {
       error_code = "v-0013";
     }
-    add_error(decl->source(), error_code,
-              "redeclared identifier '" + program_->SymbolToName(symbol) + "'");
+    add_error(
+        decl->source(), error_code,
+        "redeclared identifier '" + program_->Symbols().NameFor(symbol) + "'");
     return false;
   }
   // TODO(dneto): Check type compatibility of the initializer.
@@ -415,13 +416,13 @@
       if (!function_stack_.has(symbol)) {
         add_error(expr->source(), "v-0005",
                   "function must be declared before use: '" +
-                      program_->SymbolToName(symbol) + "'");
+                      program_->Symbols().NameFor(symbol) + "'");
         return false;
       }
       if (symbol == current_function_->symbol()) {
         add_error(expr->source(), "v-0004",
                   "recursion is not allowed: '" +
-                      program_->SymbolToName(symbol) + "'");
+                      program_->Symbols().NameFor(symbol) + "'");
         return false;
       }
     }
@@ -447,15 +448,15 @@
     if (var->is_const()) {
       add_error(assign->source(), "v-0021",
                 "cannot re-assign a constant: '" +
-                    program_->SymbolToName(ident->symbol()) + "'");
+                    program_->Symbols().NameFor(ident->symbol()) + "'");
       return false;
     }
   } else {
     // The identifier is not defined. This should already have been caught
     // when validating the subexpression.
-    add_error(
-        ident->source(), "v-0006",
-        "'" + program_->SymbolToName(ident->symbol()) + "' is not declared");
+    add_error(ident->source(), "v-0006",
+              "'" + program_->Symbols().NameFor(ident->symbol()) +
+                  "' is not declared");
     return false;
   }
   return true;
@@ -525,9 +526,9 @@
 bool ValidatorImpl::ValidateIdentifier(const ast::IdentifierExpression* ident) {
   ast::Variable* var;
   if (!variable_stack_.get(ident->symbol(), &var)) {
-    add_error(
-        ident->source(), "v-0006",
-        "'" + program_->SymbolToName(ident->symbol()) + "' is not declared");
+    add_error(ident->source(), "v-0006",
+              "'" + program_->Symbols().NameFor(ident->symbol()) +
+                  "' is not declared");
     return false;
   }
   return true;
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 9fdbc89..b153aff 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -232,7 +232,8 @@
     // HLSL typedef is for intrinsic types only. For an alias'd struct,
     // generate a secondary struct with the new name.
     if (auto* str = alias->type()->As<type::Struct>()) {
-      if (!EmitStructType(out, str, program_->SymbolToName(alias->symbol()))) {
+      if (!EmitStructType(out, str,
+                          program_->Symbols().NameFor(alias->symbol()))) {
         return false;
       }
       return true;
@@ -241,10 +242,10 @@
     if (!EmitType(out, alias->type(), "")) {
       return false;
     }
-    out << " " << namer_.NameFor(program_->SymbolToName(alias->symbol())) << ";"
-        << std::endl;
+    out << " " << namer_.NameFor(program_->Symbols().NameFor(alias->symbol()))
+        << ";" << std::endl;
   } else if (auto* str = ty->As<type::Struct>()) {
-    if (!EmitStructType(out, str, program_->SymbolToName(str->symbol()))) {
+    if (!EmitStructType(out, str, program_->Symbols().NameFor(str->symbol()))) {
       return false;
     }
   } else {
@@ -623,7 +624,7 @@
     return true;
   }
 
-  auto name = program_->SymbolToName(ident->symbol());
+  auto name = program_->Symbols().NameFor(ident->symbol());
   auto caller_sym = ident->symbol();
   auto it = ep_func_name_remapped_.find(current_ep_sym_.to_str() + "_" +
                                         caller_sym.to_str());
@@ -633,8 +634,8 @@
 
   auto* func = program_->AST().Functions().Find(ident->symbol());
   if (func == nullptr) {
-    error_ =
-        "Unable to find function: " + program_->SymbolToName(ident->symbol());
+    error_ = "Unable to find function: " +
+             program_->Symbols().NameFor(ident->symbol());
     return false;
   }
 
@@ -868,7 +869,7 @@
       break;
     default:
       error_ = "Internal compiler error: Unhandled texture intrinsic '" +
-               program_->SymbolToName(ident->symbol()) + "'";
+               program_->Symbols().NameFor(ident->symbol()) + "'";
       return false;
   }
 
@@ -972,7 +973,7 @@
     case ast::Intrinsic::kMax:
     case ast::Intrinsic::kMin:
     case ast::Intrinsic::kClamp:
-      out = program_->SymbolToName(ident->symbol());
+      out = program_->Symbols().NameFor(ident->symbol());
       break;
     case ast::Intrinsic::kFaceForward:
       out = "faceforward";
@@ -987,8 +988,8 @@
       out = "smoothstep";
       break;
     default:
-      error_ =
-          "Unknown builtin method: " + program_->SymbolToName(ident->symbol());
+      error_ = "Unknown builtin method: " +
+               program_->Symbols().NameFor(ident->symbol());
       return "";
   }
 
@@ -1168,7 +1169,7 @@
       out << name << ".";
     }
   }
-  out << namer_.NameFor(program_->SymbolToName(ident->symbol()));
+  out << namer_.NameFor(program_->Symbols().NameFor(ident->symbol()));
 
   return true;
 }
@@ -1330,12 +1331,12 @@
     auto ep_name = ep_sym.to_str();
     // TODO(dsinclair): The SymbolToName should go away and just use
     // to_str() here when the conversion is complete.
-    name = generate_name(program_->SymbolToName(func->symbol()) + "_" +
-                         program_->SymbolToName(ep_sym));
+    name = generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                         program_->Symbols().NameFor(ep_sym));
     ep_func_name_remapped_[ep_name + "_" + func_name] = name;
   } else {
     // TODO(dsinclair): this should be updated to a remapped name
-    name = namer_.NameFor(program_->SymbolToName(func->symbol()));
+    name = namer_.NameFor(program_->Symbols().NameFor(func->symbol()));
   }
 
   out << name << "(";
@@ -1371,12 +1372,12 @@
     }
     first = false;
 
-    if (!EmitType(out, v->type(), program_->SymbolToName(v->symbol()))) {
+    if (!EmitType(out, v->type(), program_->Symbols().NameFor(v->symbol()))) {
       return false;
     }
     // Array name is output as part of the type
     if (!v->type()->Is<type::Array>()) {
-      out << " " << program_->SymbolToName(v->symbol());
+      out << " " << program_->Symbols().NameFor(v->symbol());
     }
   }
 
@@ -1430,7 +1431,7 @@
     auto* binding = data.second.binding;
     if (binding == nullptr) {
       error_ = "unable to find binding information for uniform: " +
-               program_->SymbolToName(var->symbol());
+               program_->Symbols().NameFor(var->symbol());
       return false;
     }
     // auto* set = data.second.set;
@@ -1444,9 +1445,9 @@
 
     auto* type = var->type()->UnwrapIfNeeded();
     if (auto* strct = type->As<type::Struct>()) {
-      out << "ConstantBuffer<" << program_->SymbolToName(strct->symbol())
-          << "> " << program_->SymbolToName(var->symbol()) << " : register(b"
-          << binding->value() << ");" << std::endl;
+      out << "ConstantBuffer<" << program_->Symbols().NameFor(strct->symbol())
+          << "> " << program_->Symbols().NameFor(var->symbol())
+          << " : register(b" << binding->value() << ");" << std::endl;
     } else {
       // TODO(dsinclair): There is outstanding spec work to require all uniform
       // buffers to be [[block]] decorated, which means structs. This is
@@ -1454,7 +1455,7 @@
       // is not a block.
       // Relevant: https://github.com/gpuweb/gpuweb/issues/1004
       //           https://github.com/gpuweb/gpuweb/issues/1008
-      auto name = "cbuffer_" + program_->SymbolToName(var->symbol());
+      auto name = "cbuffer_" + program_->Symbols().NameFor(var->symbol());
       out << "cbuffer " << name << " : register(b" << binding->value() << ") {"
           << std::endl;
 
@@ -1463,7 +1464,8 @@
       if (!EmitType(out, type, "")) {
         return false;
       }
-      out << " " << program_->SymbolToName(var->symbol()) << ";" << std::endl;
+      out << " " << program_->Symbols().NameFor(var->symbol()) << ";"
+          << std::endl;
       decrement_indent();
       out << "};" << std::endl;
     }
@@ -1495,7 +1497,7 @@
     if (ac->IsReadWrite()) {
       out << "RW";
     }
-    out << "ByteAddressBuffer " << program_->SymbolToName(var->symbol())
+    out << "ByteAddressBuffer " << program_->Symbols().NameFor(var->symbol())
         << " : register(u" << binding->value() << ");" << std::endl;
     emitted_storagebuffer = true;
   }
@@ -1504,8 +1506,9 @@
   }
 
   if (!in_variables.empty()) {
-    auto in_struct_name = generate_name(program_->SymbolToName(func->symbol()) +
-                                        "_" + kInStructNameSuffix);
+    auto in_struct_name =
+        generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                      kInStructNameSuffix);
     auto in_var_name = generate_name(kTintStructInVarPrefix);
     ep_sym_to_in_data_[func->symbol()] = {in_struct_name, in_var_name};
 
@@ -1519,11 +1522,12 @@
       auto* deco = data.second;
 
       make_indent(out);
-      if (!EmitType(out, var->type(), program_->SymbolToName(var->symbol()))) {
+      if (!EmitType(out, var->type(),
+                    program_->Symbols().NameFor(var->symbol()))) {
         return false;
       }
 
-      out << " " << program_->SymbolToName(var->symbol()) << " : ";
+      out << " " << program_->Symbols().NameFor(var->symbol()) << " : ";
       if (auto* location = deco->As<ast::LocationDecoration>()) {
         if (func->pipeline_stage() == ast::PipelineStage::kCompute) {
           error_ = "invalid location variable for pipeline stage";
@@ -1550,8 +1554,9 @@
   }
 
   if (!outvariables.empty()) {
-    auto outstruct_name = generate_name(program_->SymbolToName(func->symbol()) +
-                                        "_" + kOutStructNameSuffix);
+    auto outstruct_name =
+        generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                      kOutStructNameSuffix);
     auto outvar_name = generate_name(kTintStructOutVarPrefix);
     ep_sym_to_out_data_[func->symbol()] = {outstruct_name, outvar_name};
 
@@ -1564,11 +1569,12 @@
       auto* deco = data.second;
 
       make_indent(out);
-      if (!EmitType(out, var->type(), program_->SymbolToName(var->symbol()))) {
+      if (!EmitType(out, var->type(),
+                    program_->Symbols().NameFor(var->symbol()))) {
         return false;
       }
 
-      out << " " << program_->SymbolToName(var->symbol()) << " : ";
+      out << " " << program_->Symbols().NameFor(var->symbol()) << " : ";
 
       if (auto* location = deco->As<ast::LocationDecoration>()) {
         auto loc = location->value();
@@ -1651,7 +1657,8 @@
     out << "void";
   }
   // TODO(dsinclair): This should output the remapped name
-  out << " " << namer_.NameFor(program_->SymbolToName(current_ep_sym_)) << "(";
+  out << " " << namer_.NameFor(program_->Symbols().NameFor(current_ep_sym_))
+      << "(";
 
   auto in_data = ep_sym_to_in_data_.find(current_ep_sym_);
   if (in_data != ep_sym_to_in_data_.end()) {
@@ -1799,7 +1806,7 @@
         }
         out << pre.str();
 
-        out << program_->SymbolToName(var->symbol()) << " = ";
+        out << program_->Symbols().NameFor(var->symbol()) << " = ";
         if (var->constructor() != nullptr) {
           out << constructor_out.str();
         } else {
@@ -1862,7 +1869,7 @@
         //
         // This must be a single element swizzle if we've got a vector at this
         // point.
-        if (program_->SymbolToName(mem->member()->symbol()).size() != 1) {
+        if (program_->Symbols().NameFor(mem->member()->symbol()).size() != 1) {
           error_ =
               "Encountered multi-element swizzle when should have only one "
               "level";
@@ -1874,7 +1881,7 @@
         // f64 types.
         out << "(4 * "
             << convert_swizzle_to_index(
-                   program_->SymbolToName(mem->member()->symbol()))
+                   program_->Symbols().NameFor(mem->member()->symbol()))
             << ")";
       } else {
         error_ =
@@ -2053,7 +2060,7 @@
   // If the data is a multi-element swizzle then we will not load the swizzle
   // portion through the Load command.
   if (data_type->Is<type::Vector>() &&
-      program_->SymbolToName(expr->member()->symbol()).size() > 1) {
+      program_->Symbols().NameFor(expr->member()->symbol()).size() > 1) {
     return false;
   }
 
@@ -2205,7 +2212,7 @@
   }
 
   if (auto* alias = type->As<type::Alias>()) {
-    out << namer_.NameFor(program_->SymbolToName(alias->symbol()));
+    out << namer_.NameFor(program_->Symbols().NameFor(alias->symbol()));
   } else if (auto* ary = type->As<type::Array>()) {
     type::Type* base_type = ary;
     std::vector<uint32_t> sizes;
@@ -2252,7 +2259,7 @@
     }
     out << "State";
   } else if (auto* str = type->As<type::Struct>()) {
-    out << program_->SymbolToName(str->symbol());
+    out << program_->Symbols().NameFor(str->symbol());
   } else if (auto* tex = type->As<type::Texture>()) {
     if (tex->Is<type::StorageTexture>()) {
       out << "RW";
@@ -2336,12 +2343,13 @@
     // TODO(dsinclair): Handle [[offset]] annotation on structs
     // https://bugs.chromium.org/p/tint/issues/detail?id=184
 
-    if (!EmitType(out, mem->type(), program_->SymbolToName(mem->symbol()))) {
+    if (!EmitType(out, mem->type(),
+                  program_->Symbols().NameFor(mem->symbol()))) {
       return false;
     }
     // Array member name will be output with the type
     if (!mem->type()->Is<type::Array>()) {
-      out << " " << namer_.NameFor(program_->SymbolToName(mem->symbol()));
+      out << " " << namer_.NameFor(program_->Symbols().NameFor(mem->symbol()));
     }
     out << ";" << std::endl;
   }
@@ -2400,11 +2408,11 @@
   if (var->is_const()) {
     out << "const ";
   }
-  if (!EmitType(out, var->type(), program_->SymbolToName(var->symbol()))) {
+  if (!EmitType(out, var->type(), program_->Symbols().NameFor(var->symbol()))) {
     return false;
   }
   if (!var->type()->Is<type::Array>()) {
-    out << " " << program_->SymbolToName(var->symbol());
+    out << " " << program_->Symbols().NameFor(var->symbol());
   }
   out << constructor_out.str() << ";" << std::endl;
 
@@ -2449,19 +2457,21 @@
     }
     out << "#endif" << std::endl;
     out << "static const ";
-    if (!EmitType(out, var->type(), program_->SymbolToName(var->symbol()))) {
+    if (!EmitType(out, var->type(),
+                  program_->Symbols().NameFor(var->symbol()))) {
       return false;
     }
-    out << " " << program_->SymbolToName(var->symbol())
+    out << " " << program_->Symbols().NameFor(var->symbol())
         << " = WGSL_SPEC_CONSTANT_" << const_id << ";" << std::endl;
     out << "#undef WGSL_SPEC_CONSTANT_" << const_id << std::endl;
   } else {
     out << "static const ";
-    if (!EmitType(out, var->type(), program_->SymbolToName(var->symbol()))) {
+    if (!EmitType(out, var->type(),
+                  program_->Symbols().NameFor(var->symbol()))) {
       return false;
     }
     if (!var->type()->Is<type::Array>()) {
-      out << " " << program_->SymbolToName(var->symbol());
+      out << " " << program_->Symbols().NameFor(var->symbol());
     }
 
     if (var->constructor() != nullptr) {
@@ -2476,7 +2486,7 @@
 std::string GeneratorImpl::get_buffer_name(ast::Expression* expr) {
   for (;;) {
     if (auto* ident = expr->As<ast::IdentifierExpression>()) {
-      return program_->SymbolToName(ident->symbol());
+      return program_->Symbols().NameFor(ident->symbol());
     } else if (auto* member = expr->As<ast::MemberAccessorExpression>()) {
       expr = member->structure();
     } else if (auto* array = expr->As<ast::ArrayAccessorExpression>()) {
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index f730784..c570a3b 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -258,7 +258,7 @@
     if (!EmitType(alias->type(), "")) {
       return false;
     }
-    out_ << " " << namer_.NameFor(program_->SymbolToName(alias->symbol()))
+    out_ << " " << namer_.NameFor(program_->Symbols().NameFor(alias->symbol()))
          << ";" << std::endl;
   } else if (auto* str = ty->As<type::Struct>()) {
     if (!EmitStructType(str)) {
@@ -517,7 +517,7 @@
     return true;
   }
 
-  auto name = program_->SymbolToName(ident->symbol());
+  auto name = program_->Symbols().NameFor(ident->symbol());
   auto caller_sym = ident->symbol();
   auto it = ep_func_name_remapped_.find(current_ep_sym_.to_str() + "_" +
                                         caller_sym.to_str());
@@ -527,8 +527,8 @@
 
   auto* func = program_->AST().Functions().Find(ident->symbol());
   if (func == nullptr) {
-    error_ =
-        "Unable to find function: " + program_->SymbolToName(ident->symbol());
+    error_ = "Unable to find function: " +
+             program_->Symbols().NameFor(ident->symbol());
     return false;
   }
 
@@ -562,7 +562,7 @@
       out_ << ", ";
     }
     first = false;
-    out_ << program_->SymbolToName(var->symbol());
+    out_ << program_->Symbols().NameFor(var->symbol());
   }
 
   for (const auto& data : func->referenced_uniform_variables()) {
@@ -571,7 +571,7 @@
       out_ << ", ";
     }
     first = false;
-    out_ << program_->SymbolToName(var->symbol());
+    out_ << program_->Symbols().NameFor(var->symbol());
   }
 
   for (const auto& data : func->referenced_storagebuffer_variables()) {
@@ -580,7 +580,7 @@
       out_ << ", ";
     }
     first = false;
-    out_ << program_->SymbolToName(var->symbol());
+    out_ << program_->Symbols().NameFor(var->symbol());
   }
 
   const auto& params = expr->params();
@@ -720,7 +720,7 @@
       break;
     default:
       error_ = "Internal compiler error: Unhandled texture intrinsic '" +
-               program_->SymbolToName(ident->symbol()) + "'";
+               program_->Symbols().NameFor(ident->symbol()) + "'";
       return false;
   }
 
@@ -847,7 +847,7 @@
     case ast::Intrinsic::kTrunc:
     case ast::Intrinsic::kSign:
     case ast::Intrinsic::kClamp:
-      out += program_->SymbolToName(ident->symbol());
+      out += program_->Symbols().NameFor(ident->symbol());
       break;
     case ast::Intrinsic::kAbs:
       if (ident->result_type()->Is<type::F32>()) {
@@ -883,8 +883,8 @@
       out += "rsqrt";
       break;
     default:
-      error_ =
-          "Unknown import method: " + program_->SymbolToName(ident->symbol());
+      error_ = "Unknown import method: " +
+               program_->Symbols().NameFor(ident->symbol());
       return "";
   }
   return out;
@@ -1059,8 +1059,9 @@
   }
 
   if (!in_locations.empty()) {
-    auto in_struct_name = generate_name(program_->SymbolToName(func->symbol()) +
-                                        "_" + kInStructNameSuffix);
+    auto in_struct_name =
+        generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                      kInStructNameSuffix);
     auto in_var_name = generate_name(kTintStructInVarPrefix);
     ep_sym_to_in_data_[func->symbol()] = {in_struct_name, in_var_name};
 
@@ -1074,11 +1075,11 @@
       uint32_t loc = data.second;
 
       make_indent();
-      if (!EmitType(var->type(), program_->SymbolToName(var->symbol()))) {
+      if (!EmitType(var->type(), program_->Symbols().NameFor(var->symbol()))) {
         return false;
       }
 
-      out_ << " " << program_->SymbolToName(var->symbol()) << " [[";
+      out_ << " " << program_->Symbols().NameFor(var->symbol()) << " [[";
       if (func->pipeline_stage() == ast::PipelineStage::kVertex) {
         out_ << "attribute(" << loc << ")";
       } else if (func->pipeline_stage() == ast::PipelineStage::kFragment) {
@@ -1096,8 +1097,9 @@
   }
 
   if (!out_variables.empty()) {
-    auto out_struct_name = generate_name(
-        program_->SymbolToName(func->symbol()) + "_" + kOutStructNameSuffix);
+    auto out_struct_name =
+        generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                      kOutStructNameSuffix);
     auto out_var_name = generate_name(kTintStructOutVarPrefix);
     ep_sym_to_out_data_[func->symbol()] = {out_struct_name, out_var_name};
 
@@ -1110,11 +1112,11 @@
       auto* deco = data.second;
 
       make_indent();
-      if (!EmitType(var->type(), program_->SymbolToName(var->symbol()))) {
+      if (!EmitType(var->type(), program_->Symbols().NameFor(var->symbol()))) {
         return false;
       }
 
-      out_ << " " << program_->SymbolToName(var->symbol()) << " [[";
+      out_ << " " << program_->Symbols().NameFor(var->symbol()) << " [[";
 
       if (auto* location = deco->As<ast::LocationDecoration>()) {
         auto loc = location->value();
@@ -1272,12 +1274,12 @@
     auto ep_name = ep_sym.to_str();
     // TODO(dsinclair): The SymbolToName should go away and just use
     // to_str() here when the conversion is complete.
-    name = generate_name(program_->SymbolToName(func->symbol()) + "_" +
-                         program_->SymbolToName(ep_sym));
+    name = generate_name(program_->Symbols().NameFor(func->symbol()) + "_" +
+                         program_->Symbols().NameFor(ep_sym));
     ep_func_name_remapped_[ep_name + "_" + func_name] = name;
   } else {
     // TODO(dsinclair): this should be updated to a remapped name
-    name = namer_.NameFor(program_->SymbolToName(func->symbol()));
+    name = namer_.NameFor(program_->Symbols().NameFor(func->symbol()));
   }
   out_ << name << "(";
 
@@ -1320,7 +1322,7 @@
     if (!EmitType(var->type(), "")) {
       return false;
     }
-    out_ << "& " << program_->SymbolToName(var->symbol());
+    out_ << "& " << program_->Symbols().NameFor(var->symbol());
   }
 
   for (const auto& data : func->referenced_uniform_variables()) {
@@ -1335,7 +1337,7 @@
     if (!EmitType(var->type(), "")) {
       return false;
     }
-    out_ << "& " << program_->SymbolToName(var->symbol());
+    out_ << "& " << program_->Symbols().NameFor(var->symbol());
   }
 
   for (const auto& data : func->referenced_storagebuffer_variables()) {
@@ -1358,7 +1360,7 @@
     if (!EmitType(ac->type(), "")) {
       return false;
     }
-    out_ << "& " << program_->SymbolToName(var->symbol());
+    out_ << "& " << program_->Symbols().NameFor(var->symbol());
   }
 
   for (auto* v : func->params()) {
@@ -1367,12 +1369,12 @@
     }
     first = false;
 
-    if (!EmitType(v->type(), program_->SymbolToName(v->symbol()))) {
+    if (!EmitType(v->type(), program_->Symbols().NameFor(v->symbol()))) {
       return false;
     }
     // Array name is output as part of the type
     if (!v->type()->Is<type::Array>()) {
-      out_ << " " << program_->SymbolToName(v->symbol());
+      out_ << " " << program_->Symbols().NameFor(v->symbol());
     }
   }
 
@@ -1432,7 +1434,8 @@
   } else {
     out_ << "void";
   }
-  out_ << " " << namer_.NameFor(program_->SymbolToName(func->symbol())) << "(";
+  out_ << " " << namer_.NameFor(program_->Symbols().NameFor(func->symbol()))
+       << "(";
 
   bool first = true;
   auto in_data = ep_sym_to_in_data_.find(current_ep_sym_);
@@ -1464,7 +1467,7 @@
       error_ = "unknown builtin";
       return false;
     }
-    out_ << " " << program_->SymbolToName(var->symbol()) << " [[" << attr
+    out_ << " " << program_->Symbols().NameFor(var->symbol()) << " [[" << attr
          << "]]";
   }
 
@@ -1481,7 +1484,7 @@
     auto* binding = data.second.binding;
     if (binding == nullptr) {
       error_ = "unable to find binding information for uniform: " +
-               program_->SymbolToName(var->symbol());
+               program_->Symbols().NameFor(var->symbol());
       return false;
     }
     // auto* set = data.second.set;
@@ -1492,7 +1495,7 @@
     if (!EmitType(var->type(), "")) {
       return false;
     }
-    out_ << "& " << program_->SymbolToName(var->symbol()) << " [[buffer("
+    out_ << "& " << program_->Symbols().NameFor(var->symbol()) << " [[buffer("
          << binding->value() << ")]]";
   }
 
@@ -1522,7 +1525,7 @@
     if (!EmitType(ac->type(), "")) {
       return false;
     }
-    out_ << "& " << program_->SymbolToName(var->symbol()) << " [[buffer("
+    out_ << "& " << program_->Symbols().NameFor(var->symbol()) << " [[buffer("
          << binding->value() << ")]]";
   }
 
@@ -1587,7 +1590,7 @@
       out_ << name << ".";
     }
   }
-  out_ << namer_.NameFor(program_->SymbolToName(ident->symbol()));
+  out_ << namer_.NameFor(program_->Symbols().NameFor(ident->symbol()));
 
   return true;
 }
@@ -1646,7 +1649,7 @@
       make_indent();
 
       auto* var = decl->variable();
-      out_ << program_->SymbolToName(var->symbol()) << " = ";
+      out_ << program_->Symbols().NameFor(var->symbol()) << " = ";
       if (var->constructor() != nullptr) {
         if (!EmitExpression(var->constructor())) {
           return false;
@@ -1877,7 +1880,7 @@
   }
 
   if (auto* alias = type->As<type::Alias>()) {
-    out_ << namer_.NameFor(program_->SymbolToName(alias->symbol()));
+    out_ << namer_.NameFor(program_->Symbols().NameFor(alias->symbol()));
   } else if (auto* ary = type->As<type::Array>()) {
     type::Type* base_type = ary;
     std::vector<uint32_t> sizes;
@@ -1920,7 +1923,7 @@
   } else if (auto* str = type->As<type::Struct>()) {
     // The struct type emits as just the name. The declaration would be emitted
     // as part of emitting the constructed types.
-    out_ << program_->SymbolToName(str->symbol());
+    out_ << program_->Symbols().NameFor(str->symbol());
   } else if (auto* tex = type->As<type::Texture>()) {
     if (tex->Is<type::DepthTexture>()) {
       out_ << "depth";
@@ -2002,7 +2005,7 @@
   // TODO(dsinclair): Block decoration?
   // if (str->impl()->decoration() != ast::StructDecoration::kNone) {
   // }
-  out_ << "struct " << program_->SymbolToName(str->symbol()) << " {"
+  out_ << "struct " << program_->Symbols().NameFor(str->symbol()) << " {"
        << std::endl;
 
   increment_indent();
@@ -2026,7 +2029,7 @@
       }
     }
 
-    if (!EmitType(mem->type(), program_->SymbolToName(mem->symbol()))) {
+    if (!EmitType(mem->type(), program_->Symbols().NameFor(mem->symbol()))) {
       return false;
     }
     auto size = calculate_alignment_size(mem->type());
@@ -2038,7 +2041,7 @@
 
     // Array member name will be output with the type
     if (!mem->type()->Is<type::Array>()) {
-      out_ << " " << namer_.NameFor(program_->SymbolToName(mem->symbol()));
+      out_ << " " << namer_.NameFor(program_->Symbols().NameFor(mem->symbol()));
     }
     out_ << ";" << std::endl;
   }
@@ -2080,11 +2083,11 @@
   if (var->is_const()) {
     out_ << "const ";
   }
-  if (!EmitType(var->type(), program_->SymbolToName(var->symbol()))) {
+  if (!EmitType(var->type(), program_->Symbols().NameFor(var->symbol()))) {
     return false;
   }
   if (!var->type()->Is<type::Array>()) {
-    out_ << " " << program_->SymbolToName(var->symbol());
+    out_ << " " << program_->Symbols().NameFor(var->symbol());
   }
 
   if (!skip_constructor) {
@@ -2122,11 +2125,11 @@
   }
 
   out_ << "constant ";
-  if (!EmitType(var->type(), program_->SymbolToName(var->symbol()))) {
+  if (!EmitType(var->type(), program_->Symbols().NameFor(var->symbol()))) {
     return false;
   }
   if (!var->type()->Is<type::Array>()) {
-    out_ << " " << program_->SymbolToName(var->symbol());
+    out_ << " " << program_->Symbols().NameFor(var->symbol());
   }
 
   if (var->HasConstantIdDecoration()) {
diff --git a/src/writer/spirv/builder.cc b/src/writer/spirv/builder.cc
index ef481ab..f64db2b 100644
--- a/src/writer/spirv/builder.cc
+++ b/src/writer/spirv/builder.cc
@@ -450,7 +450,7 @@
 
   OperandList operands = {
       Operand::Int(stage), Operand::Int(id),
-      Operand::String(program_->SymbolToName(func->symbol()))};
+      Operand::String(program_->Symbols().NameFor(func->symbol()))};
 
   for (const auto* var : func->referenced_module_variables()) {
     // For SPIR-V 1.3 we only output Input/output variables. If we update to
@@ -463,7 +463,7 @@
     uint32_t var_id;
     if (!scope_stack_.get(var->symbol(), &var_id)) {
       error_ = "unable to find ID for global variable: " +
-               program_->SymbolToName(var->symbol());
+               program_->Symbols().NameFor(var->symbol());
       return false;
     }
 
@@ -543,7 +543,7 @@
 
   push_debug(spv::Op::OpName,
              {Operand::Int(func_id),
-              Operand::String(program_->SymbolToName(func->symbol()))});
+              Operand::String(program_->Symbols().NameFor(func->symbol()))});
 
   auto ret_id = GenerateTypeIfNeeded(func->return_type());
   if (ret_id == 0) {
@@ -569,7 +569,7 @@
 
     push_debug(spv::Op::OpName,
                {Operand::Int(param_id),
-                Operand::String(program_->SymbolToName(param->symbol()))});
+                Operand::String(program_->Symbols().NameFor(param->symbol()))});
     params.push_back(Instruction{spv::Op::OpFunctionParameter,
                                  {Operand::Int(param_type_id), param_op}});
 
@@ -660,7 +660,7 @@
 
   push_debug(spv::Op::OpName,
              {Operand::Int(var_id),
-              Operand::String(program_->SymbolToName(var->symbol()))});
+              Operand::String(program_->Symbols().NameFor(var->symbol()))});
 
   // TODO(dsinclair) We could detect if the constructor is fully const and emit
   // an initializer value for the variable instead of doing the OpLoad.
@@ -712,7 +712,7 @@
     }
     push_debug(spv::Op::OpName,
                {Operand::Int(init_id),
-                Operand::String(program_->SymbolToName(var->symbol()))});
+                Operand::String(program_->Symbols().NameFor(var->symbol()))});
 
     scope_stack_.set_global(var->symbol(), init_id);
     spirv_id_to_variable_[init_id] = var;
@@ -734,7 +734,7 @@
 
   push_debug(spv::Op::OpName,
              {Operand::Int(var_id),
-              Operand::String(program_->SymbolToName(var->symbol()))});
+              Operand::String(program_->Symbols().NameFor(var->symbol()))});
 
   OperandList ops = {Operand::Int(type_id), result,
                      Operand::Int(ConvertStorageClass(sc))};
@@ -915,7 +915,7 @@
   }
 
   // TODO(dsinclair): Swizzle stuff
-  auto swiz = program_->SymbolToName(expr->member()->symbol());
+  auto swiz = program_->Symbols().NameFor(expr->member()->symbol());
   // Single element swizzle is either an access chain or a composite extract
   if (swiz.size() == 1) {
     auto val = IndexFromName(swiz[0]);
@@ -1123,7 +1123,7 @@
   }
 
   error_ = "unable to find variable with identifier: " +
-           program_->SymbolToName(expr->symbol());
+           program_->Symbols().NameFor(expr->symbol());
   return 0;
 }
 
@@ -1816,7 +1816,7 @@
   auto func_id = func_symbol_to_id_[ident->symbol()];
   if (func_id == 0) {
     error_ = "unable to find called function: " +
-             program_->SymbolToName(ident->symbol());
+             program_->Symbols().NameFor(ident->symbol());
     return 0;
   }
   ops.push_back(Operand::Int(func_id));
@@ -1948,7 +1948,7 @@
     auto inst_id =
         intrinsic_to_glsl_method(ident->result_type(), ident->intrinsic());
     if (inst_id == 0) {
-      error_ = "unknown method " + program_->SymbolToName(ident->symbol());
+      error_ = "unknown method " + program_->Symbols().NameFor(ident->symbol());
       return 0;
     }
 
@@ -1960,7 +1960,7 @@
 
   if (op == spv::Op::OpNop) {
     error_ = "unable to determine operator for: " +
-             program_->SymbolToName(ident->symbol());
+             program_->Symbols().NameFor(ident->symbol());
     return 0;
   }
 
@@ -2384,7 +2384,7 @@
 
   if (op == spv::Op::OpNop) {
     error_ = "unable to determine operator for: " +
-             program_->SymbolToName(ident->symbol());
+             program_->Symbols().NameFor(ident->symbol());
     return false;
   }
 
@@ -3006,7 +3006,7 @@
     push_debug(
         spv::Op::OpName,
         {Operand::Int(struct_id),
-         Operand::String(program_->SymbolToName(struct_type->symbol()))});
+         Operand::String(program_->Symbols().NameFor(struct_type->symbol()))});
   }
 
   OperandList ops;
@@ -3049,7 +3049,7 @@
                                        ast::StructMember* member) {
   push_debug(spv::Op::OpMemberName,
              {Operand::Int(struct_id), Operand::Int(idx),
-              Operand::String(program_->SymbolToName(member->symbol()))});
+              Operand::String(program_->Symbols().NameFor(member->symbol()))});
 
   bool has_layout = false;
   for (auto* deco : member->decorations()) {
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index dd14fe3..91b9e43 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -114,7 +114,7 @@
 bool GeneratorImpl::GenerateEntryPoint(ast::PipelineStage stage,
                                        const std::string& name) {
   auto* func =
-      program_->AST().Functions().Find(program_->GetSymbol(name), stage);
+      program_->AST().Functions().Find(program_->Symbols().Get(name), stage);
   if (func == nullptr) {
     error_ = "Unable to find requested entry point: " + name;
     return false;
@@ -154,7 +154,7 @@
   }
 
   for (auto* f : program_->AST().Functions()) {
-    if (!f->HasAncestorEntryPoint(program_->GetSymbol(name))) {
+    if (!f->HasAncestorEntryPoint(program_->Symbols().Get(name))) {
       continue;
     }
 
@@ -175,7 +175,7 @@
 bool GeneratorImpl::EmitConstructedType(const type::Type* ty) {
   make_indent();
   if (auto* alias = ty->As<type::Alias>()) {
-    out_ << "type " << program_->SymbolToName(alias->symbol()) << " = ";
+    out_ << "type " << program_->Symbols().NameFor(alias->symbol()) << " = ";
     if (!EmitType(alias->type())) {
       return false;
     }
@@ -338,7 +338,7 @@
 
 bool GeneratorImpl::EmitIdentifier(ast::IdentifierExpression* expr) {
   auto* ident = expr->As<ast::IdentifierExpression>();
-  out_ << program_->SymbolToName(ident->symbol());
+  out_ << program_->Symbols().NameFor(ident->symbol());
   return true;
 }
 
@@ -361,7 +361,7 @@
   }
 
   make_indent();
-  out_ << "fn " << program_->SymbolToName(func->symbol()) << "(";
+  out_ << "fn " << program_->Symbols().NameFor(func->symbol()) << "(";
 
   bool first = true;
   for (auto* v : func->params()) {
@@ -370,7 +370,7 @@
     }
     first = false;
 
-    out_ << program_->SymbolToName(v->symbol()) << " : ";
+    out_ << program_->Symbols().NameFor(v->symbol()) << " : ";
 
     if (!EmitType(v->type())) {
       return false;
@@ -418,7 +418,7 @@
     }
     return true;
   } else if (auto* alias = type->As<type::Alias>()) {
-    out_ << program_->SymbolToName(alias->symbol());
+    out_ << program_->Symbols().NameFor(alias->symbol());
   } else if (auto* ary = type->As<type::Array>()) {
     for (auto* deco : ary->decorations()) {
       if (auto* stride = deco->As<ast::StrideDecoration>()) {
@@ -462,7 +462,7 @@
   } else if (auto* str = type->As<type::Struct>()) {
     // The struct, as a type, is just the name. We should have already emitted
     // the declaration through a call to |EmitStructType| earlier.
-    out_ << program_->SymbolToName(str->symbol());
+    out_ << program_->Symbols().NameFor(str->symbol());
   } else if (auto* texture = type->As<type::Texture>()) {
     out_ << "texture_";
     if (texture->Is<type::DepthTexture>()) {
@@ -550,7 +550,7 @@
     deco->to_str(out_, 0);
     out_ << "]]" << std::endl;
   }
-  out_ << "struct " << program_->SymbolToName(str->symbol()) << " {"
+  out_ << "struct " << program_->Symbols().NameFor(str->symbol()) << " {"
        << std::endl;
 
   increment_indent();
@@ -564,7 +564,7 @@
       out_ << "[[offset(" << offset->offset() << ")]]" << std::endl;
     }
     make_indent();
-    out_ << program_->SymbolToName(mem->symbol()) << " : ";
+    out_ << program_->Symbols().NameFor(mem->symbol()) << " : ";
     if (!EmitType(mem->type())) {
       return false;
     }
@@ -594,7 +594,7 @@
     }
   }
 
-  out_ << " " << program_->SymbolToName(var->symbol()) << " : ";
+  out_ << " " << program_->Symbols().NameFor(var->symbol()) << " : ";
   if (!EmitType(var->type())) {
     return false;
   }