[tint][spirv][reader] Add namespaces, move common.h

Rename the spirv::Reader::Parse() to Read(), as that's what a reader does.

Place all the ast_parser into the tint::spirv::reader::ast_parser namespace.

Move the common.h to a common subdirectory to break a cyclic dependency.

Change-Id: I88b73ab63926fcfe07dacc4b6ec2b6ce7d5039e8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/145840
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 650dc82..6aca61b 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -323,7 +323,7 @@
     if (optionsDesc) {
         options.allow_non_uniform_derivatives = optionsDesc->allowNonUniformDerivatives;
     }
-    tint::Program program = tint::spirv::reader::Parse(spirv, options);
+    tint::Program program = tint::spirv::reader::Read(spirv, options);
     if (outMessages != nullptr) {
         DAWN_TRY(outMessages->AddMessages(program.Diagnostics()));
     }
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index e03894f..9ab4eee 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -940,6 +940,8 @@
     "lang/spirv/reader/ast_parser/function.h",
     "lang/spirv/reader/ast_parser/namer.cc",
     "lang/spirv/reader/ast_parser/namer.h",
+    "lang/spirv/reader/ast_parser/parse.cc",
+    "lang/spirv/reader/ast_parser/parse.h",
     "lang/spirv/reader/ast_parser/type.cc",
     "lang/spirv/reader/ast_parser/type.h",
     "lang/spirv/reader/ast_parser/usage.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 1b8804f..fa446bb 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -622,6 +622,8 @@
     lang/spirv/reader/ast_parser/function.h
     lang/spirv/reader/ast_parser/namer.cc
     lang/spirv/reader/ast_parser/namer.h
+    lang/spirv/reader/ast_parser/parse.cc
+    lang/spirv/reader/ast_parser/parse.h
     lang/spirv/reader/ast_parser/type.cc
     lang/spirv/reader/ast_parser/type.h
     lang/spirv/reader/ast_parser/usage.cc
diff --git a/src/tint/bench/benchmark.cc b/src/tint/bench/benchmark.cc
index e93becf..c70b3cb 100644
--- a/src/tint/bench/benchmark.cc
+++ b/src/tint/bench/benchmark.cc
@@ -101,7 +101,7 @@
     if (tint::HasSuffix(path, ".spv")) {
         auto spirv = ReadFile<uint32_t>(path);
         if (auto* buf = std::get_if<std::vector<uint32_t>>(&spirv)) {
-            auto program = tint::spirv::reader::Parse(*buf, {});
+            auto program = tint::spirv::reader::Read(*buf, {});
             if (!program.IsValid()) {
                 return Error{program.Diagnostics().str()};
             }
diff --git a/src/tint/cmd/common/helper.cc b/src/tint/cmd/common/helper.cc
index 6ca381b..aac52b5 100644
--- a/src/tint/cmd/common/helper.cc
+++ b/src/tint/cmd/common/helper.cc
@@ -133,7 +133,7 @@
                 exit(1);
             }
             program = std::make_unique<tint::Program>(
-                tint::spirv::reader::Parse(data, opts.spirv_reader_options));
+                tint::spirv::reader::Read(data, opts.spirv_reader_options));
             break;
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
@@ -158,7 +158,7 @@
                 exit(1);
             }
             program = std::make_unique<tint::Program>(
-                tint::spirv::reader::Parse(data, opts.spirv_reader_options));
+                tint::spirv::reader::Read(data, opts.spirv_reader_options));
             break;
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
diff --git a/src/tint/cmd/loopy/main.cc b/src/tint/cmd/loopy/main.cc
index 1aba886..0dd9eeb 100644
--- a/src/tint/cmd/loopy/main.cc
+++ b/src/tint/cmd/loopy/main.cc
@@ -341,7 +341,7 @@
 
             uint32_t loop_count = options.loop_count;
             for (uint32_t i = 0; i < loop_count; ++i) {
-                program = std::make_unique<tint::Program>(tint::spirv::reader::Parse(data, {}));
+                program = std::make_unique<tint::Program>(tint::spirv::reader::Read(data, {}));
             }
 #else
             std::cerr << "Tint not built with the SPIR-V reader enabled" << std::endl;
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index d7d4ace..3328f14 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -177,7 +177,7 @@
             if (dump_input_) {
                 dump_input_data(spirv_input, ".spv");
             }
-            program = spirv::reader::Parse(spirv_input);
+            program = spirv::reader::Read(spirv_input);
 #endif  // TINT_BUILD_SPV_READER
             break;
         }
diff --git a/src/tint/lang/spirv/reader/ast_parser/README.md b/src/tint/lang/spirv/reader/ast_parser/README.md
index bf11a77..f82d2aa 100644
--- a/src/tint/lang/spirv/reader/ast_parser/README.md
+++ b/src/tint/lang/spirv/reader/ast_parser/README.md
@@ -2,8 +2,8 @@
 
 This component translates SPIR-V written for Vulkan into the Tint AST.
 
-The SPIR-V reader entry point is `tint::spirv::reader::Parser`, which
-implements the Reader interface in `tint::reader::Reader`.
+The SPIR-V reader entry point is `tint::spirv::reader::Read()`, which
+performs the translation of SPIR-V to a `tint::Program`.
 
 It's usable from the Tint command line:
 
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
index d33730d..ec709e6 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.cc
@@ -34,7 +34,7 @@
 #include "src/tint/utils/containers/unique_vector.h"
 #include "src/tint/utils/rtti/switch.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 namespace {
 
@@ -2831,4 +2831,4 @@
 
 WorkgroupSizeInfo::~WorkgroupSizeInfo() = default;
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
index a70a502..f8304a7 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser.h
@@ -61,7 +61,7 @@
 /// familiar to Vulkan SPIR-V developers.  We will tend to use "image"
 /// and "sampler" instead of "handle".
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// The binary representation of a SPIR-V decoration enum followed by its
 /// operands, if any.
@@ -927,6 +927,6 @@
     WorkgroupSizeInfo workgroup_size_builtin_;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_AST_PARSER_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc b/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
index 0de2834..fd53457 100644
--- a/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/ast_parser_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -248,4 +248,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/attributes.h b/src/tint/lang/spirv/reader/ast_parser/attributes.h
index e613605..9ea154f 100644
--- a/src/tint/lang/spirv/reader/ast_parser/attributes.h
+++ b/src/tint/lang/spirv/reader/ast_parser/attributes.h
@@ -21,7 +21,7 @@
 #include "src/tint/utils/containers/enum_set.h"
 #include "src/tint/utils/containers/vector.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// Attributes holds a vector of ast::Attribute pointers, and a enum-set of flags used to hold
 /// additional metadata.
@@ -76,6 +76,6 @@
     tint::EnumSet<Flags> flags;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ATTRIBUTES_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc b/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
index 5aa0678..d4eb314 100644
--- a/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/barrier_test.cc
@@ -19,7 +19,7 @@
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/sem/call.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -202,4 +202,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/constant_test.cc b/src/tint/lang/spirv/reader/ast_parser/constant_test.cc
index d2cb3a9..482cc14 100644
--- a/src/tint/lang/spirv/reader/ast_parser/constant_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/constant_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -139,4 +139,4 @@
                              {"%float", "%float_ten", "10.0f"}}));
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/construct.cc b/src/tint/lang/spirv/reader/ast_parser/construct.cc
index 609495a..d027dac 100644
--- a/src/tint/lang/spirv/reader/ast_parser/construct.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/construct.cc
@@ -14,7 +14,7 @@
 
 #include "src/tint/lang/spirv/reader/ast_parser/construct.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 Construct::Construct(const Construct* the_parent,
                      int the_depth,
@@ -60,4 +60,4 @@
       end_pos(the_end_pos),
       scope_end_pos(the_scope_end_pos) {}
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/construct.h b/src/tint/lang/spirv/reader/ast_parser/construct.h
index 59f6010..4f6f53e 100644
--- a/src/tint/lang/spirv/reader/ast_parser/construct.h
+++ b/src/tint/lang/spirv/reader/ast_parser/construct.h
@@ -21,7 +21,7 @@
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// A structured control flow construct, consisting of a set of basic blocks.
 /// A construct is a span of blocks in the computed block order,
@@ -267,6 +267,6 @@
     return ss.str();
 }
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_CONSTRUCT_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc b/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
index 965cdc1..8b1779e 100644
--- a/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/convert_member_decoration_test.cc
@@ -15,7 +15,7 @@
 #include "gmock/gmock.h"
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -63,8 +63,8 @@
 TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Natural) {
     auto p = parser(std::vector<uint32_t>{});
 
-    reader::F32 f32;
-    reader::Matrix matrix(&f32, 2, 2);
+    ast_parser::F32 f32;
+    ast_parser::Matrix matrix(&f32, 2, 2);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 8});
     EXPECT_TRUE(result.list.IsEmpty());
@@ -74,8 +74,8 @@
 TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x2_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    reader::F32 f32;
-    reader::Matrix matrix(&f32, 2, 2);
+    ast_parser::F32 f32;
+    ast_parser::Matrix matrix(&f32, 2, 2);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 16});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -89,8 +89,8 @@
 TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Natural) {
     auto p = parser(std::vector<uint32_t>{});
 
-    reader::F32 f32;
-    reader::Matrix matrix(&f32, 2, 4);
+    ast_parser::F32 f32;
+    ast_parser::Matrix matrix(&f32, 2, 4);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 16});
     EXPECT_TRUE(result.list.IsEmpty());
@@ -100,8 +100,8 @@
 TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x4_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    reader::F32 f32;
-    reader::Matrix matrix(&f32, 2, 4);
+    ast_parser::F32 f32;
+    ast_parser::Matrix matrix(&f32, 2, 4);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 64});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -115,8 +115,8 @@
 TEST_F(SpirvASTParserTest, ConvertMemberDecoration_Matrix2x3_Stride_Custom) {
     auto p = parser(std::vector<uint32_t>{});
 
-    reader::F32 f32;
-    reader::Matrix matrix(&f32, 2, 3);
+    ast_parser::F32 f32;
+    ast_parser::Matrix matrix(&f32, 2, 3);
     auto result =
         p->ConvertMemberDecoration(1, 1, &matrix, {uint32_t(spv::Decoration::MatrixStride), 32});
     ASSERT_FALSE(result.list.IsEmpty());
@@ -149,4 +149,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc b/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
index 2780333..bfd63da 100644
--- a/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/convert_type_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -896,4 +896,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
index 69a2e13..69dd7fe 100644
--- a/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.cc
@@ -16,7 +16,7 @@
 
 #include <utility>
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 EntryPointInfo::EntryPointInfo(std::string the_name,
                                ast::PipelineStage the_stage,
@@ -37,4 +37,4 @@
 
 EntryPointInfo::~EntryPointInfo() = default;
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
index acddabd..d1b5a9f 100644
--- a/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
+++ b/src/tint/lang/spirv/reader/ast_parser/entry_point_info.h
@@ -20,7 +20,7 @@
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
 #include "src/tint/utils/containers/vector.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// The size of an integer-coordinate grid, in the x, y, and z dimensions.
 struct GridSize {
@@ -86,6 +86,6 @@
     GridSize workgroup_size;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENTRY_POINT_INFO_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc b/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
index 67842ab..c374df0 100644
--- a/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter.cc
@@ -16,7 +16,7 @@
 
 #include "src/tint/lang/core/type/texture_dimension.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 EnumConverter::EnumConverter(const FailStream& fs) : fail_stream_(fs) {}
 
@@ -179,4 +179,4 @@
     return core::TexelFormat::kUndefined;
 }
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/enum_converter.h b/src/tint/lang/spirv/reader/ast_parser/enum_converter.h
index 80f16fd..01b81cf 100644
--- a/src/tint/lang/spirv/reader/ast_parser/enum_converter.h
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter.h
@@ -24,7 +24,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
 #include "src/tint/lang/wgsl/ast/pipeline_stage.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// A converter from SPIR-V enums to Tint AST enums.
 class EnumConverter {
@@ -91,6 +91,6 @@
     FailStream fail_stream_;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_ENUM_CONVERTER_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc b/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
index 5ce9dc7..bb7790b 100644
--- a/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/enum_converter_test.cc
@@ -20,7 +20,7 @@
 #include "src/tint/lang/core/type/texture_dimension.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 // Pipeline stage
@@ -380,4 +380,4 @@
         TexelFormatCase{spv::ImageFormat::Rg8ui, false, core::TexelFormat::kUndefined}));
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/fail_stream.h b/src/tint/lang/spirv/reader/ast_parser/fail_stream.h
index 19f80b6..ebf170c 100644
--- a/src/tint/lang/spirv/reader/ast_parser/fail_stream.h
+++ b/src/tint/lang/spirv/reader/ast_parser/fail_stream.h
@@ -17,7 +17,7 @@
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// A FailStream object accumulates values onto a given stream,
 /// and can be used to record failure by writing the false value
@@ -64,6 +64,6 @@
     StringStream* out_;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FAIL_STREAM_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc b/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
index ab62e38..3d4f485 100644
--- a/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/fail_stream_test.cc
@@ -17,7 +17,7 @@
 #include "gmock/gmock.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -67,4 +67,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function.cc b/src/tint/lang/spirv/reader/ast_parser/function.cc
index 8316aa2..8dfe5c2 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function.cc
@@ -143,7 +143,7 @@
 
 using namespace tint::number_suffixes;  // NOLINT
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 namespace {
 
@@ -6423,9 +6423,9 @@
 FunctionEmitter::FunctionDeclaration::FunctionDeclaration() = default;
 FunctionEmitter::FunctionDeclaration::~FunctionDeclaration() = default;
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::StatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::SwitchStatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::IfStatementBuilder);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::LoopStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::StatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::SwitchStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::IfStatementBuilder);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::LoopStatementBuilder);
diff --git a/src/tint/lang/spirv/reader/ast_parser/function.h b/src/tint/lang/spirv/reader/ast_parser/function.h
index 1226acf..dbe48e9 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function.h
+++ b/src/tint/lang/spirv/reader/ast_parser/function.h
@@ -30,7 +30,7 @@
 #include "src/tint/lang/wgsl/program/program_builder.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// Kinds of CFG edges.
 //
@@ -1345,6 +1345,6 @@
     const EntryPointInfo* ep_info_ = nullptr;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_FUNCTION_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
index 4d991b0..3540752 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_arithmetic_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -969,4 +969,4 @@
 // TODO(dneto): OpSMulExtended
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
index 502b19e..84868c2 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_bit_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -1067,4 +1067,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
index 526da22..14228a2 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_call_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -367,4 +367,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
index 60d31ce..731b75d 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_cfg_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -12087,4 +12087,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
index 836e3da..374cba5 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_composite_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -1105,4 +1105,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
index 13b54ad..b535717 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_conversion_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -615,4 +615,4 @@
 // TODO(dneto): OpSatConvertUToS // Kernel (OpenCL), not in WebGPU
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
index 2144885..56fdd7e 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_decl_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -224,4 +224,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
index d1c595b..41f2bba 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_glsl_std_450_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -1531,4 +1531,4 @@
     EXPECT_THAT(body, HasSubstr(expected)) << body;
 }
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
index f1f3377..1cdd05c 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_logical_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -908,4 +908,4 @@
 // TODO(dneto): OpSelect over more general types, as in SPIR-V 1.4
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
index 8068dd1..ad8c6e9 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_memory_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -1395,4 +1395,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
index 03800d0..628825f 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_misc_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -289,4 +289,4 @@
 // TODO(dneto): OpSizeof : requires Kernel (OpenCL)
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc b/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
index 9dee822..ba83ded 100644
--- a/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/function_var_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -1909,4 +1909,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc b/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
index 66253c6..a6b67c5 100644
--- a/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/get_decorations_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -254,4 +254,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
index c2ff2da..8fb26ed 100644
--- a/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/handle_test.cc
@@ -20,7 +20,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -4282,4 +4282,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/helper_test.cc b/src/tint/lang/spirv/reader/ast_parser/helper_test.cc
index bfb8eb1..7e5ed82 100644
--- a/src/tint/lang/spirv/reader/ast_parser/helper_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/helper_test.cc
@@ -19,7 +19,7 @@
 
 #include "gmock/gmock.h"
 
-namespace tint::spirv::reader::test {
+namespace tint::spirv::reader::ast_parser::test {
 
 // Default to not dumping the SPIR-V assembly.
 bool ASTParserWrapperForTest::dump_successfully_converted_spirv_ = false;
@@ -81,4 +81,4 @@
         });
 }
 
-}  // namespace tint::spirv::reader::test
+}  // namespace tint::spirv::reader::ast_parser::test
diff --git a/src/tint/lang/spirv/reader/ast_parser/helper_test.h b/src/tint/lang/spirv/reader/ast_parser/helper_test.h
index 356d8a6..ccb381c 100644
--- a/src/tint/lang/spirv/reader/ast_parser/helper_test.h
+++ b/src/tint/lang/spirv/reader/ast_parser/helper_test.h
@@ -41,8 +41,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/usage.h"
 
-namespace tint::spirv::reader {
-namespace test {
+namespace tint::spirv::reader::ast_parser::test {
 
 /// A test class that wraps ParseImpl
 class ASTParserWrapperForTest {
@@ -284,7 +283,9 @@
 /// @returns the WGSL printed string of the AST node.
 std::string ToString(const Program& program, const ast::Node* node);
 
-}  // namespace test
+}  // namespace tint::spirv::reader::ast_parser::test
+
+namespace tint::spirv::reader::ast_parser {
 
 /// SPIR-V Parser test class
 template <typename T>
@@ -309,6 +310,6 @@
 /// Use this form when you don't need to template any further.
 using SpirvASTParserTest = SpirvASTParserTestBase<::testing::Test>;
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_HELPER_TEST_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/import_test.cc b/src/tint/lang/spirv/reader/ast_parser/import_test.cc
index 8416e3f..82776e5 100644
--- a/src/tint/lang/spirv/reader/ast_parser/import_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/import_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::ElementsAre;
@@ -127,4 +127,4 @@
 // imports.
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc b/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
index c6db896..7b17175 100644
--- a/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/module_function_decl_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -465,4 +465,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc b/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
index 7b70fe8..73012b8 100644
--- a/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/module_var_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 #include "src/tint/utils/text/string.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using SpvModuleScopeVarParserTest = SpirvASTParserTest;
@@ -5360,4 +5360,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc b/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
index 16b1fa5..86c44e1 100644
--- a/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/named_types_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::HasSubstr;
@@ -147,4 +147,4 @@
 // Blocked by crbug.com/tint/32
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/namer.cc b/src/tint/lang/spirv/reader/ast_parser/namer.cc
index 29b67f6..aaa1ba6 100644
--- a/src/tint/lang/spirv/reader/ast_parser/namer.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/namer.cc
@@ -21,7 +21,7 @@
 #include "src/tint/utils/ice/ice.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 namespace {
 
@@ -345,4 +345,4 @@
     }
 }
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/namer.h b/src/tint/lang/spirv/reader/ast_parser/namer.h
index fe7d479..758105f 100644
--- a/src/tint/lang/spirv/reader/ast_parser/namer.h
+++ b/src/tint/lang/spirv/reader/ast_parser/namer.h
@@ -21,7 +21,7 @@
 
 #include "src/tint/lang/spirv/reader/ast_parser/fail_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// A Namer maps SPIR-V IDs to strings.
 ///
@@ -152,6 +152,6 @@
     std::unordered_map<std::string, uint32_t> next_unusued_derived_name_id_;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_NAMER_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/namer_test.cc b/src/tint/lang/spirv/reader/ast_parser/namer_test.cc
index b3ab734..f6af2c7 100644
--- a/src/tint/lang/spirv/reader/ast_parser/namer_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/namer_test.cc
@@ -18,7 +18,7 @@
 #include "src/tint/lang/core/function.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -411,4 +411,4 @@
                          ::testing::ValuesIn(core::kFunctionStrings));
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/parse.cc b/src/tint/lang/spirv/reader/ast_parser/parse.cc
new file mode 100644
index 0000000..27dc272
--- /dev/null
+++ b/src/tint/lang/spirv/reader/ast_parser/parse.cc
@@ -0,0 +1,73 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/tint/lang/spirv/reader/ast_parser/parse.h"
+
+#include <utility>
+
+#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
+#include "src/tint/lang/wgsl/ast/transform/decompose_strided_array.h"
+#include "src/tint/lang/wgsl/ast/transform/decompose_strided_matrix.h"
+#include "src/tint/lang/wgsl/ast/transform/fold_trivial_lets.h"
+#include "src/tint/lang/wgsl/ast/transform/manager.h"
+#include "src/tint/lang/wgsl/ast/transform/remove_unreachable_statements.h"
+#include "src/tint/lang/wgsl/ast/transform/simplify_pointers.h"
+#include "src/tint/lang/wgsl/ast/transform/spirv_atomic.h"
+#include "src/tint/lang/wgsl/ast/transform/unshadow.h"
+#include "src/tint/lang/wgsl/program/clone_context.h"
+#include "src/tint/lang/wgsl/resolver/resolve.h"
+
+namespace tint::spirv::reader::ast_parser {
+
+Program Parse(const std::vector<uint32_t>& input, const Options& options) {
+    ASTParser parser(input);
+    bool parsed = parser.Parse();
+
+    ProgramBuilder& builder = parser.builder();
+    if (!parsed) {
+        // TODO(bclayton): Migrate ASTParser to using diagnostics.
+        builder.Diagnostics().add_error(diag::System::Reader, parser.error());
+        return Program(std::move(builder));
+    }
+
+    if (options.allow_non_uniform_derivatives) {
+        // Suppress errors regarding non-uniform derivative operations if requested, by adding a
+        // diagnostic directive to the module.
+        builder.DiagnosticDirective(core::DiagnosticSeverity::kOff, "derivative_uniformity");
+    }
+
+    // The SPIR-V parser can construct disjoint AST nodes, which is invalid for
+    // the Resolver. Clone the Program to clean these up.
+    Program program_with_disjoint_ast(std::move(builder));
+
+    ProgramBuilder output;
+    program::CloneContext(&output, &program_with_disjoint_ast, false).Clone();
+    auto program = Program(resolver::Resolve(output));
+    if (!program.IsValid()) {
+        return program;
+    }
+
+    ast::transform::Manager manager;
+    ast::transform::DataMap outputs;
+    manager.Add<ast::transform::Unshadow>();
+    manager.Add<ast::transform::SimplifyPointers>();
+    manager.Add<ast::transform::FoldTrivialLets>();
+    manager.Add<ast::transform::DecomposeStridedMatrix>();
+    manager.Add<ast::transform::DecomposeStridedArray>();
+    manager.Add<ast::transform::RemoveUnreachableStatements>();
+    manager.Add<ast::transform::SpirvAtomic>();
+    return manager.Run(&program, {}, outputs);
+}
+
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/parse.h b/src/tint/lang/spirv/reader/ast_parser/parse.h
new file mode 100644
index 0000000..56fb9cd
--- /dev/null
+++ b/src/tint/lang/spirv/reader/ast_parser/parse.h
@@ -0,0 +1,35 @@
+// Copyright 2020 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TINT_LANG_SPIRV_READER_AST_PARSER_PARSE_H_
+#define SRC_TINT_LANG_SPIRV_READER_AST_PARSER_PARSE_H_
+
+#include <vector>
+
+#include "src/tint/lang/spirv/reader/common/options.h"
+#include "src/tint/lang/wgsl/program/program.h"
+
+namespace tint::spirv::reader::ast_parser {
+
+/// Parses the SPIR-V source data, returning the parsed program.
+/// If the source data fails to parse then the returned `program.Diagnostics.contains_errors()` will
+/// be true, and the `program.Diagnostics()` will describe the error.
+/// @param input the source data
+/// @param options the parser options
+/// @returns the parsed program
+Program Parse(const std::vector<uint32_t>& input, const Options& options);
+
+}  // namespace tint::spirv::reader::ast_parser
+
+#endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_PARSE_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
index ef18b0f..29c222a 100644
--- a/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/parser_test.cc
@@ -12,20 +12,20 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/spirv/reader/reader.h"
+#include "src/tint/lang/spirv/reader/ast_parser/parse.h"
 
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ParserTest = testing::Test;
 
 TEST_F(ParserTest, DataEmpty) {
     std::vector<uint32_t> data;
-    auto program = Parse(data);
+    auto program = Parse(data, {});
     auto errs = program.Diagnostics().str();
     ASSERT_FALSE(program.IsValid()) << errs;
     EXPECT_EQ(errs, "error: line:0: Invalid SPIR-V magic number.");
@@ -82,4 +82,4 @@
 // TODO(dneto): uint32 vec, invalid SPIR-V
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
index 26ef27f..bc067a5 100644
--- a/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.cc
@@ -18,7 +18,7 @@
 #include "spirv-tools/libspirv.hpp"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader::test {
+namespace tint::spirv::reader::ast_parser::test {
 
 std::vector<uint32_t> Assemble(const std::string& spirv_assembly) {
     // TODO(dneto): Use ScopedTrace?
@@ -55,4 +55,4 @@
     return result;
 }
 
-}  // namespace tint::spirv::reader::test
+}  // namespace tint::spirv::reader::ast_parser::test
diff --git a/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
index 456ceb2..2b2800b 100644
--- a/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
+++ b/src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h
@@ -18,7 +18,7 @@
 #include <string>
 #include <vector>
 
-namespace tint::spirv::reader::test {
+namespace tint::spirv::reader::ast_parser::test {
 
 /// @param spirv_assembly SPIR-V assembly text
 /// @returns the SPIR-V module assembled from the given text.  Numeric IDs
@@ -29,6 +29,6 @@
 /// @returns the disassembled module
 std::string Disassemble(const std::vector<uint32_t>& spirv_module);
 
-}  // namespace tint::spirv::reader::test
+}  // namespace tint::spirv::reader::ast_parser::test
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_SPIRV_TOOLS_HELPERS_TEST_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/type.cc b/src/tint/lang/spirv/reader/ast_parser/type.cc
index 115e6f5..fa36202 100644
--- a/src/tint/lang/spirv/reader/ast_parser/type.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/type.cc
@@ -28,29 +28,29 @@
 #include "src/tint/utils/text/string.h"
 #include "src/tint/utils/text/string_stream.h"
 
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Type);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Void);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Bool);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::U32);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::F32);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::I32);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Pointer);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Reference);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Vector);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Matrix);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Array);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Sampler);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Texture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::DepthTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::DepthMultisampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::MultisampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::SampledTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::StorageTexture);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Named);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Alias);
-TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::Struct);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Type);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Void);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Bool);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::U32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::F32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::I32);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Pointer);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Reference);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Vector);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Matrix);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Array);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Sampler);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Texture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::DepthTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::DepthMultisampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::MultisampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::SampledTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::StorageTexture);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Named);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Alias);
+TINT_INSTANTIATE_TYPEINFO(tint::spirv::reader::ast_parser::Struct);
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 namespace {
 struct PointerHasher {
@@ -309,42 +309,43 @@
     /// The allocator of primitive types
     BlockAllocator<Type> allocator_;
     /// The lazily-created Void type
-    reader::Void const* void_ = nullptr;
+    ast_parser::Void const* void_ = nullptr;
     /// The lazily-created Bool type
-    reader::Bool const* bool_ = nullptr;
+    ast_parser::Bool const* bool_ = nullptr;
     /// The lazily-created U32 type
-    reader::U32 const* u32_ = nullptr;
+    ast_parser::U32 const* u32_ = nullptr;
     /// The lazily-created F32 type
-    reader::F32 const* f32_ = nullptr;
+    ast_parser::F32 const* f32_ = nullptr;
     /// The lazily-created I32 type
-    reader::I32 const* i32_ = nullptr;
+    ast_parser::I32 const* i32_ = nullptr;
     /// Unique Pointer instances
-    UniqueAllocator<reader::Pointer, PointerHasher> pointers_;
+    UniqueAllocator<ast_parser::Pointer, PointerHasher> pointers_;
     /// Unique Reference instances
-    UniqueAllocator<reader::Reference, ReferenceHasher> references_;
+    UniqueAllocator<ast_parser::Reference, ReferenceHasher> references_;
     /// Unique Vector instances
-    UniqueAllocator<reader::Vector, VectorHasher> vectors_;
+    UniqueAllocator<ast_parser::Vector, VectorHasher> vectors_;
     /// Unique Matrix instances
-    UniqueAllocator<reader::Matrix, MatrixHasher> matrices_;
+    UniqueAllocator<ast_parser::Matrix, MatrixHasher> matrices_;
     /// Unique Array instances
-    UniqueAllocator<reader::Array, ArrayHasher> arrays_;
+    UniqueAllocator<ast_parser::Array, ArrayHasher> arrays_;
     /// Unique Alias instances
-    UniqueAllocator<reader::Alias, AliasHasher> aliases_;
+    UniqueAllocator<ast_parser::Alias, AliasHasher> aliases_;
     /// Unique Struct instances
-    UniqueAllocator<reader::Struct, StructHasher> structs_;
+    UniqueAllocator<ast_parser::Struct, StructHasher> structs_;
     /// Unique Sampler instances
-    UniqueAllocator<reader::Sampler, SamplerHasher> samplers_;
+    UniqueAllocator<ast_parser::Sampler, SamplerHasher> samplers_;
     /// Unique DepthTexture instances
-    UniqueAllocator<reader::DepthTexture, DepthTextureHasher> depth_textures_;
+    UniqueAllocator<ast_parser::DepthTexture, DepthTextureHasher> depth_textures_;
     /// Unique DepthMultisampledTexture instances
-    UniqueAllocator<reader::DepthMultisampledTexture, DepthMultisampledTextureHasher>
+    UniqueAllocator<ast_parser::DepthMultisampledTexture, DepthMultisampledTextureHasher>
         depth_multisampled_textures_;
     /// Unique MultisampledTexture instances
-    UniqueAllocator<reader::MultisampledTexture, MultisampledTextureHasher> multisampled_textures_;
+    UniqueAllocator<ast_parser::MultisampledTexture, MultisampledTextureHasher>
+        multisampled_textures_;
     /// Unique SampledTexture instances
-    UniqueAllocator<reader::SampledTexture, SampledTextureHasher> sampled_textures_;
+    UniqueAllocator<ast_parser::SampledTexture, SampledTextureHasher> sampled_textures_;
     /// Unique StorageTexture instances
-    UniqueAllocator<reader::StorageTexture, StorageTextureHasher> storage_textures_;
+    UniqueAllocator<ast_parser::StorageTexture, StorageTextureHasher> storage_textures_;
 };
 
 const Type* Type::UnwrapPtr() const {
@@ -431,114 +432,114 @@
 
 TypeManager::~TypeManager() = default;
 
-const reader::Void* TypeManager::Void() {
+const ast_parser::Void* TypeManager::Void() {
     if (!state->void_) {
-        state->void_ = state->allocator_.Create<reader::Void>();
+        state->void_ = state->allocator_.Create<ast_parser::Void>();
     }
     return state->void_;
 }
 
-const reader::Bool* TypeManager::Bool() {
+const ast_parser::Bool* TypeManager::Bool() {
     if (!state->bool_) {
-        state->bool_ = state->allocator_.Create<reader::Bool>();
+        state->bool_ = state->allocator_.Create<ast_parser::Bool>();
     }
     return state->bool_;
 }
 
-const reader::U32* TypeManager::U32() {
+const ast_parser::U32* TypeManager::U32() {
     if (!state->u32_) {
-        state->u32_ = state->allocator_.Create<reader::U32>();
+        state->u32_ = state->allocator_.Create<ast_parser::U32>();
     }
     return state->u32_;
 }
 
-const reader::F32* TypeManager::F32() {
+const ast_parser::F32* TypeManager::F32() {
     if (!state->f32_) {
-        state->f32_ = state->allocator_.Create<reader::F32>();
+        state->f32_ = state->allocator_.Create<ast_parser::F32>();
     }
     return state->f32_;
 }
 
-const reader::I32* TypeManager::I32() {
+const ast_parser::I32* TypeManager::I32() {
     if (!state->i32_) {
-        state->i32_ = state->allocator_.Create<reader::I32>();
+        state->i32_ = state->allocator_.Create<ast_parser::I32>();
     }
     return state->i32_;
 }
 
 const Type* TypeManager::AsUnsigned(const Type* ty) {
     return Switch(
-        ty,                                         //
-        [&](const reader::I32*) { return U32(); },  //
-        [&](const reader::U32*) { return ty; },     //
-        [&](const reader::Vector* vec) {
+        ty,                                             //
+        [&](const ast_parser::I32*) { return U32(); },  //
+        [&](const ast_parser::U32*) { return ty; },     //
+        [&](const ast_parser::Vector* vec) {
             return Switch(
-                vec->type,                                                     //
-                [&](const reader::I32*) { return Vector(U32(), vec->size); },  //
-                [&](const reader::U32*) { return ty; }                         //
+                vec->type,                                                         //
+                [&](const ast_parser::I32*) { return Vector(U32(), vec->size); },  //
+                [&](const ast_parser::U32*) { return ty; }                         //
             );
         });
 }
 
-const reader::Pointer* TypeManager::Pointer(core::AddressSpace address_space,
-                                            const Type* el,
-                                            core::Access access) {
+const ast_parser::Pointer* TypeManager::Pointer(core::AddressSpace address_space,
+                                                const Type* el,
+                                                core::Access access) {
     return state->pointers_.Get(address_space, el, access);
 }
 
-const reader::Reference* TypeManager::Reference(core::AddressSpace address_space,
-                                                const Type* el,
-                                                core::Access access) {
+const ast_parser::Reference* TypeManager::Reference(core::AddressSpace address_space,
+                                                    const Type* el,
+                                                    core::Access access) {
     return state->references_.Get(address_space, el, access);
 }
 
-const reader::Vector* TypeManager::Vector(const Type* el, uint32_t size) {
+const ast_parser::Vector* TypeManager::Vector(const Type* el, uint32_t size) {
     return state->vectors_.Get(el, size);
 }
 
-const reader::Matrix* TypeManager::Matrix(const Type* el, uint32_t columns, uint32_t rows) {
+const ast_parser::Matrix* TypeManager::Matrix(const Type* el, uint32_t columns, uint32_t rows) {
     return state->matrices_.Get(el, columns, rows);
 }
 
-const reader::Array* TypeManager::Array(const Type* el, uint32_t size, uint32_t stride) {
+const ast_parser::Array* TypeManager::Array(const Type* el, uint32_t size, uint32_t stride) {
     return state->arrays_.Get(el, size, stride);
 }
 
-const reader::Alias* TypeManager::Alias(Symbol name, const Type* ty) {
+const ast_parser::Alias* TypeManager::Alias(Symbol name, const Type* ty) {
     return state->aliases_.Get(name, ty);
 }
 
-const reader::Struct* TypeManager::Struct(Symbol name, TypeList members) {
+const ast_parser::Struct* TypeManager::Struct(Symbol name, TypeList members) {
     return state->structs_.Get(name, std::move(members));
 }
 
-const reader::Sampler* TypeManager::Sampler(core::type::SamplerKind kind) {
+const ast_parser::Sampler* TypeManager::Sampler(core::type::SamplerKind kind) {
     return state->samplers_.Get(kind);
 }
 
-const reader::DepthTexture* TypeManager::DepthTexture(core::type::TextureDimension dims) {
+const ast_parser::DepthTexture* TypeManager::DepthTexture(core::type::TextureDimension dims) {
     return state->depth_textures_.Get(dims);
 }
 
-const reader::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
+const ast_parser::DepthMultisampledTexture* TypeManager::DepthMultisampledTexture(
     core::type::TextureDimension dims) {
     return state->depth_multisampled_textures_.Get(dims);
 }
 
-const reader::MultisampledTexture* TypeManager::MultisampledTexture(
+const ast_parser::MultisampledTexture* TypeManager::MultisampledTexture(
     core::type::TextureDimension dims,
     const Type* ty) {
     return state->multisampled_textures_.Get(dims, ty);
 }
 
-const reader::SampledTexture* TypeManager::SampledTexture(core::type::TextureDimension dims,
-                                                          const Type* ty) {
+const ast_parser::SampledTexture* TypeManager::SampledTexture(core::type::TextureDimension dims,
+                                                              const Type* ty) {
     return state->sampled_textures_.Get(dims, ty);
 }
 
-const reader::StorageTexture* TypeManager::StorageTexture(core::type::TextureDimension dims,
-                                                          core::TexelFormat fmt,
-                                                          core::Access access) {
+const ast_parser::StorageTexture* TypeManager::StorageTexture(core::type::TextureDimension dims,
+                                                              core::TexelFormat fmt,
+                                                              core::Access access) {
     return state->storage_textures_.Get(dims, fmt, access);
 }
 
@@ -639,4 +640,4 @@
 }
 #endif  // NDEBUG
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/type.h b/src/tint/lang/spirv/reader/ast_parser/type.h
index 65b95f8..60c31eb 100644
--- a/src/tint/lang/spirv/reader/ast_parser/type.h
+++ b/src/tint/lang/spirv/reader/ast_parser/type.h
@@ -34,7 +34,7 @@
 class ProgramBuilder;
 }  // namespace tint
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// Type is the base class for all types
 class Type : public Castable<Type> {
@@ -529,15 +529,15 @@
     ~TypeManager();
 
     /// @return a Void type. Repeated calls will return the same pointer.
-    const reader::Void* Void();
+    const ast_parser::Void* Void();
     /// @return a Bool type. Repeated calls will return the same pointer.
-    const reader::Bool* Bool();
+    const ast_parser::Bool* Bool();
     /// @return a U32 type. Repeated calls will return the same pointer.
-    const reader::U32* U32();
+    const ast_parser::U32* U32();
     /// @return a F32 type. Repeated calls will return the same pointer.
-    const reader::F32* F32();
+    const ast_parser::F32* F32();
     /// @return a I32 type. Repeated calls will return the same pointer.
-    const reader::I32* I32();
+    const ast_parser::I32* I32();
     /// @param ty the input type.
     /// @returns the equivalent unsigned integer scalar or vector if @p ty is a scalar or vector,
     /// otherwise nullptr.
@@ -548,83 +548,83 @@
     /// @param access the declared access mode
     /// @return a Pointer type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Pointer* Pointer(core::AddressSpace address_space,
-                                   const Type* ty,
-                                   core::Access access = core::Access::kUndefined);
+    const ast_parser::Pointer* Pointer(core::AddressSpace address_space,
+                                       const Type* ty,
+                                       core::Access access = core::Access::kUndefined);
     /// @param address_space the reference address space
     /// @param ty the referenced type
     /// @param access the declared access mode
     /// @return a Reference type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const reader::Reference* Reference(core::AddressSpace address_space,
-                                       const Type* ty,
-                                       core::Access access = core::Access::kUndefined);
+    const ast_parser::Reference* Reference(core::AddressSpace address_space,
+                                           const Type* ty,
+                                           core::Access access = core::Access::kUndefined);
     /// @param ty the element type
     /// @param sz the number of elements in the vector
     /// @return a Vector type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Vector* Vector(const Type* ty, uint32_t sz);
+    const ast_parser::Vector* Vector(const Type* ty, uint32_t sz);
     /// @param ty the matrix element type
     /// @param c the number of columns in the matrix
     /// @param r the number of rows in the matrix
     /// @return a Matrix type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Matrix* Matrix(const Type* ty, uint32_t c, uint32_t r);
+    const ast_parser::Matrix* Matrix(const Type* ty, uint32_t c, uint32_t r);
     /// @param el the element type
     /// @param sz the number of elements in the array. 0 represents runtime-sized
     /// array.
     /// @param st the byte stride of the array
     /// @return a Array type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Array* Array(const Type* el, uint32_t sz, uint32_t st);
+    const ast_parser::Array* Array(const Type* el, uint32_t sz, uint32_t st);
     /// @param n the alias name
     /// @param t the aliased type
     /// @return a Alias type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Alias* Alias(Symbol n, const Type* t);
+    const ast_parser::Alias* Alias(Symbol n, const Type* t);
     /// @param n the struct name
     /// @param m the member types
     /// @return a Struct type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Struct* Struct(Symbol n, TypeList m);
+    const ast_parser::Struct* Struct(Symbol n, TypeList m);
     /// @param k the sampler kind
     /// @return a Sampler type. Repeated calls with the same arguments will return
     /// the same pointer.
-    const reader::Sampler* Sampler(core::type::SamplerKind k);
+    const ast_parser::Sampler* Sampler(core::type::SamplerKind k);
     /// @param d the texture dimensions
     /// @return a DepthTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const reader::DepthTexture* DepthTexture(core::type::TextureDimension d);
+    const ast_parser::DepthTexture* DepthTexture(core::type::TextureDimension d);
     /// @param d the texture dimensions
     /// @return a DepthMultisampledTexture type. Repeated calls with the same
     /// arguments will return the same pointer.
-    const reader::DepthMultisampledTexture* DepthMultisampledTexture(
+    const ast_parser::DepthMultisampledTexture* DepthMultisampledTexture(
         core::type::TextureDimension d);
     /// @param d the texture dimensions
     /// @param t the multisampled texture type
     /// @return a MultisampledTexture type. Repeated calls with the same arguments
     /// will return the same pointer.
-    const reader::MultisampledTexture* MultisampledTexture(core::type::TextureDimension d,
-                                                           const Type* t);
+    const ast_parser::MultisampledTexture* MultisampledTexture(core::type::TextureDimension d,
+                                                               const Type* t);
     /// @param d the texture dimensions
     /// @param t the sampled texture type
     /// @return a SampledTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const reader::SampledTexture* SampledTexture(core::type::TextureDimension d, const Type* t);
+    const ast_parser::SampledTexture* SampledTexture(core::type::TextureDimension d, const Type* t);
     /// @param d the texture dimensions
     /// @param f the storage image format
     /// @param a the access control
     /// @return a StorageTexture type. Repeated calls with the same arguments will
     /// return the same pointer.
-    const reader::StorageTexture* StorageTexture(core::type::TextureDimension d,
-                                                 core::TexelFormat f,
-                                                 core::Access a);
+    const ast_parser::StorageTexture* StorageTexture(core::type::TextureDimension d,
+                                                     core::TexelFormat f,
+                                                     core::Access a);
 
   private:
     struct State;
     std::unique_ptr<State> state;
 };
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_TYPE_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/type_test.cc b/src/tint/lang/spirv/reader/ast_parser/type_test.cc
index 1cbd2ff..1ccaedc 100644
--- a/src/tint/lang/spirv/reader/ast_parser/type_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/type_test.cc
@@ -17,7 +17,7 @@
 #include "src/tint/lang/core/type/texture_dimension.h"
 #include "src/tint/lang/spirv/reader/ast_parser/type.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 TEST(SpirvASTParserTypeTest, SameArgumentsGivesSamePointer) {
@@ -96,4 +96,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/usage.cc b/src/tint/lang/spirv/reader/ast_parser/usage.cc
index 0b4d447..0a67cac 100644
--- a/src/tint/lang/spirv/reader/ast_parser/usage.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/usage.cc
@@ -16,7 +16,7 @@
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 Usage::Usage() {}
 Usage::Usage(const Usage& other) = default;
@@ -184,4 +184,4 @@
     return ss.str();
 }
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/usage.h b/src/tint/lang/spirv/reader/ast_parser/usage.h
index 144abe4..cf55287 100644
--- a/src/tint/lang/spirv/reader/ast_parser/usage.h
+++ b/src/tint/lang/spirv/reader/ast_parser/usage.h
@@ -20,7 +20,7 @@
 #include "src/tint/utils/text/string_stream.h"
 #include "src/tint/utils/traits/traits.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 
 /// Records the properties of a sampler or texture based on how it's used
 /// by image instructions inside function bodies.
@@ -134,6 +134,6 @@
     return u.operator<<(out);
 }
 
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
 
 #endif  // SRC_TINT_LANG_SPIRV_READER_AST_PARSER_USAGE_H_
diff --git a/src/tint/lang/spirv/reader/ast_parser/usage_test.cc b/src/tint/lang/spirv/reader/ast_parser/usage_test.cc
index b073675..fb6dee1 100644
--- a/src/tint/lang/spirv/reader/ast_parser/usage_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/usage_test.cc
@@ -19,7 +19,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -289,4 +289,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc b/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
index f964787..a0cff55 100644
--- a/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
+++ b/src/tint/lang/spirv/reader/ast_parser/user_name_test.cc
@@ -16,7 +16,7 @@
 #include "src/tint/lang/spirv/reader/ast_parser/helper_test.h"
 #include "src/tint/lang/spirv/reader/ast_parser/spirv_tools_helpers_test.h"
 
-namespace tint::spirv::reader {
+namespace tint::spirv::reader::ast_parser {
 namespace {
 
 using ::testing::Eq;
@@ -208,4 +208,4 @@
 }
 
 }  // namespace
-}  // namespace tint::spirv::reader
+}  // namespace tint::spirv::reader::ast_parser
diff --git a/src/tint/lang/spirv/reader/options.h b/src/tint/lang/spirv/reader/common/options.h
similarity index 84%
rename from src/tint/lang/spirv/reader/options.h
rename to src/tint/lang/spirv/reader/common/options.h
index fe74e15..6dddb44 100644
--- a/src/tint/lang/spirv/reader/options.h
+++ b/src/tint/lang/spirv/reader/common/options.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
-#define SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
+#ifndef SRC_TINT_LANG_SPIRV_READER_COMMON_OPTIONS_H_
+#define SRC_TINT_LANG_SPIRV_READER_COMMON_OPTIONS_H_
 
 namespace tint::spirv::reader {
 
@@ -25,4 +25,4 @@
 
 }  // namespace tint::spirv::reader
 
-#endif  // SRC_TINT_LANG_SPIRV_READER_OPTIONS_H_
+#endif  // SRC_TINT_LANG_SPIRV_READER_COMMON_OPTIONS_H_
diff --git a/src/tint/lang/spirv/reader/reader.cc b/src/tint/lang/spirv/reader/reader.cc
index 96091ed..15d0dc3 100644
--- a/src/tint/lang/spirv/reader/reader.cc
+++ b/src/tint/lang/spirv/reader/reader.cc
@@ -16,58 +16,12 @@
 
 #include <utility>
 
-#include "src/tint/lang/spirv/reader/ast_parser/ast_parser.h"
-#include "src/tint/lang/wgsl/ast/transform/decompose_strided_array.h"
-#include "src/tint/lang/wgsl/ast/transform/decompose_strided_matrix.h"
-#include "src/tint/lang/wgsl/ast/transform/fold_trivial_lets.h"
-#include "src/tint/lang/wgsl/ast/transform/manager.h"
-#include "src/tint/lang/wgsl/ast/transform/remove_unreachable_statements.h"
-#include "src/tint/lang/wgsl/ast/transform/simplify_pointers.h"
-#include "src/tint/lang/wgsl/ast/transform/spirv_atomic.h"
-#include "src/tint/lang/wgsl/ast/transform/unshadow.h"
-#include "src/tint/lang/wgsl/program/clone_context.h"
-#include "src/tint/lang/wgsl/resolver/resolve.h"
+#include "src/tint/lang/spirv/reader/ast_parser/parse.h"
 
 namespace tint::spirv::reader {
 
-Program Parse(const std::vector<uint32_t>& input, const Options& options) {
-    ASTParser parser(input);
-    bool parsed = parser.Parse();
-
-    ProgramBuilder& builder = parser.builder();
-    if (!parsed) {
-        // TODO(bclayton): Migrate ASTParser to using diagnostics.
-        builder.Diagnostics().add_error(diag::System::Reader, parser.error());
-        return Program(std::move(builder));
-    }
-
-    if (options.allow_non_uniform_derivatives) {
-        // Suppress errors regarding non-uniform derivative operations if requested, by adding a
-        // diagnostic directive to the module.
-        builder.DiagnosticDirective(core::DiagnosticSeverity::kOff, "derivative_uniformity");
-    }
-
-    // The SPIR-V parser can construct disjoint AST nodes, which is invalid for
-    // the Resolver. Clone the Program to clean these up.
-    Program program_with_disjoint_ast(std::move(builder));
-
-    ProgramBuilder output;
-    program::CloneContext(&output, &program_with_disjoint_ast, false).Clone();
-    auto program = Program(resolver::Resolve(output));
-    if (!program.IsValid()) {
-        return program;
-    }
-
-    ast::transform::Manager manager;
-    ast::transform::DataMap outputs;
-    manager.Add<ast::transform::Unshadow>();
-    manager.Add<ast::transform::SimplifyPointers>();
-    manager.Add<ast::transform::FoldTrivialLets>();
-    manager.Add<ast::transform::DecomposeStridedMatrix>();
-    manager.Add<ast::transform::DecomposeStridedArray>();
-    manager.Add<ast::transform::RemoveUnreachableStatements>();
-    manager.Add<ast::transform::SpirvAtomic>();
-    return manager.Run(&program, {}, outputs);
+Program Read(const std::vector<uint32_t>& input, const Options& options) {
+    return ast_parser::Parse(input, options);
 }
 
 }  // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/reader.h b/src/tint/lang/spirv/reader/reader.h
index 5840ac4..aa0de9b 100644
--- a/src/tint/lang/spirv/reader/reader.h
+++ b/src/tint/lang/spirv/reader/reader.h
@@ -17,19 +17,19 @@
 
 #include <vector>
 
-#include "src/tint/lang/spirv/reader/options.h"
+#include "src/tint/lang/spirv/reader/common/options.h"
 #include "src/tint/lang/wgsl/program/program.h"
 
 namespace tint::spirv::reader {
 
-/// Parses the SPIR-V source data, returning the parsed program.
+/// Reads the SPIR-V source data, returning the parsed program.
 /// If the source data fails to parse then the returned
 /// `program.Diagnostics.contains_errors()` will be true, and the
 /// `program.Diagnostics()` will describe the error.
 /// @param input the source data
 /// @param options the parser options
 /// @returns the parsed program
-Program Parse(const std::vector<uint32_t>& input, const Options& options = {});
+Program Read(const std::vector<uint32_t>& input, const Options& options = {});
 
 }  // namespace tint::spirv::reader