[shuffle] Move wgsl reader to new structure.

This CL moves the `wgsl/reader` to `wgsl/reader/parser/`.

Bug: tint:1988
Change-Id: Ic9d4b9b93e86e3cbd923c8e56def7c95554aeb26
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/143320
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: James Price <jrprice@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/include/tint/tint.h b/include/tint/tint.h
index e401ec6..4fba869 100644
--- a/include/tint/tint.h
+++ b/include/tint/tint.h
@@ -40,7 +40,7 @@
 #endif  // TINT_BUILD_SPV_READER
 
 #if TINT_BUILD_WGSL_READER
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #endif  // TINT_BUILD_WGSL_READER
 
 #if TINT_BUILD_SPV_WRITER
diff --git a/src/dawn/native/ShaderModule.cpp b/src/dawn/native/ShaderModule.cpp
index 6158faf..0eb480b 100644
--- a/src/dawn/native/ShaderModule.cpp
+++ b/src/dawn/native/ShaderModule.cpp
@@ -301,7 +301,7 @@
 ResultOrError<tint::Program> ParseWGSL(const tint::Source::File* file,
                                        OwnedCompilationMessages* outMessages) {
 #if TINT_BUILD_WGSL_READER
-    tint::Program program = tint::reader::wgsl::Parse(file);
+    tint::Program program = tint::wgsl::reader::Parse(file);
     if (outMessages != nullptr) {
         DAWN_TRY(outMessages->AddMessages(program.Diagnostics()));
     }
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 1707c00..c0444aa 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -1044,17 +1044,17 @@
 
 libtint_source_set("libtint_wgsl_reader_src") {
   sources = [
-    "lang/wgsl/reader/classify_template_args.cc",
-    "lang/wgsl/reader/classify_template_args.h",
-    "lang/wgsl/reader/lexer.cc",
-    "lang/wgsl/reader/lexer.h",
-    "lang/wgsl/reader/parser.cc",
-    "lang/wgsl/reader/parser.h",
-    "lang/wgsl/reader/parser_impl.cc",
-    "lang/wgsl/reader/parser_impl.h",
-    "lang/wgsl/reader/parser_impl_detail.h",
-    "lang/wgsl/reader/token.cc",
-    "lang/wgsl/reader/token.h",
+    "lang/wgsl/reader/parser/classify_template_args.cc",
+    "lang/wgsl/reader/parser/classify_template_args.h",
+    "lang/wgsl/reader/parser/detail.h",
+    "lang/wgsl/reader/parser/lexer.cc",
+    "lang/wgsl/reader/parser/lexer.h",
+    "lang/wgsl/reader/parser/parser.cc",
+    "lang/wgsl/reader/parser/parser.h",
+    "lang/wgsl/reader/parser/token.cc",
+    "lang/wgsl/reader/parser/token.h",
+    "lang/wgsl/reader/reader.cc",
+    "lang/wgsl/reader/reader.h",
   ]
 
   deps = [
@@ -2069,74 +2069,73 @@
 
   tint_unittests_source_set("tint_unittests_wgsl_reader_src") {
     sources = [
-      "lang/wgsl/reader/classify_template_args_test.cc",
-      "lang/wgsl/reader/lexer_test.cc",
-      "lang/wgsl/reader/parser_impl_additive_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_argument_expression_list_test.cc",
-      "lang/wgsl/reader/parser_impl_assignment_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_bitwise_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_break_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_bug_cases_test.cc",
-      "lang/wgsl/reader/parser_impl_call_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_compound_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_const_literal_test.cc",
-      "lang/wgsl/reader/parser_impl_continue_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_continuing_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_core_lhs_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_diagnostic_attribute_test.cc",
-      "lang/wgsl/reader/parser_impl_diagnostic_control_test.cc",
-      "lang/wgsl/reader/parser_impl_diagnostic_directive_test.cc",
-      "lang/wgsl/reader/parser_impl_enable_directive_test.cc",
-      "lang/wgsl/reader/parser_impl_error_msg_test.cc",
-      "lang/wgsl/reader/parser_impl_error_resync_test.cc",
-      "lang/wgsl/reader/parser_impl_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_for_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_function_attribute_list_test.cc",
-      "lang/wgsl/reader/parser_impl_function_attribute_test.cc",
-      "lang/wgsl/reader/parser_impl_function_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_function_header_test.cc",
-      "lang/wgsl/reader/parser_impl_global_constant_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_global_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_global_variable_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_if_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_increment_decrement_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_lhs_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_loop_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_math_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_multiplicative_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_param_list_test.cc",
-      "lang/wgsl/reader/parser_impl_paren_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_primary_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_relational_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_require_directive_test.cc",
-      "lang/wgsl/reader/parser_impl_reserved_keyword_test.cc",
-      "lang/wgsl/reader/parser_impl_shift_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_singular_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_statement_test.cc",
-      "lang/wgsl/reader/parser_impl_statements_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_attribute_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_body_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_member_attribute_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_member_attribute_test.cc",
-      "lang/wgsl/reader/parser_impl_struct_member_test.cc",
-      "lang/wgsl/reader/parser_impl_switch_body_test.cc",
-      "lang/wgsl/reader/parser_impl_switch_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_test.cc",
-      "lang/wgsl/reader/parser_impl_test_helper.cc",
-      "lang/wgsl/reader/parser_impl_test_helper.h",
-      "lang/wgsl/reader/parser_impl_type_alias_test.cc",
-      "lang/wgsl/reader/parser_impl_type_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_unary_expression_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_attribute_list_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_attribute_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_ident_decl_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_qualifier_test.cc",
-      "lang/wgsl/reader/parser_impl_variable_stmt_test.cc",
-      "lang/wgsl/reader/parser_impl_while_stmt_test.cc",
-      "lang/wgsl/reader/parser_test.cc",
-      "lang/wgsl/reader/token_test.cc",
+      "lang/wgsl/reader/parser/additive_expression_test.cc",
+      "lang/wgsl/reader/parser/argument_expression_list_test.cc",
+      "lang/wgsl/reader/parser/assignment_stmt_test.cc",
+      "lang/wgsl/reader/parser/bitwise_expression_test.cc",
+      "lang/wgsl/reader/parser/break_stmt_test.cc",
+      "lang/wgsl/reader/parser/bug_cases_test.cc",
+      "lang/wgsl/reader/parser/call_stmt_test.cc",
+      "lang/wgsl/reader/parser/classify_template_args_test.cc",
+      "lang/wgsl/reader/parser/compound_stmt_test.cc",
+      "lang/wgsl/reader/parser/const_literal_test.cc",
+      "lang/wgsl/reader/parser/continue_stmt_test.cc",
+      "lang/wgsl/reader/parser/continuing_stmt_test.cc",
+      "lang/wgsl/reader/parser/core_lhs_expression_test.cc",
+      "lang/wgsl/reader/parser/diagnostic_attribute_test.cc",
+      "lang/wgsl/reader/parser/diagnostic_control_test.cc",
+      "lang/wgsl/reader/parser/diagnostic_directive_test.cc",
+      "lang/wgsl/reader/parser/enable_directive_test.cc",
+      "lang/wgsl/reader/parser/error_msg_test.cc",
+      "lang/wgsl/reader/parser/error_resync_test.cc",
+      "lang/wgsl/reader/parser/expression_test.cc",
+      "lang/wgsl/reader/parser/for_stmt_test.cc",
+      "lang/wgsl/reader/parser/function_attribute_list_test.cc",
+      "lang/wgsl/reader/parser/function_attribute_test.cc",
+      "lang/wgsl/reader/parser/function_decl_test.cc",
+      "lang/wgsl/reader/parser/function_header_test.cc",
+      "lang/wgsl/reader/parser/global_constant_decl_test.cc",
+      "lang/wgsl/reader/parser/global_decl_test.cc",
+      "lang/wgsl/reader/parser/global_variable_decl_test.cc",
+      "lang/wgsl/reader/parser/if_stmt_test.cc",
+      "lang/wgsl/reader/parser/increment_decrement_stmt_test.cc",
+      "lang/wgsl/reader/parser/lexer_test.cc",
+      "lang/wgsl/reader/parser/lhs_expression_test.cc",
+      "lang/wgsl/reader/parser/loop_stmt_test.cc",
+      "lang/wgsl/reader/parser/math_expression_test.cc",
+      "lang/wgsl/reader/parser/multiplicative_expression_test.cc",
+      "lang/wgsl/reader/parser/param_list_test.cc",
+      "lang/wgsl/reader/parser/paren_expression_test.cc",
+      "lang/wgsl/reader/parser/parser_test.cc",
+      "lang/wgsl/reader/parser/primary_expression_test.cc",
+      "lang/wgsl/reader/parser/relational_expression_test.cc",
+      "lang/wgsl/reader/parser/require_directive_test.cc",
+      "lang/wgsl/reader/parser/reserved_keyword_test.cc",
+      "lang/wgsl/reader/parser/shift_expression_test.cc",
+      "lang/wgsl/reader/parser/singular_expression_test.cc",
+      "lang/wgsl/reader/parser/statement_test.cc",
+      "lang/wgsl/reader/parser/statements_test.cc",
+      "lang/wgsl/reader/parser/struct_attribute_decl_test.cc",
+      "lang/wgsl/reader/parser/struct_body_decl_test.cc",
+      "lang/wgsl/reader/parser/struct_decl_test.cc",
+      "lang/wgsl/reader/parser/struct_member_attribute_decl_test.cc",
+      "lang/wgsl/reader/parser/struct_member_attribute_test.cc",
+      "lang/wgsl/reader/parser/struct_member_test.cc",
+      "lang/wgsl/reader/parser/switch_body_test.cc",
+      "lang/wgsl/reader/parser/switch_stmt_test.cc",
+      "lang/wgsl/reader/parser/test_helper.cc",
+      "lang/wgsl/reader/parser/test_helper.h",
+      "lang/wgsl/reader/parser/token_test.cc",
+      "lang/wgsl/reader/parser/type_alias_test.cc",
+      "lang/wgsl/reader/parser/type_decl_test.cc",
+      "lang/wgsl/reader/parser/unary_expression_test.cc",
+      "lang/wgsl/reader/parser/variable_attribute_list_test.cc",
+      "lang/wgsl/reader/parser/variable_attribute_test.cc",
+      "lang/wgsl/reader/parser/variable_decl_test.cc",
+      "lang/wgsl/reader/parser/variable_ident_decl_test.cc",
+      "lang/wgsl/reader/parser/variable_qualifier_test.cc",
+      "lang/wgsl/reader/parser/variable_stmt_test.cc",
+      "lang/wgsl/reader/parser/while_stmt_test.cc",
     ]
 
     deps = [
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index d1a0911..ffbaa25 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -622,17 +622,17 @@
 
 if(${TINT_BUILD_WGSL_READER})
   list(APPEND TINT_LIB_SRCS
-    lang/wgsl/reader/classify_template_args.cc
-    lang/wgsl/reader/classify_template_args.h
-    lang/wgsl/reader/lexer.cc
-    lang/wgsl/reader/lexer.h
-    lang/wgsl/reader/parser.cc
-    lang/wgsl/reader/parser.h
-    lang/wgsl/reader/parser_impl.cc
-    lang/wgsl/reader/parser_impl.h
-    lang/wgsl/reader/parser_impl_detail.h
-    lang/wgsl/reader/token.cc
-    lang/wgsl/reader/token.h
+    lang/wgsl/reader/parser/classify_template_args.cc
+    lang/wgsl/reader/parser/classify_template_args.h
+    lang/wgsl/reader/parser/detail.h
+    lang/wgsl/reader/parser/lexer.cc
+    lang/wgsl/reader/parser/lexer.h
+    lang/wgsl/reader/parser/parser.cc
+    lang/wgsl/reader/parser/parser.h
+    lang/wgsl/reader/parser/token.cc
+    lang/wgsl/reader/parser/token.h
+    lang/wgsl/reader/reader.cc
+    lang/wgsl/reader/reader.h
   )
 endif()
 
@@ -1223,74 +1223,73 @@
 
   if(${TINT_BUILD_WGSL_READER})
     list(APPEND TINT_TEST_SRCS
-      lang/wgsl/reader/classify_template_args_test.cc
-      lang/wgsl/reader/lexer_test.cc
-      lang/wgsl/reader/parser_test.cc
-      lang/wgsl/reader/parser_impl_additive_expression_test.cc
-      lang/wgsl/reader/parser_impl_argument_expression_list_test.cc
-      lang/wgsl/reader/parser_impl_assignment_stmt_test.cc
-      lang/wgsl/reader/parser_impl_bitwise_expression_test.cc
-      lang/wgsl/reader/parser_impl_break_stmt_test.cc
-      lang/wgsl/reader/parser_impl_bug_cases_test.cc
-      lang/wgsl/reader/parser_impl_call_stmt_test.cc
-      lang/wgsl/reader/parser_impl_compound_stmt_test.cc
-      lang/wgsl/reader/parser_impl_const_literal_test.cc
-      lang/wgsl/reader/parser_impl_continue_stmt_test.cc
-      lang/wgsl/reader/parser_impl_continuing_stmt_test.cc
-      lang/wgsl/reader/parser_impl_core_lhs_expression_test.cc
-      lang/wgsl/reader/parser_impl_diagnostic_attribute_test.cc
-      lang/wgsl/reader/parser_impl_diagnostic_control_test.cc
-      lang/wgsl/reader/parser_impl_diagnostic_directive_test.cc
-      lang/wgsl/reader/parser_impl_enable_directive_test.cc
-      lang/wgsl/reader/parser_impl_error_msg_test.cc
-      lang/wgsl/reader/parser_impl_error_resync_test.cc
-      lang/wgsl/reader/parser_impl_expression_test.cc
-      lang/wgsl/reader/parser_impl_for_stmt_test.cc
-      lang/wgsl/reader/parser_impl_function_decl_test.cc
-      lang/wgsl/reader/parser_impl_function_attribute_list_test.cc
-      lang/wgsl/reader/parser_impl_function_attribute_test.cc
-      lang/wgsl/reader/parser_impl_function_header_test.cc
-      lang/wgsl/reader/parser_impl_global_constant_decl_test.cc
-      lang/wgsl/reader/parser_impl_global_decl_test.cc
-      lang/wgsl/reader/parser_impl_global_variable_decl_test.cc
-      lang/wgsl/reader/parser_impl_if_stmt_test.cc
-      lang/wgsl/reader/parser_impl_increment_decrement_stmt_test.cc
-      lang/wgsl/reader/parser_impl_lhs_expression_test.cc
-      lang/wgsl/reader/parser_impl_loop_stmt_test.cc
-      lang/wgsl/reader/parser_impl_math_expression_test.cc
-      lang/wgsl/reader/parser_impl_multiplicative_expression_test.cc
-      lang/wgsl/reader/parser_impl_param_list_test.cc
-      lang/wgsl/reader/parser_impl_paren_expression_test.cc
-      lang/wgsl/reader/parser_impl_primary_expression_test.cc
-      lang/wgsl/reader/parser_impl_relational_expression_test.cc
-      lang/wgsl/reader/parser_impl_reserved_keyword_test.cc
-      lang/wgsl/reader/parser_impl_require_directive_test.cc
-      lang/wgsl/reader/parser_impl_shift_expression_test.cc
-      lang/wgsl/reader/parser_impl_singular_expression_test.cc
-      lang/wgsl/reader/parser_impl_statement_test.cc
-      lang/wgsl/reader/parser_impl_statements_test.cc
-      lang/wgsl/reader/parser_impl_struct_body_decl_test.cc
-      lang/wgsl/reader/parser_impl_struct_decl_test.cc
-      lang/wgsl/reader/parser_impl_struct_attribute_decl_test.cc
-      lang/wgsl/reader/parser_impl_struct_member_attribute_decl_test.cc
-      lang/wgsl/reader/parser_impl_struct_member_attribute_test.cc
-      lang/wgsl/reader/parser_impl_struct_member_test.cc
-      lang/wgsl/reader/parser_impl_switch_body_test.cc
-      lang/wgsl/reader/parser_impl_switch_stmt_test.cc
-      lang/wgsl/reader/parser_impl_test.cc
-      lang/wgsl/reader/parser_impl_test_helper.cc
-      lang/wgsl/reader/parser_impl_test_helper.h
-      lang/wgsl/reader/parser_impl_type_alias_test.cc
-      lang/wgsl/reader/parser_impl_type_decl_test.cc
-      lang/wgsl/reader/parser_impl_unary_expression_test.cc
-      lang/wgsl/reader/parser_impl_variable_decl_test.cc
-      lang/wgsl/reader/parser_impl_variable_attribute_list_test.cc
-      lang/wgsl/reader/parser_impl_variable_attribute_test.cc
-      lang/wgsl/reader/parser_impl_variable_ident_decl_test.cc
-      lang/wgsl/reader/parser_impl_variable_stmt_test.cc
-      lang/wgsl/reader/parser_impl_variable_qualifier_test.cc
-      lang/wgsl/reader/parser_impl_while_stmt_test.cc
-      lang/wgsl/reader/token_test.cc
+      lang/wgsl/reader/parser/additive_expression_test.cc
+      lang/wgsl/reader/parser/argument_expression_list_test.cc
+      lang/wgsl/reader/parser/assignment_stmt_test.cc
+      lang/wgsl/reader/parser/bitwise_expression_test.cc
+      lang/wgsl/reader/parser/break_stmt_test.cc
+      lang/wgsl/reader/parser/bug_cases_test.cc
+      lang/wgsl/reader/parser/call_stmt_test.cc
+      lang/wgsl/reader/parser/classify_template_args_test.cc
+      lang/wgsl/reader/parser/compound_stmt_test.cc
+      lang/wgsl/reader/parser/const_literal_test.cc
+      lang/wgsl/reader/parser/continue_stmt_test.cc
+      lang/wgsl/reader/parser/continuing_stmt_test.cc
+      lang/wgsl/reader/parser/core_lhs_expression_test.cc
+      lang/wgsl/reader/parser/diagnostic_attribute_test.cc
+      lang/wgsl/reader/parser/diagnostic_control_test.cc
+      lang/wgsl/reader/parser/diagnostic_directive_test.cc
+      lang/wgsl/reader/parser/enable_directive_test.cc
+      lang/wgsl/reader/parser/error_msg_test.cc
+      lang/wgsl/reader/parser/error_resync_test.cc
+      lang/wgsl/reader/parser/expression_test.cc
+      lang/wgsl/reader/parser/for_stmt_test.cc
+      lang/wgsl/reader/parser/function_attribute_list_test.cc
+      lang/wgsl/reader/parser/function_attribute_test.cc
+      lang/wgsl/reader/parser/function_decl_test.cc
+      lang/wgsl/reader/parser/function_header_test.cc
+      lang/wgsl/reader/parser/global_constant_decl_test.cc
+      lang/wgsl/reader/parser/global_decl_test.cc
+      lang/wgsl/reader/parser/global_variable_decl_test.cc
+      lang/wgsl/reader/parser/if_stmt_test.cc
+      lang/wgsl/reader/parser/increment_decrement_stmt_test.cc
+      lang/wgsl/reader/parser/lexer_test.cc
+      lang/wgsl/reader/parser/lhs_expression_test.cc
+      lang/wgsl/reader/parser/loop_stmt_test.cc
+      lang/wgsl/reader/parser/math_expression_test.cc
+      lang/wgsl/reader/parser/multiplicative_expression_test.cc
+      lang/wgsl/reader/parser/param_list_test.cc
+      lang/wgsl/reader/parser/paren_expression_test.cc
+      lang/wgsl/reader/parser/parser_test.cc
+      lang/wgsl/reader/parser/primary_expression_test.cc
+      lang/wgsl/reader/parser/relational_expression_test.cc
+      lang/wgsl/reader/parser/require_directive_test.cc
+      lang/wgsl/reader/parser/reserved_keyword_test.cc
+      lang/wgsl/reader/parser/shift_expression_test.cc
+      lang/wgsl/reader/parser/singular_expression_test.cc
+      lang/wgsl/reader/parser/statement_test.cc
+      lang/wgsl/reader/parser/statements_test.cc
+      lang/wgsl/reader/parser/struct_attribute_decl_test.cc
+      lang/wgsl/reader/parser/struct_body_decl_test.cc
+      lang/wgsl/reader/parser/struct_decl_test.cc
+      lang/wgsl/reader/parser/struct_member_attribute_decl_test.cc
+      lang/wgsl/reader/parser/struct_member_attribute_test.cc
+      lang/wgsl/reader/parser/struct_member_test.cc
+      lang/wgsl/reader/parser/switch_body_test.cc
+      lang/wgsl/reader/parser/switch_stmt_test.cc
+      lang/wgsl/reader/parser/test_helper.cc
+      lang/wgsl/reader/parser/test_helper.h
+      lang/wgsl/reader/parser/token_test.cc
+      lang/wgsl/reader/parser/type_alias_test.cc
+      lang/wgsl/reader/parser/type_decl_test.cc
+      lang/wgsl/reader/parser/unary_expression_test.cc
+      lang/wgsl/reader/parser/variable_attribute_list_test.cc
+      lang/wgsl/reader/parser/variable_attribute_test.cc
+      lang/wgsl/reader/parser/variable_decl_test.cc
+      lang/wgsl/reader/parser/variable_ident_decl_test.cc
+      lang/wgsl/reader/parser/variable_qualifier_test.cc
+      lang/wgsl/reader/parser/variable_stmt_test.cc
+      lang/wgsl/reader/parser/while_stmt_test.cc
     )
   endif()
 
@@ -1720,7 +1719,7 @@
   list(APPEND TINT_BENCHMARK_SRCS
     "utils/rtti/switch_bench.cc"
     "bench/benchmark.cc"
-    "lang/wgsl/reader/parser_bench.cc"
+    "lang/wgsl/reader/reader_bench.cc"
   )
 
   if (${TINT_BUILD_GLSL_WRITER})
diff --git a/src/tint/bench/benchmark.cc b/src/tint/bench/benchmark.cc
index f60db6a..6daf142 100644
--- a/src/tint/bench/benchmark.cc
+++ b/src/tint/bench/benchmark.cc
@@ -122,7 +122,7 @@
         return *err;
     }
     auto file = std::make_unique<Source::File>(std::move(std::get<Source::File>(res)));
-    auto program = reader::wgsl::Parse(file.get());
+    auto program = wgsl::reader::Parse(file.get());
     if (program.Diagnostics().contains_errors()) {
         return Error{program.Diagnostics().str()};
     }
diff --git a/src/tint/cmd/helper.cc b/src/tint/cmd/helper.cc
index a3d60bc..da30d78 100644
--- a/src/tint/cmd/helper.cc
+++ b/src/tint/cmd/helper.cc
@@ -113,7 +113,7 @@
             }
             source_file = std::make_unique<tint::Source::File>(
                 opts.filename, std::string(data.begin(), data.end()));
-            program = std::make_unique<tint::Program>(tint::reader::wgsl::Parse(source_file.get()));
+            program = std::make_unique<tint::Program>(tint::wgsl::reader::Parse(source_file.get()));
             break;
 #else
             std::cerr << "Tint not built with the WGSL reader enabled" << std::endl;
diff --git a/src/tint/cmd/loopy.cc b/src/tint/cmd/loopy.cc
index dea0fdc..5617350 100644
--- a/src/tint/cmd/loopy.cc
+++ b/src/tint/cmd/loopy.cc
@@ -338,7 +338,7 @@
             uint32_t loop_count = options.loop_count;
             for (uint32_t i = 0; i < loop_count; ++i) {
                 program =
-                    std::make_unique<tint::Program>(tint::reader::wgsl::Parse(source_file.get()));
+                    std::make_unique<tint::Program>(tint::wgsl::reader::Parse(source_file.get()));
             }
 #else
             std::cerr << "Tint not built with the WGSL reader enabled" << std::endl;
diff --git a/src/tint/cmd/main.cc b/src/tint/cmd/main.cc
index 2f1198e..f56d8c6 100644
--- a/src/tint/cmd/main.cc
+++ b/src/tint/cmd/main.cc
@@ -580,7 +580,7 @@
     if (options.validate && options.skip_hash.count(hash) == 0) {
         // Attempt to re-parse the output program with Tint's WGSL reader.
         auto source = std::make_unique<tint::Source::File>(options.input_filename, result.wgsl);
-        auto reparsed_program = tint::reader::wgsl::Parse(source.get());
+        auto reparsed_program = tint::wgsl::reader::Parse(source.get());
         if (!reparsed_program.IsValid()) {
             auto diag_printer = tint::diag::Printer::create(stderr, true);
             tint::diag::Formatter diag_formatter;
diff --git a/src/tint/fuzzers/tint_ast_clone_fuzzer.cc b/src/tint/fuzzers/tint_ast_clone_fuzzer.cc
index da0c505..e498915 100644
--- a/src/tint/fuzzers/tint_ast_clone_fuzzer.cc
+++ b/src/tint/fuzzers/tint_ast_clone_fuzzer.cc
@@ -16,7 +16,7 @@
 #include <string>
 #include <unordered_set>
 
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 #define ASSERT_EQ(A, B)                                        \
@@ -54,7 +54,7 @@
     tint::Source::File file("test.wgsl", str);
 
     // Parse the wgsl, create the src program
-    tint::reader::wgsl::ParserImpl parser(&file);
+    tint::wgsl::reader::Parser parser(&file);
     parser.set_max_errors(1);
     if (!parser.Parse()) {
         return 0;
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/expression_size_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/expression_size_test.cc
index 2d0b985..76d5571 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/expression_size_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/expression_size_test.cc
@@ -22,7 +22,7 @@
 #include "src/tint/lang/wgsl/ast/expression.h"
 #include "src/tint/lang/wgsl/ast/int_literal_expression.h"
 #include "src/tint/lang/wgsl/program/program.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 
 namespace tint::fuzzers::ast_fuzzer {
 namespace {
@@ -34,7 +34,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     ExpressionSize expression_size(program);
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
index 3df373db..8f2946d 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/fuzzer.cc
@@ -21,7 +21,7 @@
 #include "src/tint/fuzzers/tint_ast_fuzzer/override_cli_params.h"
 #include "src/tint/fuzzers/tint_common_fuzzer.h"
 #include "src/tint/fuzzers/transform_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 #include "testing/libfuzzer/libfuzzer_exports.h"
 
@@ -45,7 +45,7 @@
                                           size_t max_size,
                                           unsigned seed) {
     Source::File file("test.wgsl", {reinterpret_cast<char*>(data), size});
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     if (!program.IsValid()) {
         std::cout << "Trying to mutate an invalid program:" << std::endl
                   << program.Diagnostics().str() << std::endl;
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc
index 68afb4a0..1a15298 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/jump_tracker_test.cc
@@ -29,7 +29,7 @@
 #include "src/tint/lang/wgsl/ast/switch_statement.h"
 #include "src/tint/lang/wgsl/ast/while_statement.h"
 #include "src/tint/lang/wgsl/program/program.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 
 namespace tint::fuzzers::ast_fuzzer {
 namespace {
@@ -71,7 +71,7 @@
 }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     JumpTracker jump_tracker(program);
@@ -150,7 +150,7 @@
 }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     JumpTracker jump_tracker(program);
@@ -214,7 +214,7 @@
 }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     JumpTracker jump_tracker(program);
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator_test.cc
index 6423c5a..ca88de0 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_binary_operator_test.cc
@@ -23,7 +23,7 @@
 #include "src/tint/fuzzers/tint_ast_fuzzer/mutator.h"
 #include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::fuzzers::ast_fuzzer {
@@ -80,7 +80,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -121,7 +121,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -184,7 +184,7 @@
 
     for (auto new_operator : all_operators) {
         Source::File file("test.wgsl", shader.str());
-        auto program = reader::wgsl::Parse(&file);
+        auto program = wgsl::reader::Parse(&file);
         ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
         NodeIdMap node_id_map(program);
@@ -211,7 +211,7 @@
             ASSERT_FALSE(mutation.IsApplicable(program, node_id_map));
             if (new_operator != binary_expr->op) {
                 Source::File invalid_file("test.wgsl", expected_shader.str());
-                auto invalid_program = reader::wgsl::Parse(&invalid_file);
+                auto invalid_program = wgsl::reader::Parse(&invalid_file);
                 ASSERT_FALSE(invalid_program.IsValid()) << program.Diagnostics().str();
             }
         } else {
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator_test.cc
index 7c9ebcc..6ca9bab 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/change_unary_operator_test.cc
@@ -22,7 +22,7 @@
 #include "src/tint/fuzzers/tint_ast_fuzzer/probability_context.h"
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::fuzzers::ast_fuzzer {
@@ -43,7 +43,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -135,7 +135,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -176,7 +176,7 @@
       var comp_b : vec3<i32> = ~b;
     })";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -219,7 +219,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -261,7 +261,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc
index eea64fe..7eb963a 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/delete_statement_test.cc
@@ -29,7 +29,7 @@
 #include "src/tint/lang/wgsl/ast/if_statement.h"
 #include "src/tint/lang/wgsl/ast/switch_statement.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::fuzzers::ast_fuzzer {
@@ -40,10 +40,10 @@
     const std::string& expected,
     const std::function<const ast::Statement*(const Program&)>& statement_finder) {
     Source::File original_file("original.wgsl", original);
-    auto program = reader::wgsl::Parse(&original_file);
+    auto program = wgsl::reader::Parse(&original_file);
 
     Source::File expected_file("expected.wgsl", expected);
-    auto expected_program = reader::wgsl::Parse(&expected_file);
+    auto expected_program = wgsl::reader::Parse(&expected_file);
 
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
     ASSERT_TRUE(expected_program.IsValid()) << expected_program.Diagnostics().str();
@@ -68,7 +68,7 @@
     const std::string& original,
     const std::function<const ast::Statement*(const Program&)>& statement_finder) {
     Source::File original_file("original.wgsl", original);
-    auto program = reader::wgsl::Parse(&original_file);
+    auto program = wgsl::reader::Parse(&original_file);
 
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
index 4bd1b64..fc72221 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/replace_identifier_test.cc
@@ -22,7 +22,7 @@
 #include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::fuzzers::ast_fuzzer {
@@ -40,7 +40,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -119,7 +119,7 @@
 var<private> b: i32;
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -146,7 +146,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -178,7 +178,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -214,7 +214,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -249,7 +249,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -285,7 +285,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -321,7 +321,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -358,7 +358,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -393,7 +393,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -429,7 +429,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -460,7 +460,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -509,7 +509,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -554,7 +554,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -587,7 +587,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -622,7 +622,7 @@
 }
 )";
     Source::File file("test.wgsl", shader);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
diff --git a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
index 3396900..4f47ac0 100644
--- a/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
+++ b/src/tint/fuzzers/tint_ast_fuzzer/mutations/wrap_unary_operator_test.cc
@@ -21,7 +21,7 @@
 #include "src/tint/fuzzers/tint_ast_fuzzer/node_id_map.h"
 #include "src/tint/fuzzers/tint_ast_fuzzer/probability_context.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::fuzzers::ast_fuzzer {
@@ -37,7 +37,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -75,7 +75,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -114,7 +114,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -153,7 +153,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -194,7 +194,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -234,7 +234,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -276,7 +276,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -319,7 +319,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -358,7 +358,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -387,7 +387,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -415,7 +415,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -444,7 +444,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -473,7 +473,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -500,7 +500,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
@@ -529,7 +529,7 @@
     }
   )";
     Source::File file("test.wgsl", content);
-    auto program = reader::wgsl::Parse(&file);
+    auto program = wgsl::reader::Parse(&file);
     ASSERT_TRUE(program.IsValid()) << program.Diagnostics().str();
 
     NodeIdMap node_id_map(program);
diff --git a/src/tint/fuzzers/tint_common_fuzzer.cc b/src/tint/fuzzers/tint_common_fuzzer.cc
index ad877c2..809eef2 100644
--- a/src/tint/fuzzers/tint_common_fuzzer.cc
+++ b/src/tint/fuzzers/tint_common_fuzzer.cc
@@ -166,7 +166,7 @@
             if (dump_input_) {
                 dump_input_data(str, ".wgsl");
             }
-            program = reader::wgsl::Parse(file_.get());
+            program = wgsl::reader::Parse(file_.get());
 #endif  // TINT_BUILD_WGSL_READER
             break;
         }
diff --git a/src/tint/fuzzers/tint_concurrency_fuzzer.cc b/src/tint/fuzzers/tint_concurrency_fuzzer.cc
index be0d2c3..24d8e02 100644
--- a/src/tint/fuzzers/tint_concurrency_fuzzer.cc
+++ b/src/tint/fuzzers/tint_concurrency_fuzzer.cc
@@ -26,7 +26,7 @@
 #include "src/tint/lang/spirv/writer/writer.h"
 #include "src/tint/lang/wgsl/helpers/flatten_bindings.h"
 #include "src/tint/lang/wgsl/inspector/inspector.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 #include "src/tint/utils/math/hash.h"
 
@@ -43,7 +43,7 @@
 
     std::string str(reinterpret_cast<const char*>(data), size);
     auto file = std::make_unique<tint::Source::File>("test.wgsl", str);
-    auto program = tint::reader::wgsl::Parse(file.get());
+    auto program = tint::wgsl::reader::Parse(file.get());
     if (!program.IsValid()) {
         return 0;
     }
diff --git a/src/tint/fuzzers/tint_ir_roundtrip_fuzzer.cc b/src/tint/fuzzers/tint_ir_roundtrip_fuzzer.cc
index 0621620..d4d8e68 100644
--- a/src/tint/fuzzers/tint_ir_roundtrip_fuzzer.cc
+++ b/src/tint/fuzzers/tint_ir_roundtrip_fuzzer.cc
@@ -19,7 +19,7 @@
 #include "src/tint/fuzzers/apply_substitute_overrides.h"
 #include "src/tint/lang/core/ir/from_program.h"
 #include "src/tint/lang/core/ir/to_program.h"
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 [[noreturn]] void TintInternalCompilerErrorReporter(const tint::diag::List& diagnostics) {
@@ -36,7 +36,7 @@
     tint::Source::File file("test.wgsl", str);
 
     // Parse the wgsl, create the src program
-    tint::reader::wgsl::ParserImpl parser(&file);
+    tint::wgsl::reader::Parser parser(&file);
     parser.set_max_errors(1);
     if (!parser.Parse()) {
         return 0;
diff --git a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
index d520725..85795ae 100644
--- a/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
+++ b/src/tint/fuzzers/tint_regex_fuzzer/fuzzer.cc
@@ -22,7 +22,7 @@
 #include "src/tint/fuzzers/tint_regex_fuzzer/override_cli_params.h"
 #include "src/tint/fuzzers/tint_regex_fuzzer/wgsl_mutator.h"
 #include "src/tint/fuzzers/transform_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 #include "testing/libfuzzer/libfuzzer_exports.h"
 
diff --git a/src/tint/lang/core/ir/program_test_helper.h b/src/tint/lang/core/ir/program_test_helper.h
index 5105641..b45c029 100644
--- a/src/tint/lang/core/ir/program_test_helper.h
+++ b/src/tint/lang/core/ir/program_test_helper.h
@@ -25,7 +25,7 @@
 #include "src/tint/lang/core/ir/from_program.h"
 #include "src/tint/lang/core/ir/validator.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/utils/text/string_stream.h"
 
 namespace tint::ir {
@@ -63,7 +63,7 @@
     utils::Result<Module, std::string> Build(std::string wgsl) {
 #if TINT_BUILD_WGSL_READER
         Source::File file("test.wgsl", std::move(wgsl));
-        auto program = reader::wgsl::Parse(&file);
+        auto program = wgsl::reader::Parse(&file);
         if (!program.IsValid()) {
             return program.Diagnostics().str();
         }
diff --git a/src/tint/lang/core/ir/to_program_roundtrip_test.cc b/src/tint/lang/core/ir/to_program_roundtrip_test.cc
index 6ceeaea..d5d68cb 100644
--- a/src/tint/lang/core/ir/to_program_roundtrip_test.cc
+++ b/src/tint/lang/core/ir/to_program_roundtrip_test.cc
@@ -15,7 +15,7 @@
 #include "src/tint/lang/core/ir/from_program.h"
 #include "src/tint/lang/core/ir/program_test_helper.h"
 #include "src/tint/lang/core/ir/to_program.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 #include "src/tint/utils/text/string.h"
 
@@ -33,7 +33,7 @@
     void Test(std::string_view input_wgsl, std::string_view expected_wgsl) {
         auto input = utils::TrimSpace(input_wgsl);
         Source::File file("test.wgsl", std::string(input));
-        auto input_program = reader::wgsl::Parse(&file);
+        auto input_program = wgsl::reader::Parse(&file);
         ASSERT_TRUE(input_program.IsValid()) << input_program.Diagnostics().str();
 
         auto ir_module = FromProgram(&input_program);
diff --git a/src/tint/lang/wgsl/ast/module_clone_test.cc b/src/tint/lang/wgsl/ast/module_clone_test.cc
index 874df6d..701c353 100644
--- a/src/tint/lang/wgsl/ast/module_clone_test.cc
+++ b/src/tint/lang/wgsl/ast/module_clone_test.cc
@@ -15,7 +15,7 @@
 #include <unordered_set>
 
 #include "gtest/gtest.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::ast {
@@ -122,7 +122,7 @@
 )");
 
     // Parse the wgsl, create the src program
-    auto src = reader::wgsl::Parse(&file);
+    auto src = wgsl::reader::Parse(&file);
 
     ASSERT_TRUE(src.IsValid()) << diag::Formatter().format(src.Diagnostics());
 
diff --git a/src/tint/lang/wgsl/ast/transform/spirv_atomic_test.cc b/src/tint/lang/wgsl/ast/transform/spirv_atomic_test.cc
index f03912e..b745cd9 100644
--- a/src/tint/lang/wgsl/ast/transform/spirv_atomic_test.cc
+++ b/src/tint/lang/wgsl/ast/transform/spirv_atomic_test.cc
@@ -20,7 +20,7 @@
 #include <vector>
 
 #include "src/tint/lang/wgsl/ast/transform/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 
 using namespace tint::number_suffixes;  // NOLINT
 
@@ -31,7 +31,7 @@
   public:
     Output Run(std::string in) {
         auto file = std::make_unique<Source::File>("test", std::move(in));
-        auto parser = reader::wgsl::ParserImpl(file.get());
+        auto parser = wgsl::reader::Parser(file.get());
         parser.Parse();
 
         auto& b = parser.builder();
diff --git a/src/tint/lang/wgsl/ast/transform/test_helper.h b/src/tint/lang/wgsl/ast/transform/test_helper.h
index 3d77fee..ed5a220 100644
--- a/src/tint/lang/wgsl/ast/transform/test_helper.h
+++ b/src/tint/lang/wgsl/ast/transform/test_helper.h
@@ -23,7 +23,7 @@
 #include "gtest/gtest.h"
 #include "src/tint/lang/wgsl/ast/transform/manager.h"
 #include "src/tint/lang/wgsl/ast/transform/transform.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/writer/writer.h"
 
 namespace tint::ast::transform {
@@ -85,7 +85,7 @@
     template <typename... TRANSFORMS>
     Output Run(std::string in, const DataMap& data = {}) {
         auto file = std::make_unique<Source::File>("test", in);
-        auto program = reader::wgsl::Parse(file.get());
+        auto program = wgsl::reader::Parse(file.get());
 
         // Keep this pointer alive after Transform() returns
         files_.emplace_back(std::move(file));
@@ -145,7 +145,7 @@
     template <typename TRANSFORM>
     bool ShouldRun(std::string in, const DataMap& data = {}) {
         auto file = std::make_unique<Source::File>("test", in);
-        auto program = reader::wgsl::Parse(file.get());
+        auto program = wgsl::reader::Parse(file.get());
         return ShouldRun<TRANSFORM>(std::move(program), data);
     }
 
diff --git a/src/tint/lang/wgsl/inspector/test_inspector_runner.cc b/src/tint/lang/wgsl/inspector/test_inspector_runner.cc
index 38306e3..e8e56eb 100644
--- a/src/tint/lang/wgsl/inspector/test_inspector_runner.cc
+++ b/src/tint/lang/wgsl/inspector/test_inspector_runner.cc
@@ -25,7 +25,7 @@
     }
 
     file_ = std::make_unique<Source::File>("test", shader);
-    program_ = std::make_unique<Program>(reader::wgsl::Parse(file_.get()));
+    program_ = std::make_unique<Program>(wgsl::reader::Parse(file_.get()));
     [&] {
         ASSERT_TRUE(program_->IsValid()) << diag::Formatter().format(program_->Diagnostics());
     }();
diff --git a/src/tint/lang/wgsl/reader/parser_impl_additive_expression_test.cc b/src/tint/lang/wgsl/reader/parser/additive_expression_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_additive_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/additive_expression_test.cc
index 4d070b8..5eb6c67 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_additive_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/additive_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AdditiveExpression_Parses_Plus) {
+TEST_F(WGSLParserTest, AdditiveExpression_Parses_Plus) {
     auto p = parser("a + b");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -43,7 +43,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_Parses_Minus) {
+TEST_F(WGSLParserTest, AdditiveExpression_Parses_Minus) {
     auto p = parser("a - b");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -64,7 +64,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_Parses_MinusMinus) {
+TEST_F(WGSLParserTest, AdditiveExpression_Parses_MinusMinus) {
     auto p = parser("a--b");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -89,7 +89,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_Parses_MultipleOps) {
+TEST_F(WGSLParserTest, AdditiveExpression_Parses_MultipleOps) {
     auto p = parser("a - b + c - d");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -135,7 +135,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_Parses_MultipleOps_MixedMultiplication) {
+TEST_F(WGSLParserTest, AdditiveExpression_Parses_MultipleOps_MixedMultiplication) {
     auto p = parser("a - b * c - d");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -181,7 +181,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("c"));
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_InvalidRHS) {
+TEST_F(WGSLParserTest, AdditiveExpression_InvalidRHS) {
     auto p = parser("a + if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -191,7 +191,7 @@
     EXPECT_EQ(p->error(), "1:5: unable to parse right side of + expression");
 }
 
-TEST_F(ParserImplTest, AdditiveExpression_NoMatch_ReturnsLHS) {
+TEST_F(WGSLParserTest, AdditiveExpression_NoMatch_ReturnsLHS) {
     auto p = parser("a true");
     auto lhs = p->unary_expression();
     auto e = p->expect_additive_expression_post_unary_expression(lhs.value);
@@ -202,4 +202,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_argument_expression_list_test.cc b/src/tint/lang/wgsl/reader/parser/argument_expression_list_test.cc
similarity index 81%
rename from src/tint/lang/wgsl/reader/parser_impl_argument_expression_list_test.cc
rename to src/tint/lang/wgsl/reader/parser/argument_expression_list_test.cc
index f5c50f2..b7342c8 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_argument_expression_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/argument_expression_list_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ArgumentExpressionList_Parses) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_Parses) {
     auto p = parser("(a)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -27,7 +27,7 @@
     ASSERT_TRUE(e.value[0]->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_ParsesEmptyList) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_ParsesEmptyList) {
     auto p = parser("()");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -36,7 +36,7 @@
     ASSERT_EQ(e.value.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_ParsesMultiple) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_ParsesMultiple) {
     auto p = parser("(a, 33, 1+2)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -48,7 +48,7 @@
     ASSERT_TRUE(e.value[2]->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_TrailingComma) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_TrailingComma) {
     auto p = parser("(a, 42,)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -59,7 +59,7 @@
     ASSERT_TRUE(e.value[1]->Is<ast::LiteralExpression>());
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingLeftParen) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_HandlesMissingLeftParen) {
     auto p = parser("a)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_TRUE(p->has_error());
@@ -67,7 +67,7 @@
     EXPECT_EQ(p->error(), "1:1: expected '(' for argument list");
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingRightParen) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_HandlesMissingRightParen) {
     auto p = parser("(a");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_TRUE(p->has_error());
@@ -75,7 +75,7 @@
     EXPECT_EQ(p->error(), "1:3: expected ',' for argument list");
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingExpression_0) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_HandlesMissingExpression_0) {
     auto p = parser("(,)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_TRUE(p->has_error());
@@ -83,7 +83,7 @@
     EXPECT_EQ(p->error(), "1:2: expected expression for argument list");
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_HandlesMissingExpression_1) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_HandlesMissingExpression_1) {
     auto p = parser("(a, ,)");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_TRUE(p->has_error());
@@ -91,7 +91,7 @@
     EXPECT_EQ(p->error(), "1:5: expected expression for argument list");
 }
 
-TEST_F(ParserImplTest, ArgumentExpressionList_HandlesInvalidExpression) {
+TEST_F(WGSLParserTest, ArgumentExpressionList_HandlesInvalidExpression) {
     auto p = parser("(if(a) {})");
     auto e = p->expect_argument_expression_list("argument list");
     ASSERT_TRUE(p->has_error());
@@ -100,4 +100,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_assignment_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/assignment_stmt_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_assignment_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/assignment_stmt_test.cc
index 9ce44fc..b8cdd55 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_assignment_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/assignment_stmt_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AssignmentStmt_Parses_ToVariable) {
+TEST_F(WGSLParserTest, AssignmentStmt_Parses_ToVariable) {
     auto p = parser("a = 123");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -45,7 +45,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Parses_ToMember) {
+TEST_F(WGSLParserTest, AssignmentStmt_Parses_ToMember) {
     auto p = parser("a.b.c[2].d = 123");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -93,7 +93,7 @@
     EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Parses_ToPhony) {
+TEST_F(WGSLParserTest, AssignmentStmt_Parses_ToPhony) {
     auto p = parser("_ = 123i");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -119,7 +119,7 @@
     ASSERT_TRUE(a->lhs->Is<ast::PhonyExpression>());
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Phony_CompoundOpFails) {
+TEST_F(WGSLParserTest, AssignmentStmt_Phony_CompoundOpFails) {
     auto p = parser("_ += 123i");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -129,7 +129,7 @@
     EXPECT_EQ(p->error(), "1:3: expected '=' for assignment");
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Phony_IncrementFails) {
+TEST_F(WGSLParserTest, AssignmentStmt_Phony_IncrementFails) {
     auto p = parser("_ ++");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -139,7 +139,7 @@
     EXPECT_EQ(p->error(), "1:3: expected '=' for assignment");
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Phony_EqualIncrementFails) {
+TEST_F(WGSLParserTest, AssignmentStmt_Phony_EqualIncrementFails) {
     auto p = parser("_ = ++");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -155,7 +155,7 @@
     std::string str;
     ast::BinaryOp op;
 };
-using CompoundOpTest = ParserImplTestWithParam<CompoundData>;
+using CompoundOpTest = WGSLParserTestWithParam<CompoundData>;
 TEST_P(CompoundOpTest, CompoundOp) {
     auto params = GetParam();
     auto p = parser("a " + params.str + " 123u");
@@ -185,7 +185,7 @@
     EXPECT_EQ(a->rhs->As<ast::IntLiteralExpression>()->suffix,
               ast::IntLiteralExpression::Suffix::kU);
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          CompoundOpTest,
                          testing::Values(CompoundData{"+=", ast::BinaryOp::kAdd},
                                          CompoundData{"-=", ast::BinaryOp::kSubtract},
@@ -198,7 +198,7 @@
                                          CompoundData{">>=", ast::BinaryOp::kShiftRight},
                                          CompoundData{"<<=", ast::BinaryOp::kShiftLeft}));
 
-TEST_F(ParserImplTest, AssignmentStmt_MissingEqual) {
+TEST_F(WGSLParserTest, AssignmentStmt_MissingEqual) {
     auto p = parser("a.b.c[2].d 123");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -208,7 +208,7 @@
     EXPECT_EQ(p->error(), "1:12: expected '=' for assignment");
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_Compound_MissingEqual) {
+TEST_F(WGSLParserTest, AssignmentStmt_Compound_MissingEqual) {
     auto p = parser("a + 123");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -218,7 +218,7 @@
     EXPECT_EQ(p->error(), "1:3: expected '=' for assignment");
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_InvalidLHS) {
+TEST_F(WGSLParserTest, AssignmentStmt_InvalidLHS) {
     auto p = parser("if (true) {} = 123");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -227,7 +227,7 @@
     EXPECT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_InvalidRHS) {
+TEST_F(WGSLParserTest, AssignmentStmt_InvalidRHS) {
     auto p = parser("a.b.c[2].d = if (true) {}");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -237,7 +237,7 @@
     EXPECT_EQ(p->error(), "1:14: unable to parse right side of assignment");
 }
 
-TEST_F(ParserImplTest, AssignmentStmt_InvalidCompoundOp) {
+TEST_F(WGSLParserTest, AssignmentStmt_InvalidCompoundOp) {
     auto p = parser("a &&= true");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -248,4 +248,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_bitwise_expression_test.cc b/src/tint/lang/wgsl/reader/parser/bitwise_expression_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_bitwise_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/bitwise_expression_test.cc
index a62706c..530c848 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_bitwise_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/bitwise_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, BitwiseExpr_NoOp) {
+TEST_F(WGSLParserTest, BitwiseExpr_NoOp) {
     auto p = parser("a true");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -27,7 +27,7 @@
     ASSERT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Or_Parses) {
+TEST_F(WGSLParserTest, BitwiseExpr_Or_Parses) {
     auto p = parser("a | true");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -53,7 +53,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Or_Parses_Multiple) {
+TEST_F(WGSLParserTest, BitwiseExpr_Or_Parses_Multiple) {
     auto p = parser("a | true | b");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -87,7 +87,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Or_InvalidRHS) {
+TEST_F(WGSLParserTest, BitwiseExpr_Or_InvalidRHS) {
     auto p = parser("true | if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -98,7 +98,7 @@
     EXPECT_EQ(p->error(), "1:8: unable to parse right side of | expression");
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Xor_Parses) {
+TEST_F(WGSLParserTest, BitwiseExpr_Xor_Parses) {
     auto p = parser("a ^ true");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -124,7 +124,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Xor_Parses_Multiple) {
+TEST_F(WGSLParserTest, BitwiseExpr_Xor_Parses_Multiple) {
     auto p = parser("a ^ true ^ b");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -157,7 +157,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_Xor_InvalidRHS) {
+TEST_F(WGSLParserTest, BitwiseExpr_Xor_InvalidRHS) {
     auto p = parser("true ^ if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -168,7 +168,7 @@
     EXPECT_EQ(p->error(), "1:8: unable to parse right side of ^ expression");
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_And_Parses) {
+TEST_F(WGSLParserTest, BitwiseExpr_And_Parses) {
     auto p = parser("a & true");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -194,7 +194,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_And_Parses_Multiple) {
+TEST_F(WGSLParserTest, BitwiseExpr_And_Parses_Multiple) {
     auto p = parser("a & true & b");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -227,7 +227,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_And_Parses_AndAnd) {
+TEST_F(WGSLParserTest, BitwiseExpr_And_Parses_AndAnd) {
     auto p = parser("a & true &&b");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -248,7 +248,7 @@
     ASSERT_TRUE(rel->rhs->Is<ast::BoolLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, BitwiseExpr_And_InvalidRHS) {
+TEST_F(WGSLParserTest, BitwiseExpr_And_InvalidRHS) {
     auto p = parser("true & if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->bitwise_expression_post_unary_expression(lhs.value);
@@ -260,4 +260,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_break_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/break_stmt_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_break_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/break_stmt_test.cc
index ff3c4bd..24a0815 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_break_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/break_stmt_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/break_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, BreakStmt) {
+TEST_F(WGSLParserTest, BreakStmt) {
     auto p = parser("break");
     auto e = p->break_statement();
     EXPECT_FALSE(e.errored);
@@ -28,4 +28,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_bug_cases_test.cc b/src/tint/lang/wgsl/reader/parser/bug_cases_test.cc
similarity index 93%
rename from src/tint/lang/wgsl/reader/parser_impl_bug_cases_test.cc
rename to src/tint/lang/wgsl/reader/parser/bug_cases_test.cc
index 04ff7f4..0e883dc 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_bug_cases_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/bug_cases_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Bug_chromium_1180130) {
+TEST_F(WGSLParserTest, Bug_chromium_1180130) {
     auto p = parser(
         R"(a;{}}a;}};{{{;{}};{};{}}a;{}};{{{}};{{{;{}};{};{}}a;{}};{{{}}{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{{{;u[([[,a;{}}a;{}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{z{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}}{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}}i;{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};{}{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{{;u[({}};{{{}};{{}a;{}};{{{}};{{{;{}};{};}a;{}};{{{}};{{;u[[a,([}};{{{;{}})");
     EXPECT_FALSE(p->Parse());
@@ -25,4 +25,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_call_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/call_stmt_test.cc
similarity index 86%
rename from src/tint/lang/wgsl/reader/parser_impl_call_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/call_stmt_test.cc
index e3058d6..df7c632 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_call_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/call_stmt_test.cc
@@ -14,12 +14,12 @@
 
 #include "src/tint/lang/wgsl/ast/call_statement.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Statement_Call) {
+TEST_F(WGSLParserTest, Statement_Call) {
     auto p = parser("a();");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -40,7 +40,7 @@
     EXPECT_EQ(c->args.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, Statement_Call_WithParams) {
+TEST_F(WGSLParserTest, Statement_Call_WithParams) {
     auto p = parser("a(1, b, 2 + 3 / b);");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -59,7 +59,7 @@
     EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, Statement_Call_WithParams_TrailingComma) {
+TEST_F(WGSLParserTest, Statement_Call_WithParams_TrailingComma) {
     auto p = parser("a(1, b,);");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -77,7 +77,7 @@
     EXPECT_TRUE(c->args[1]->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, Statement_Call_Missing_RightParen) {
+TEST_F(WGSLParserTest, Statement_Call_Missing_RightParen) {
     auto p = parser("a(");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -86,7 +86,7 @@
     EXPECT_EQ(p->error(), "1:3: expected expression for function call");
 }
 
-TEST_F(ParserImplTest, Statement_Call_Missing_Semi) {
+TEST_F(WGSLParserTest, Statement_Call_Missing_Semi) {
     auto p = parser("a()");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -95,7 +95,7 @@
     EXPECT_EQ(p->error(), "1:4: expected ';' for function call");
 }
 
-TEST_F(ParserImplTest, Statement_Call_Bad_ArgList) {
+TEST_F(WGSLParserTest, Statement_Call_Bad_ArgList) {
     auto p = parser("a(b c);");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -105,4 +105,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/classify_template_args.cc b/src/tint/lang/wgsl/reader/parser/classify_template_args.cc
similarity index 97%
rename from src/tint/lang/wgsl/reader/classify_template_args.cc
rename to src/tint/lang/wgsl/reader/parser/classify_template_args.cc
index 780552b..f913893 100644
--- a/src/tint/lang/wgsl/reader/classify_template_args.cc
+++ b/src/tint/lang/wgsl/reader/parser/classify_template_args.cc
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/classify_template_args.h"
+#include "src/tint/lang/wgsl/reader/parser/classify_template_args.h"
 
 #include <vector>
 
 #include "src/tint/utils/containers/vector.h"
 #include "src/tint/utils/debug/debug.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 namespace {
 
@@ -139,4 +139,4 @@
     }
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/classify_template_args.h b/src/tint/lang/wgsl/reader/parser/classify_template_args.h
similarity index 67%
rename from src/tint/lang/wgsl/reader/classify_template_args.h
rename to src/tint/lang/wgsl/reader/parser/classify_template_args.h
index 166c724..2b90af2 100644
--- a/src/tint/lang/wgsl/reader/classify_template_args.h
+++ b/src/tint/lang/wgsl/reader/parser/classify_template_args.h
@@ -12,17 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_CLASSIFY_TEMPLATE_ARGS_H_
-#define SRC_TINT_LANG_WGSL_READER_CLASSIFY_TEMPLATE_ARGS_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_CLASSIFY_TEMPLATE_ARGS_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_CLASSIFY_TEMPLATE_ARGS_H_
 
 #include <vector>
 
-#include "src/tint/lang/wgsl/reader/token.h"
+#include "src/tint/lang/wgsl/reader/parser/token.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 void ClassifyTemplateArguments(std::vector<Token>& tokens);
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_CLASSIFY_TEMPLATE_ARGS_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_CLASSIFY_TEMPLATE_ARGS_H_
diff --git a/src/tint/lang/wgsl/reader/classify_template_args_test.cc b/src/tint/lang/wgsl/reader/parser/classify_template_args_test.cc
similarity index 98%
rename from src/tint/lang/wgsl/reader/classify_template_args_test.cc
rename to src/tint/lang/wgsl/reader/parser/classify_template_args_test.cc
index ed7a888..741dd0d 100644
--- a/src/tint/lang/wgsl/reader/classify_template_args_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/classify_template_args_test.cc
@@ -14,11 +14,11 @@
 
 #include "gmock/gmock.h"
 
-#include "src/tint/lang/wgsl/reader/classify_template_args.h"
-#include "src/tint/lang/wgsl/reader/lexer.h"
+#include "src/tint/lang/wgsl/reader/parser/classify_template_args.h"
+#include "src/tint/lang/wgsl/reader/parser/lexer.h"
 #include "src/tint/utils/containers/transform.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 using T = Token::Type;
@@ -32,9 +32,9 @@
     return out << "'" << c.wgsl << "'";
 }
 
-using ClassifyTemplateArgsTest = testing::TestWithParam<Case>;
+using WGSLParserClassifyTemplateArgsTest = testing::TestWithParam<Case>;
 
-TEST_P(ClassifyTemplateArgsTest, Classify) {
+TEST_P(WGSLParserClassifyTemplateArgsTest, Classify) {
     auto& params = GetParam();
     Source::File file("", params.wgsl);
     Lexer l(&file);
@@ -45,7 +45,7 @@
 }
 
 INSTANTIATE_TEST_SUITE_P(NonTemplate,
-                         ClassifyTemplateArgsTest,
+                         WGSLParserClassifyTemplateArgsTest,
                          testing::ValuesIn(std::vector<Case>{
                              {
                                  "",
@@ -204,7 +204,7 @@
                          }));
 
 INSTANTIATE_TEST_SUITE_P(Template,
-                         ClassifyTemplateArgsTest,
+                         WGSLParserClassifyTemplateArgsTest,
                          testing::ValuesIn(std::vector<Case>{
                              {
                                  "a<b>()",
@@ -480,7 +480,7 @@
                          }));
 
 INSTANTIATE_TEST_SUITE_P(TreesitterScannerSeparatingCases,
-                         ClassifyTemplateArgsTest,
+                         WGSLParserClassifyTemplateArgsTest,
                          testing::ValuesIn(std::vector<Case>{
                              // Treesitter had trouble missing '=' in its lookahead
                              {
@@ -673,4 +673,4 @@
                          }));
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_compound_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/compound_stmt_test.cc
similarity index 85%
rename from src/tint/lang/wgsl/reader/parser_impl_compound_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/compound_stmt_test.cc
index 6d984c11..474052c 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_compound_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/compound_stmt_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, CompoundStmt) {
+TEST_F(WGSLParserTest, CompoundStmt) {
     auto p = parser(R"({
   discard;
   return 1 + b / 2;
@@ -37,7 +37,7 @@
     EXPECT_TRUE(e->statements[1]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, CompoundStmt_Empty) {
+TEST_F(WGSLParserTest, CompoundStmt_Empty) {
     auto p = parser("{}");
     auto e = p->expect_compound_statement("");
 
@@ -51,7 +51,7 @@
     EXPECT_EQ(e->statements.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, CompoundStmt_InvalidStmt) {
+TEST_F(WGSLParserTest, CompoundStmt_InvalidStmt) {
     auto p = parser("{fn main() {}}");
     auto e = p->expect_compound_statement("");
     ASSERT_TRUE(p->has_error());
@@ -59,7 +59,7 @@
     EXPECT_EQ(p->error(), "1:2: expected '}'");
 }
 
-TEST_F(ParserImplTest, CompoundStmt_MissingRightParen) {
+TEST_F(WGSLParserTest, CompoundStmt_MissingRightParen) {
     auto p = parser("{return;");
     auto e = p->expect_compound_statement("");
     ASSERT_TRUE(p->has_error());
@@ -68,4 +68,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_const_literal_test.cc b/src/tint/lang/wgsl/reader/parser/const_literal_test.cc
similarity index 97%
rename from src/tint/lang/wgsl/reader/parser_impl_const_literal_test.cc
rename to src/tint/lang/wgsl/reader/parser/const_literal_test.cc
index 3c20f0c..33fe5fe 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_const_literal_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/const_literal_test.cc
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
-
 #include <cstring>
 
 #include "gmock/gmock.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 // Makes an IEEE 754 binary64 floating point number with
@@ -40,7 +39,7 @@
     return result;
 }
 
-TEST_F(ParserImplTest, ConstLiteral_Int) {
+TEST_F(WGSLParserTest, ConstLiteral_Int) {
     {
         auto p = parser("234");
         auto c = p->const_literal();
@@ -69,7 +68,7 @@
     }
 }
 
-TEST_F(ParserImplTest, ConstLiteral_Uint) {
+TEST_F(WGSLParserTest, ConstLiteral_Uint) {
     auto p = parser("234u");
     auto c = p->const_literal();
     EXPECT_TRUE(c.matched);
@@ -82,7 +81,7 @@
     EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
-TEST_F(ParserImplTest, ConstLiteral_InvalidFloat_IncompleteExponent) {
+TEST_F(WGSLParserTest, ConstLiteral_InvalidFloat_IncompleteExponent) {
     auto p = parser("1.0e+");
     auto c = p->const_literal();
     EXPECT_FALSE(c.matched);
@@ -104,7 +103,7 @@
     return out;
 }
 
-class ParserImplFloatLiteralTest : public ParserImplTestWithParam<FloatLiteralTestCase> {};
+class ParserImplFloatLiteralTest : public WGSLParserTestWithParam<FloatLiteralTestCase> {};
 TEST_P(ParserImplFloatLiteralTest, Parse) {
     auto params = GetParam();
     SCOPED_TRACE(params.input);
@@ -403,7 +402,7 @@
 // <error, source>
 using InvalidLiteralTestCase = std::tuple<const char*, const char*>;
 
-class ParserImplInvalidLiteralTest : public ParserImplTestWithParam<InvalidLiteralTestCase> {};
+class ParserImplInvalidLiteralTest : public WGSLParserTestWithParam<InvalidLiteralTestCase> {};
 TEST_P(ParserImplInvalidLiteralTest, Parse) {
     auto* error = std::get<0>(GetParam());
     auto* source = std::get<1>(GetParam());
@@ -629,7 +628,7 @@
                          "1.2e+32h",
                      })));
 
-TEST_F(ParserImplTest, ConstLiteral_FloatHighest) {
+TEST_F(WGSLParserTest, ConstLiteral_FloatHighest) {
     const auto highest = std::numeric_limits<float>::max();
     const auto expected_highest = 340282346638528859811704183484516925440.0f;
     if (highest < expected_highest || highest > expected_highest) {
@@ -649,7 +648,7 @@
     EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 42u}}));
 }
 
-TEST_F(ParserImplTest, ConstLiteral_True) {
+TEST_F(WGSLParserTest, ConstLiteral_True) {
     auto p = parser("true");
     auto c = p->const_literal();
     EXPECT_TRUE(c.matched);
@@ -661,7 +660,7 @@
     EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
-TEST_F(ParserImplTest, ConstLiteral_False) {
+TEST_F(WGSLParserTest, ConstLiteral_False) {
     auto p = parser("false");
     auto c = p->const_literal();
     EXPECT_TRUE(c.matched);
@@ -673,7 +672,7 @@
     EXPECT_EQ(c->source.range, (Source::Range{{1u, 1u}, {1u, 6u}}));
 }
 
-TEST_F(ParserImplTest, ConstLiteral_NoMatch) {
+TEST_F(WGSLParserTest, ConstLiteral_NoMatch) {
     auto p = parser("another-token");
     auto c = p->const_literal();
     EXPECT_FALSE(c.matched);
@@ -683,4 +682,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_continue_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/continue_stmt_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_continue_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/continue_stmt_test.cc
index ea03a99..4097807 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_continue_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/continue_stmt_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/continue_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ContinueStmt) {
+TEST_F(WGSLParserTest, ContinueStmt) {
     auto p = parser("continue");
     auto e = p->continue_statement();
     EXPECT_FALSE(e.errored);
@@ -28,4 +28,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_continuing_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/continuing_stmt_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_continuing_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/continuing_stmt_test.cc
index de24790..bc244c2 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_continuing_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/continuing_stmt_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ContinuingStmt) {
+TEST_F(WGSLParserTest, ContinuingStmt) {
     auto p = parser("continuing { discard; }");
     auto e = p->continuing_statement();
     EXPECT_TRUE(e.matched);
@@ -28,7 +28,7 @@
     ASSERT_TRUE(e->statements[0]->Is<ast::DiscardStatement>());
 }
 
-TEST_F(ParserImplTest, ContinuingStmt_WithAttributes) {
+TEST_F(WGSLParserTest, ContinuingStmt_WithAttributes) {
     auto p = parser("continuing @diagnostic(off, derivative_uniformity) { discard; }");
     auto e = p->continuing_statement();
     EXPECT_TRUE(e.matched);
@@ -38,7 +38,7 @@
     EXPECT_TRUE(e->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, ContinuingStmt_InvalidBody) {
+TEST_F(WGSLParserTest, ContinuingStmt_InvalidBody) {
     auto p = parser("continuing { discard }");
     auto e = p->continuing_statement();
     EXPECT_FALSE(e.matched);
@@ -49,4 +49,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_core_lhs_expression_test.cc b/src/tint/lang/wgsl/reader/parser/core_lhs_expression_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_core_lhs_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/core_lhs_expression_test.cc
index f2ae8bf..10825d1 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_core_lhs_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/core_lhs_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, CoreLHS_NoMatch) {
+TEST_F(WGSLParserTest, CoreLHS_NoMatch) {
     auto p = parser("123");
     auto e = p->core_lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -25,7 +25,7 @@
     EXPECT_FALSE(e.matched);
 }
 
-TEST_F(ParserImplTest, CoreLHS_Ident) {
+TEST_F(WGSLParserTest, CoreLHS_Ident) {
     auto p = parser("identifier");
     auto e = p->core_lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -38,7 +38,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("identifier"));
 }
 
-TEST_F(ParserImplTest, CoreLHS_ParenStmt) {
+TEST_F(WGSLParserTest, CoreLHS_ParenStmt) {
     auto p = parser("(a)");
     auto e = p->core_lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -51,7 +51,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("a"));
 }
 
-TEST_F(ParserImplTest, CoreLHS_MissingRightParen) {
+TEST_F(WGSLParserTest, CoreLHS_MissingRightParen) {
     auto p = parser("(a");
     auto e = p->core_lhs_expression();
     ASSERT_TRUE(p->has_error());
@@ -61,7 +61,7 @@
     EXPECT_EQ(p->error(), "1:3: expected ')'");
 }
 
-TEST_F(ParserImplTest, CoreLHS_InvalidLHSExpression) {
+TEST_F(WGSLParserTest, CoreLHS_InvalidLHSExpression) {
     auto p = parser("(if (a() {})");
     auto e = p->core_lhs_expression();
     ASSERT_TRUE(p->has_error());
@@ -71,7 +71,7 @@
     EXPECT_EQ(p->error(), "1:1: invalid expression");
 }
 
-TEST_F(ParserImplTest, CoreLHS_MissingLHSExpression) {
+TEST_F(WGSLParserTest, CoreLHS_MissingLHSExpression) {
     auto p = parser("()");
     auto e = p->core_lhs_expression();
     ASSERT_TRUE(p->has_error());
@@ -81,7 +81,7 @@
     EXPECT_EQ(p->error(), "1:1: invalid expression");
 }
 
-TEST_F(ParserImplTest, CoreLHS_Invalid) {
+TEST_F(WGSLParserTest, CoreLHS_Invalid) {
     auto p = parser("1234");
     auto e = p->core_lhs_expression();
     ASSERT_FALSE(p->has_error());
@@ -90,4 +90,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_detail.h b/src/tint/lang/wgsl/reader/parser/detail.h
similarity index 89%
rename from src/tint/lang/wgsl/reader/parser_impl_detail.h
rename to src/tint/lang/wgsl/reader/parser/detail.h
index 7977cb6..ea490bb 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_detail.h
+++ b/src/tint/lang/wgsl/reader/parser/detail.h
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_DETAIL_H_
-#define SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_DETAIL_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_DETAIL_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_DETAIL_H_
 
 #include <memory>
 
-namespace tint::reader::wgsl::detail {
+namespace tint::wgsl::reader::detail {
 
 /// OperatorArrow is a traits helper for ParserImpl::Expect<T>::operator->() and
 /// ParserImpl::Maybe<T>::operator->() so that pointer types are automatically
@@ -59,6 +59,6 @@
     static inline T* ptr(T* val) { return val; }
 };
 
-}  // namespace tint::reader::wgsl::detail
+}  // namespace tint::wgsl::reader::detail
 
-#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_DETAIL_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_DETAIL_H_
diff --git a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_attribute_test.cc b/src/tint/lang/wgsl/reader/parser/diagnostic_attribute_test.cc
similarity index 86%
rename from src/tint/lang/wgsl/reader/parser_impl_diagnostic_attribute_test.cc
rename to src/tint/lang/wgsl/reader/parser/diagnostic_attribute_test.cc
index 1af4402..63f1628 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_attribute_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/diagnostic_attribute_test.cc
@@ -12,15 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/diagnostic_control.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, DiagnosticAttribute_Name) {
+TEST_F(WGSLParserTest, DiagnosticAttribute_Name) {
     auto p = parser("diagnostic(off, foo)");
     auto a = p->attribute();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -34,7 +34,7 @@
     ast::CheckIdentifier(r->name, "foo");
 }
 
-TEST_F(ParserImplTest, DiagnosticAttribute_CategoryName) {
+TEST_F(WGSLParserTest, DiagnosticAttribute_CategoryName) {
     auto p = parser("diagnostic(off, foo.bar)");
     auto a = p->attribute();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -49,4 +49,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_control_test.cc b/src/tint/lang/wgsl/reader/parser/diagnostic_control_test.cc
similarity index 85%
rename from src/tint/lang/wgsl/reader/parser_impl_diagnostic_control_test.cc
rename to src/tint/lang/wgsl/reader/parser/diagnostic_control_test.cc
index 09ec3cb..bfe39aa 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_control_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/diagnostic_control_test.cc
@@ -12,16 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/diagnostic_control.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 using SeverityPair = std::pair<std::string, builtin::DiagnosticSeverity>;
-class DiagnosticControlParserTest : public ParserImplTestWithParam<SeverityPair> {};
+class DiagnosticControlParserTest : public WGSLParserTestWithParam<SeverityPair> {};
 
 TEST_P(DiagnosticControlParserTest, DiagnosticControl_Name) {
     auto& params = GetParam();
@@ -57,7 +57,7 @@
                                          SeverityPair{"info", builtin::DiagnosticSeverity::kInfo},
                                          SeverityPair{"off", builtin::DiagnosticSeverity::kOff}));
 
-TEST_F(ParserImplTest, DiagnosticControl_Name_TrailingComma) {
+TEST_F(WGSLParserTest, DiagnosticControl_Name_TrailingComma) {
     auto p = parser("(error, foo,)");
     auto e = p->expect_diagnostic_control();
     EXPECT_FALSE(e.errored);
@@ -70,7 +70,7 @@
     ast::CheckIdentifier(r->name, "foo");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_CategoryAndName_TrailingComma) {
+TEST_F(WGSLParserTest, DiagnosticControl_CategoryAndName_TrailingComma) {
     auto p = parser("(error, foo.bar,)");
     auto e = p->expect_diagnostic_control();
     EXPECT_FALSE(e.errored);
@@ -83,7 +83,7 @@
     ast::CheckIdentifier(r->name, "bar");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingOpenParen) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingOpenParen) {
     auto p = parser("off, foo)");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -91,7 +91,7 @@
     EXPECT_EQ(p->error(), R"(1:1: expected '(' for diagnostic control)");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingCloseParen) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingCloseParen) {
     auto p = parser("(off, foo");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -99,7 +99,7 @@
     EXPECT_EQ(p->error(), R"(1:10: expected ')' for diagnostic control)");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingDiagnosticSeverity) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingDiagnosticSeverity) {
     auto p = parser("(, foo");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -108,7 +108,7 @@
 Possible values: 'error', 'info', 'off', 'warning')");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_InvalidDiagnosticSeverity) {
+TEST_F(WGSLParserTest, DiagnosticControl_InvalidDiagnosticSeverity) {
     auto p = parser("(fatal, foo)");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -117,7 +117,7 @@
 Possible values: 'error', 'info', 'off', 'warning')");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingComma) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingComma) {
     auto p = parser("(off foo");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -125,7 +125,7 @@
     EXPECT_EQ(p->error(), R"(1:6: expected ',' for diagnostic control)");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingRuleName) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingRuleName) {
     auto p = parser("(off,)");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -133,7 +133,7 @@
     EXPECT_EQ(p->error(), R"(1:6: expected diagnostic rule name)");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_MissingRuleCategory) {
+TEST_F(WGSLParserTest, DiagnosticControl_MissingRuleCategory) {
     auto p = parser("(off,for.foo)");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -141,7 +141,7 @@
     EXPECT_EQ(p->error(), R"(1:6: expected diagnostic rule category)");
 }
 
-TEST_F(ParserImplTest, DiagnosticControl_InvalidRuleName) {
+TEST_F(WGSLParserTest, DiagnosticControl_InvalidRuleName) {
     auto p = parser("(off, foo$bar)");
     auto e = p->expect_diagnostic_control();
     EXPECT_TRUE(e.errored);
@@ -150,4 +150,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_directive_test.cc b/src/tint/lang/wgsl/reader/parser/diagnostic_directive_test.cc
similarity index 86%
rename from src/tint/lang/wgsl/reader/parser_impl_diagnostic_directive_test.cc
rename to src/tint/lang/wgsl/reader/parser/diagnostic_directive_test.cc
index c5d95e0..04e7965 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_diagnostic_directive_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/diagnostic_directive_test.cc
@@ -12,15 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/diagnostic_control.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, DiagnosticDirective_Name) {
+TEST_F(WGSLParserTest, DiagnosticDirective_Name) {
     auto p = parser("diagnostic(off, foo);");
     p->diagnostic_directive();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -37,7 +37,7 @@
     ast::CheckIdentifier(r->name, "foo");
 }
 
-TEST_F(ParserImplTest, DiagnosticDirective_CategoryName) {
+TEST_F(WGSLParserTest, DiagnosticDirective_CategoryName) {
     auto p = parser("diagnostic(off, foo.bar);");
     p->diagnostic_directive();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -54,7 +54,7 @@
     ast::CheckIdentifier(r->name, "bar");
 }
 
-TEST_F(ParserImplTest, DiagnosticDirective_MissingSemicolon) {
+TEST_F(WGSLParserTest, DiagnosticDirective_MissingSemicolon) {
     auto p = parser("diagnostic(off, foo)");
     p->translation_unit();
     EXPECT_TRUE(p->has_error());
@@ -65,7 +65,7 @@
     EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
 }
 
-TEST_F(ParserImplTest, DiagnosticDirective_FollowingOtherGlobalDecl) {
+TEST_F(WGSLParserTest, DiagnosticDirective_FollowingOtherGlobalDecl) {
     auto p = parser(R"(
 var<private> t: f32 = 0f;
 diagnostic(off, foo);
@@ -75,7 +75,7 @@
     EXPECT_EQ(p->error(), "3:1: directives must come before all global declarations");
 }
 
-TEST_F(ParserImplTest, DiagnosticDirective_FollowingEmptySemicolon) {
+TEST_F(WGSLParserTest, DiagnosticDirective_FollowingEmptySemicolon) {
     auto p = parser(R"(
 ;
 diagnostic(off, foo);
@@ -87,4 +87,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_enable_directive_test.cc b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
similarity index 98%
rename from src/tint/lang/wgsl/reader/parser_impl_enable_directive_test.cc
rename to src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
index 675e70b..964bb3b 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_enable_directive_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/enable.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using EnableDirectiveTest = ParserImplTest;
+using EnableDirectiveTest = WGSLParserTest;
 
 // Test a valid enable directive.
 TEST_F(EnableDirectiveTest, Single) {
@@ -307,4 +307,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_error_msg_test.cc b/src/tint/lang/wgsl/reader/parser/error_msg_test.cc
similarity index 98%
rename from src/tint/lang/wgsl/reader/parser_impl_error_msg_test.cc
rename to src/tint/lang/wgsl/reader/parser/error_msg_test.cc
index 3233c20..65e88b1 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_error_msg_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/error_msg_test.cc
@@ -12,18 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 const diag::Formatter::Style formatter_style{/* print_file: */ true, /* print_severity: */ true,
                                              /* print_line: */ true,
                                              /* print_newline_at_end: */ false};
 
-class ParserImplErrorTest : public ParserImplTest {};
+class ParserImplErrorTest : public WGSLParserTest {};
 
 #define EXPECT(SOURCE, EXPECTED)                                                   \
     do {                                                                           \
@@ -1154,4 +1154,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_error_resync_test.cc b/src/tint/lang/wgsl/reader/parser/error_resync_test.cc
similarity index 95%
rename from src/tint/lang/wgsl/reader/parser_impl_error_resync_test.cc
rename to src/tint/lang/wgsl/reader/parser/error_resync_test.cc
index 4f87282..847c7e4 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_error_resync_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/error_resync_test.cc
@@ -12,16 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 const diag::Formatter::Style formatter_style{/* print_file: */ true, /* print_severity: */ true,
                                              /* print_line: */ true,
                                              /* print_newline_at_end: */ false};
 
-class ParserImplErrorResyncTest : public ParserImplTest {};
+class ParserImplErrorResyncTest : public WGSLParserTest {};
 
 #define EXPECT(SOURCE, EXPECTED)                                                   \
     do {                                                                           \
@@ -173,4 +173,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_expression_test.cc b/src/tint/lang/wgsl/reader/parser/expression_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/expression_test.cc
index dad793d..6ab05d2 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/expression_test.cc
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Expression_InvalidLHS) {
+TEST_F(WGSLParserTest, Expression_InvalidLHS) {
     auto p = parser("if (a) {} || true");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -28,7 +28,7 @@
     EXPECT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, Expression_Or_Parses) {
+TEST_F(WGSLParserTest, Expression_Or_Parses) {
     auto p = parser("a || true");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -53,7 +53,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, Expression_Or_Parses_Multiple) {
+TEST_F(WGSLParserTest, Expression_Or_Parses_Multiple) {
     auto p = parser("a || true || b");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -85,7 +85,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, Expression_Or_InvalidRHS) {
+TEST_F(WGSLParserTest, Expression_Or_InvalidRHS) {
     auto p = parser("true || if (a) {}");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -95,7 +95,7 @@
     EXPECT_EQ(p->error(), "1:9: unable to parse right side of || expression");
 }
 
-TEST_F(ParserImplTest, Expression_And_Parses) {
+TEST_F(WGSLParserTest, Expression_And_Parses) {
     auto p = parser("a && true");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -120,7 +120,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, Expression_And_Parses_Multple) {
+TEST_F(WGSLParserTest, Expression_And_Parses_Multple) {
     auto p = parser("a && true && b");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -150,7 +150,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, Expression_And_InvalidRHS) {
+TEST_F(WGSLParserTest, Expression_And_InvalidRHS) {
     auto p = parser("true && if (a) {}");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -160,7 +160,7 @@
     EXPECT_EQ(p->error(), "1:9: unable to parse right side of && expression");
 }
 
-TEST_F(ParserImplTest, Expression_Mixing_OrWithAnd) {
+TEST_F(WGSLParserTest, Expression_Mixing_OrWithAnd) {
     auto p = parser("a && true || b");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -170,7 +170,7 @@
     EXPECT_EQ(p->error(), "1:3: mixing '&&' and '||' requires parenthesis");
 }
 
-TEST_F(ParserImplTest, Expression_Mixing_AndWithOr) {
+TEST_F(WGSLParserTest, Expression_Mixing_AndWithOr) {
     auto p = parser("a || true && b");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -180,7 +180,7 @@
     EXPECT_EQ(p->error(), "1:3: mixing '||' and '&&' requires parenthesis");
 }
 
-TEST_F(ParserImplTest, Expression_Bitwise) {
+TEST_F(WGSLParserTest, Expression_Bitwise) {
     auto p = parser("a & b");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -201,7 +201,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, Expression_Relational) {
+TEST_F(WGSLParserTest, Expression_Relational) {
     auto p = parser("a <= b");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -222,7 +222,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, Expression_InvalidUnary) {
+TEST_F(WGSLParserTest, Expression_InvalidUnary) {
     auto p = parser("!if || true");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -232,7 +232,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse right side of ! expression");
 }
 
-TEST_F(ParserImplTest, Expression_InvalidBitwise) {
+TEST_F(WGSLParserTest, Expression_InvalidBitwise) {
     auto p = parser("a & if");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -242,7 +242,7 @@
     EXPECT_EQ(p->error(), "1:5: unable to parse right side of & expression");
 }
 
-TEST_F(ParserImplTest, Expression_InvalidRelational) {
+TEST_F(WGSLParserTest, Expression_InvalidRelational) {
     auto p = parser("a <= if");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -252,7 +252,7 @@
     EXPECT_EQ(p->error(), "1:6: unable to parse right side of <= expression");
 }
 
-TEST_F(ParserImplTest, Expression_Associativity) {
+TEST_F(WGSLParserTest, Expression_Associativity) {
     auto p = parser("1 < 2 || 2 < 3");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -261,7 +261,7 @@
     ASSERT_NE(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, Expression_InvalidAssociativity) {
+TEST_F(WGSLParserTest, Expression_InvalidAssociativity) {
     auto p = parser("1 < 2 && 2 < 3 || 3 < 4");
     auto e = p->expression();
     EXPECT_FALSE(e.matched);
@@ -271,7 +271,7 @@
     EXPECT_EQ(p->error(), R"(1:7: mixing '&&' and '||' requires parenthesis)");
 }
 
-TEST_F(ParserImplTest, Expression_SubtractionNoSpace) {
+TEST_F(WGSLParserTest, Expression_SubtractionNoSpace) {
     auto p = parser("(2-1)");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -289,7 +289,7 @@
     EXPECT_EQ(b->rhs->As<ast::IntLiteralExpression>()->value, 1);
 }
 
-TEST_F(ParserImplTest, Expression_NegatedNumber) {
+TEST_F(WGSLParserTest, Expression_NegatedNumber) {
     auto p = parser("-1");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -305,7 +305,7 @@
     EXPECT_EQ(b->expr->As<ast::IntLiteralExpression>()->value, 1);
 }
 
-TEST_F(ParserImplTest, Expression_MaxI32) {
+TEST_F(WGSLParserTest, Expression_MaxI32) {
     auto p = parser("2147483647");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -317,7 +317,7 @@
     EXPECT_EQ(e->As<ast::IntLiteralExpression>()->value, 2147483647);
 }
 
-TEST_F(ParserImplTest, Expression_MinI32) {
+TEST_F(WGSLParserTest, Expression_MinI32) {
     auto p = parser("-2147483648");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -333,7 +333,7 @@
     EXPECT_EQ(b->expr->As<ast::IntLiteralExpression>()->value, 2147483648);
 }
 
-TEST_F(ParserImplTest, Expression_MaxU32) {
+TEST_F(WGSLParserTest, Expression_MaxU32) {
     auto p = parser("4294967295");
     auto e = p->expression();
     EXPECT_TRUE(e.matched);
@@ -345,7 +345,7 @@
     EXPECT_EQ(e->As<ast::IntLiteralExpression>()->value, 4294967295);
 }
 
-TEST_F(ParserImplTest, Expression_MaxF32) {
+TEST_F(WGSLParserTest, Expression_MaxF32) {
     const auto highest = std::numeric_limits<float>::max();
     const auto expected_highest = 340282346638528859811704183484516925440.0f;
     if (highest < expected_highest || highest > expected_highest) {
@@ -365,7 +365,7 @@
               340282346638528859811704183484516925440.0f);
 }
 
-TEST_F(ParserImplTest, Expression_MinF32) {
+TEST_F(WGSLParserTest, Expression_MinF32) {
     const auto lowest = std::numeric_limits<float>::lowest();
     const auto expected_lowest = -340282346638528859811704183484516925440.0f;
     if (lowest < expected_lowest || lowest > expected_lowest) {
@@ -485,7 +485,7 @@
     return out;
 }
 
-using ParserImplMixedBinaryOpTest = ParserImplTestWithParam<Case>;
+using ParserImplMixedBinaryOpTest = WGSLParserTestWithParam<Case>;
 
 TEST_P(ParserImplMixedBinaryOpTest, Test) {
     utils::StringStream wgsl;
@@ -513,4 +513,4 @@
 }  // namespace mixing_binary_ops
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_for_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/for_stmt_test.cc
similarity index 93%
rename from src/tint/lang/wgsl/reader/parser_impl_for_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/for_stmt_test.cc
index ecd06e3..d26dda0 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_for_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/for_stmt_test.cc
@@ -12,19 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using ForStmtTest = ParserImplTest;
+using ForStmtTest = WGSLParserTest;
 
 // Test an empty for loop.
 TEST_F(ForStmtTest, Empty) {
     auto p = parser("for (;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -38,7 +38,7 @@
 // Test a for loop with non-empty body.
 TEST_F(ForStmtTest, Body) {
     auto p = parser("for (;;) { discard; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -53,7 +53,7 @@
 // Test a for loop declaring a variable in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementDecl) {
     auto p = parser("for (var i: i32 ;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -71,7 +71,7 @@
 // statement.
 TEST_F(ForStmtTest, InitializerStatementDeclEqual) {
     auto p = parser("for (var i: i32 = 0 ;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -88,7 +88,7 @@
 // Test a for loop declaring a const variable in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementConstDecl) {
     auto p = parser("for (let i: i32 = 0 ;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -105,7 +105,7 @@
 // Test a for loop assigning a variable in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementAssignment) {
     auto p = parser("for (i = 0 ;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -119,7 +119,7 @@
 // Test a for loop incrementing a variable in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementIncrement) {
     auto p = parser("for (i++;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -133,7 +133,7 @@
 // Test a for loop calling a function in the initializer statement.
 TEST_F(ForStmtTest, InitializerStatementFuncCall) {
     auto p = parser("for (a(b,c) ;;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -147,7 +147,7 @@
 // Test a for loop with a break condition
 TEST_F(ForStmtTest, BreakCondition) {
     auto p = parser("for (; 0 == 1;) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -161,7 +161,7 @@
 // Test a for loop assigning a variable in the continuing statement.
 TEST_F(ForStmtTest, ContinuingAssignment) {
     auto p = parser("for (;; x = 2) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -175,7 +175,7 @@
 // Test a for loop with an increment statement as the continuing statement.
 TEST_F(ForStmtTest, ContinuingIncrement) {
     auto p = parser("for (;; x++) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -189,7 +189,7 @@
 // Test a for loop calling a function in the continuing statement.
 TEST_F(ForStmtTest, ContinuingFuncCall) {
     auto p = parser("for (;; a(b,c)) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto fl = p->for_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(fl.errored);
@@ -214,11 +214,11 @@
     EXPECT_TRUE(fl->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-class ForStmtErrorTest : public ParserImplTest {
+class ForStmtErrorTest : public WGSLParserTest {
   public:
     void TestForWithError(std::string for_str, std::string error_str) {
         auto p_for = parser(for_str);
-        ParserImpl::AttributeList attrs;
+        Parser::AttributeList attrs;
         auto e_for = p_for->for_statement(attrs);
 
         EXPECT_FALSE(e_for.matched);
@@ -345,4 +345,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_function_attribute_list_test.cc b/src/tint/lang/wgsl/reader/parser/function_attribute_list_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_function_attribute_list_test.cc
rename to src/tint/lang/wgsl/reader/parser/function_attribute_list_test.cc
index 5ac213e..8d72776 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_function_attribute_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/function_attribute_list_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AttributeList_Parses) {
+TEST_F(WGSLParserTest, AttributeList_Parses) {
     auto p = parser("@workgroup_size(2) @compute");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -44,7 +44,7 @@
     EXPECT_EQ(attr_1->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
 }
 
-TEST_F(ParserImplTest, AttributeList_Invalid) {
+TEST_F(WGSLParserTest, AttributeList_Invalid) {
     auto p = parser("@invalid");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -57,4 +57,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_function_attribute_test.cc b/src/tint/lang/wgsl/reader/parser/function_attribute_test.cc
similarity index 91%
rename from src/tint/lang/wgsl/reader/parser_impl_function_attribute_test.cc
rename to src/tint/lang/wgsl/reader/parser/function_attribute_test.cc
index 3e54dc1..a43d0c4 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_function_attribute_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/function_attribute_test.cc
@@ -15,12 +15,12 @@
 #include "src/tint/lang/wgsl/ast/stage_attribute.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
 #include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Attribute_Workgroup) {
+TEST_F(WGSLParserTest, Attribute_Workgroup) {
     auto p = parser("workgroup_size(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -42,7 +42,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_Expression) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_Expression) {
     auto p = parser("workgroup_size(4 + 2)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -71,7 +71,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_1Param_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_1Param_TrailingComma) {
     auto p = parser("workgroup_size(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -93,7 +93,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_1Param_TrailingComma_Double) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_1Param_TrailingComma_Double) {
     auto p = parser("workgroup_size(4,,)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -103,7 +103,7 @@
     EXPECT_EQ(p->error(), "1:18: expected expression for workgroup_size");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_2Param) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_2Param) {
     auto p = parser("workgroup_size(4, 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -129,7 +129,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_2Param_Expression) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_2Param_Expression) {
     auto p = parser("workgroup_size(4, 5 - 2)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -162,7 +162,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_2Param_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_2Param_TrailingComma) {
     auto p = parser("workgroup_size(4, 5,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -188,7 +188,7 @@
     EXPECT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup21Param_TrailingComma_Double) {
+TEST_F(WGSLParserTest, Attribute_Workgroup21Param_TrailingComma_Double) {
     auto p = parser("workgroup_size(4,5,,)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -198,7 +198,7 @@
     EXPECT_EQ(p->error(), "1:20: expected expression for workgroup_size");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_3Param) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_3Param) {
     auto p = parser("workgroup_size(4, 5, 6)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -227,7 +227,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_3Param_Expression) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_3Param_Expression) {
     auto p = parser("workgroup_size(4, 5, 6 << 1)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -263,7 +263,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_3Param_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_3Param_TrailingComma) {
     auto p = parser("workgroup_size(4, 5, 6,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -292,7 +292,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_WithIdent) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_WithIdent) {
     auto p = parser("workgroup_size(4, height)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -316,7 +316,7 @@
     ASSERT_EQ(values[2], nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_TooManyValues) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_TooManyValues) {
     auto p = parser("workgroup_size(1, 2, 3, 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -326,7 +326,7 @@
     EXPECT_EQ(p->error(), "1:1: workgroup_size expects at most 3 arguments, got 4");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_MissingLeftParam) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_MissingLeftParam) {
     auto p = parser("workgroup_size 4, 5, 6)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -336,7 +336,7 @@
     EXPECT_EQ(p->error(), "1:16: expected '(' for workgroup_size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_MissingRightParam) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_MissingRightParam) {
     auto p = parser("workgroup_size(4, 5, 6");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -346,7 +346,7 @@
     EXPECT_EQ(p->error(), "1:23: expected ')' for workgroup_size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_MissingValues) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_MissingValues) {
     auto p = parser("workgroup_size()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -356,7 +356,7 @@
     EXPECT_EQ(p->error(), "1:1: workgroup_size expects at least 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_Missing_X_Value) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_Missing_X_Value) {
     auto p = parser("workgroup_size(, 2, 3)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -366,7 +366,7 @@
     EXPECT_EQ(p->error(), "1:16: expected expression for workgroup_size");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Comma) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_Missing_Y_Comma) {
     auto p = parser("workgroup_size(1 2, 3)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -376,7 +376,7 @@
     EXPECT_EQ(p->error(), "1:18: expected ')' for workgroup_size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Y_Value) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_Missing_Y_Value) {
     auto p = parser("workgroup_size(1, , 3)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -386,7 +386,7 @@
     EXPECT_EQ(p->error(), "1:19: expected expression for workgroup_size");
 }
 
-TEST_F(ParserImplTest, Attribute_Workgroup_Missing_Z_Comma) {
+TEST_F(WGSLParserTest, Attribute_Workgroup_Missing_Z_Comma) {
     auto p = parser("workgroup_size(1, 2 3)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -396,7 +396,7 @@
     EXPECT_EQ(p->error(), "1:21: expected ')' for workgroup_size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Compute) {
+TEST_F(WGSLParserTest, Attribute_Compute) {
     auto p = parser("compute");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -409,7 +409,7 @@
     EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kCompute);
 }
 
-TEST_F(ParserImplTest, Attribute_Vertex) {
+TEST_F(WGSLParserTest, Attribute_Vertex) {
     auto p = parser("vertex");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -422,7 +422,7 @@
     EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kVertex);
 }
 
-TEST_F(ParserImplTest, Attribute_Fragment) {
+TEST_F(WGSLParserTest, Attribute_Fragment) {
     auto p = parser("fragment");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -435,7 +435,7 @@
     EXPECT_EQ(func_attr->As<ast::StageAttribute>()->stage, ast::PipelineStage::kFragment);
 }
 
-TEST_F(ParserImplTest, Attribute_MustUse) {
+TEST_F(WGSLParserTest, Attribute_MustUse) {
     auto p = parser("must_use");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -448,4 +448,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_function_decl_test.cc b/src/tint/lang/wgsl/reader/parser/function_decl_test.cc
similarity index 94%
rename from src/tint/lang/wgsl/reader/parser_impl_function_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/function_decl_test.cc
index 6822822..0a4209f 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_function_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/function_decl_test.cc
@@ -14,13 +14,13 @@
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
 #include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 #include "src/tint/utils/text/string.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, FunctionDecl) {
+TEST_F(WGSLParserTest, FunctionDecl) {
     auto p = parser("fn main(a : i32, b : f32) { return; }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -46,7 +46,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_Unicode) {
+TEST_F(WGSLParserTest, FunctionDecl_Unicode) {
     const std::string function_ident =  // "𝗳𝘂𝗻𝗰𝘁𝗶𝗼𝗻"
         "\xf0\x9d\x97\xb3\xf0\x9d\x98\x82\xf0\x9d\x97\xbb\xf0\x9d\x97\xb0\xf0\x9d"
         "\x98\x81\xf0\x9d\x97\xb6\xf0\x9d\x97\xbc\xf0\x9d\x97\xbb";
@@ -89,7 +89,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_AttributeList) {
+TEST_F(WGSLParserTest, FunctionDecl_AttributeList) {
     auto p = parser("@workgroup_size(2, 3, 4) fn main() { return; }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -131,7 +131,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleEntries) {
+TEST_F(WGSLParserTest, FunctionDecl_AttributeList_MultipleEntries) {
     auto p = parser(R"(
 @workgroup_size(2, 3, 4) @compute
 fn main() { return; })");
@@ -178,7 +178,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_AttributeList_MultipleLists) {
+TEST_F(WGSLParserTest, FunctionDecl_AttributeList_MultipleLists) {
     auto p = parser(R"(
 @workgroup_size(2, 3, 4)
 @compute
@@ -226,7 +226,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_ReturnTypeAttributeList) {
+TEST_F(WGSLParserTest, FunctionDecl_ReturnTypeAttributeList) {
     auto p = parser("fn main() -> @location(1) f32 { return 1.0; }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -262,7 +262,7 @@
     EXPECT_TRUE(body->statements[0]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_MustUse) {
+TEST_F(WGSLParserTest, FunctionDecl_MustUse) {
     auto p = parser("@must_use fn main() { return; }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -279,7 +279,7 @@
     ASSERT_TRUE(attributes[0]->Is<ast::MustUseAttribute>());
 }
 
-TEST_F(ParserImplTest, FunctionDecl_InvalidHeader) {
+TEST_F(WGSLParserTest, FunctionDecl_InvalidHeader) {
     auto p = parser("fn main() -> { }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -293,7 +293,7 @@
     EXPECT_EQ(p->error(), "1:14: unable to determine function return type");
 }
 
-TEST_F(ParserImplTest, FunctionDecl_InvalidBody) {
+TEST_F(WGSLParserTest, FunctionDecl_InvalidBody) {
     auto p = parser("fn main() { return }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -307,7 +307,7 @@
     EXPECT_EQ(p->error(), "1:20: expected ';' for return statement");
 }
 
-TEST_F(ParserImplTest, FunctionDecl_MissingLeftBrace) {
+TEST_F(WGSLParserTest, FunctionDecl_MissingLeftBrace) {
     auto p = parser("fn main() return; }");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -322,4 +322,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_function_header_test.cc b/src/tint/lang/wgsl/reader/parser/function_header_test.cc
similarity index 85%
rename from src/tint/lang/wgsl/reader/parser_impl_function_header_test.cc
rename to src/tint/lang/wgsl/reader/parser/function_header_test.cc
index e043e68..e155ace 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_function_header_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/function_header_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, FunctionHeader) {
+TEST_F(WGSLParserTest, FunctionHeader) {
     auto p = parser("fn main(a : i32, b: f32)");
     auto f = p->function_header();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -32,7 +32,7 @@
     EXPECT_EQ(f->return_type, nullptr);
 }
 
-TEST_F(ParserImplTest, FunctionHeader_TrailingComma) {
+TEST_F(WGSLParserTest, FunctionHeader_TrailingComma) {
     auto p = parser("fn main(a :i32,)");
     auto f = p->function_header();
     EXPECT_TRUE(f.matched);
@@ -44,7 +44,7 @@
     EXPECT_EQ(f->return_type, nullptr);
 }
 
-TEST_F(ParserImplTest, FunctionHeader_AttributeReturnType) {
+TEST_F(WGSLParserTest, FunctionHeader_AttributeReturnType) {
     auto p = parser("fn main() -> @location(1) f32");
     auto f = p->function_header();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -63,7 +63,7 @@
     EXPECT_EQ(exp->value, 1u);
 }
 
-TEST_F(ParserImplTest, FunctionHeader_InvariantReturnType) {
+TEST_F(WGSLParserTest, FunctionHeader_InvariantReturnType) {
     auto p = parser("fn main() -> @invariant f32");
     auto f = p->function_header();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -77,7 +77,7 @@
     EXPECT_TRUE(f->return_type_attributes[0]->Is<ast::InvariantAttribute>());
 }
 
-TEST_F(ParserImplTest, FunctionHeader_MissingIdent) {
+TEST_F(WGSLParserTest, FunctionHeader_MissingIdent) {
     auto p = parser("fn ()");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -86,7 +86,7 @@
     EXPECT_EQ(p->error(), "1:4: expected identifier for function declaration");
 }
 
-TEST_F(ParserImplTest, FunctionHeader_InvalidIdent) {
+TEST_F(WGSLParserTest, FunctionHeader_InvalidIdent) {
     auto p = parser("fn 133main() -> i32");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -95,7 +95,7 @@
     EXPECT_EQ(p->error(), "1:4: expected identifier for function declaration");
 }
 
-TEST_F(ParserImplTest, FunctionHeader_MissingParenLeft) {
+TEST_F(WGSLParserTest, FunctionHeader_MissingParenLeft) {
     auto p = parser("fn main) -> i32");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -104,7 +104,7 @@
     EXPECT_EQ(p->error(), "1:8: expected '(' for function declaration");
 }
 
-TEST_F(ParserImplTest, FunctionHeader_InvalidParamList) {
+TEST_F(WGSLParserTest, FunctionHeader_InvalidParamList) {
     auto p = parser("fn main(a :i32, ,) -> i32");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -113,7 +113,7 @@
     EXPECT_EQ(p->error(), "1:17: expected ')' for function declaration");
 }
 
-TEST_F(ParserImplTest, FunctionHeader_MissingParenRight) {
+TEST_F(WGSLParserTest, FunctionHeader_MissingParenRight) {
     auto p = parser("fn main( -> i32");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -122,7 +122,7 @@
     EXPECT_EQ(p->error(), "1:10: expected ')' for function declaration");
 }
 
-TEST_F(ParserImplTest, FunctionHeader_MissingReturnType) {
+TEST_F(WGSLParserTest, FunctionHeader_MissingReturnType) {
     auto p = parser("fn main() ->");
     auto f = p->function_header();
     EXPECT_FALSE(f.matched);
@@ -132,4 +132,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_global_constant_decl_test.cc b/src/tint/lang/wgsl/reader/parser/global_constant_decl_test.cc
similarity index 91%
rename from src/tint/lang/wgsl/reader/parser_impl_global_constant_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/global_constant_decl_test.cc
index 696058f..a2008e6 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_global_constant_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/global_constant_decl_test.cc
@@ -14,12 +14,12 @@
 
 #include "src/tint/lang/wgsl/ast/id_attribute.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, GlobalLetDecl) {
+TEST_F(WGSLParserTest, GlobalLetDecl) {
     auto p = parser("let a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -31,7 +31,7 @@
     EXPECT_EQ(p->error(), "1:1: module-scope 'let' is invalid, use 'const'");
 }
 
-TEST_F(ParserImplTest, GlobalConstDecl) {
+TEST_F(WGSLParserTest, GlobalConstDecl) {
     auto p = parser("const a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -56,7 +56,7 @@
     EXPECT_TRUE(c->initializer->Is<ast::LiteralExpression>());
 }
 
-TEST_F(ParserImplTest, GlobalConstDecl_Inferred) {
+TEST_F(WGSLParserTest, GlobalConstDecl_Inferred) {
     auto p = parser("const a = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -80,7 +80,7 @@
     EXPECT_TRUE(c->initializer->Is<ast::LiteralExpression>());
 }
 
-TEST_F(ParserImplTest, GlobalConstDecl_InvalidExpression) {
+TEST_F(WGSLParserTest, GlobalConstDecl_InvalidExpression) {
     auto p = parser("const a : f32 = if (a) {}");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -93,7 +93,7 @@
     EXPECT_EQ(p->error(), "1:17: missing initializer for 'const' declaration");
 }
 
-TEST_F(ParserImplTest, GlobalConstDecl_MissingExpression) {
+TEST_F(WGSLParserTest, GlobalConstDecl_MissingExpression) {
     auto p = parser("const a : f32 =");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -106,7 +106,7 @@
     EXPECT_EQ(p->error(), "1:16: missing initializer for 'const' declaration");
 }
 
-TEST_F(ParserImplTest, GlobalOverrideDecl_WithId) {
+TEST_F(WGSLParserTest, GlobalOverrideDecl_WithId) {
     auto p = parser("@id(7) override a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -136,7 +136,7 @@
     EXPECT_TRUE(override_attr->expr->Is<ast::IntLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, GlobalOverrideDecl_WithId_TrailingComma) {
+TEST_F(WGSLParserTest, GlobalOverrideDecl_WithId_TrailingComma) {
     auto p = parser("@id(7,) override a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -166,7 +166,7 @@
     EXPECT_TRUE(override_attr->expr->Is<ast::IntLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, GlobalOverrideDecl_WithoutId) {
+TEST_F(WGSLParserTest, GlobalOverrideDecl_WithoutId) {
     auto p = parser("override a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -196,4 +196,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_global_decl_test.cc b/src/tint/lang/wgsl/reader/parser/global_decl_test.cc
similarity index 85%
rename from src/tint/lang/wgsl/reader/parser_impl_global_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/global_decl_test.cc
index 0e19d15..65a0368 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_global_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/global_decl_test.cc
@@ -13,18 +13,18 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, GlobalDecl_Semicolon) {
+TEST_F(WGSLParserTest, GlobalDecl_Semicolon) {
     auto p = parser(";");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalVariable) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalVariable) {
     auto p = parser("var<private> a : vec2<i32> = vec2<i32>(1, 2);");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -37,7 +37,7 @@
     ast::CheckIdentifier(v->type, ast::Template("vec2", "i32"));
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_Inferred) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalVariable_Inferred) {
     auto p = parser("var<private> a = vec2<i32>(1, 2);");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -50,14 +50,14 @@
     EXPECT_EQ(v->type, nullptr);
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalVariable_MissingSemicolon) {
     auto p = parser("var<private> a : vec2<i32>");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:27: expected ';' for variable declaration");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalLet) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalLet) {
     auto p = parser("let a : i32 = 2;");
     auto e = p->global_decl();
     EXPECT_TRUE(p->has_error());
@@ -66,7 +66,7 @@
     EXPECT_EQ(p->error(), "1:1: module-scope 'let' is invalid, use 'const'");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalConst) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalConst) {
     auto p = parser("const a : i32 = 2;");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -78,28 +78,28 @@
     EXPECT_EQ(v->name->symbol, program.Symbols().Get("a"));
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalConst_MissingInitializer) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalConst_MissingInitializer) {
     auto p = parser("const a : vec2<i32>;");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:20: expected '=' for 'const' declaration");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalConst_Invalid) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalConst_Invalid) {
     auto p = parser("const a : vec2<i32> 1.0;");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:21: expected '=' for 'const' declaration");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_GlobalConst_MissingSemicolon) {
+TEST_F(WGSLParserTest, GlobalDecl_GlobalConst_MissingSemicolon) {
     auto p = parser("const a : vec2<i32> = vec2<i32>(1, 2)");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:38: expected ';' for 'const' declaration");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_TypeAlias) {
+TEST_F(WGSLParserTest, GlobalDecl_TypeAlias) {
     auto p = parser("alias A = i32;");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -110,7 +110,7 @@
     ast::CheckIdentifier(program.AST().TypeDecls()[0]->As<ast::Alias>()->name, "A");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_TypeAlias_StructIdent) {
+TEST_F(WGSLParserTest, GlobalDecl_TypeAlias_StructIdent) {
     auto p = parser(R"(struct A {
   a : f32,
 }
@@ -131,14 +131,14 @@
     ast::CheckIdentifier(alias->type, "A");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_TypeAlias_MissingSemicolon) {
+TEST_F(WGSLParserTest, GlobalDecl_TypeAlias_MissingSemicolon) {
     auto p = parser("alias A = i32");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:14: expected ';' for type alias");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_Function) {
+TEST_F(WGSLParserTest, GlobalDecl_Function) {
     auto p = parser("fn main() { return; }");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -148,7 +148,7 @@
     ast::CheckIdentifier(program.AST().Functions()[0]->name, "main");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) {
+TEST_F(WGSLParserTest, GlobalDecl_Function_WithAttribute) {
     auto p = parser("@workgroup_size(2) fn main() { return; }");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -158,14 +158,14 @@
     ast::CheckIdentifier(program.AST().Functions()[0]->name, "main");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) {
+TEST_F(WGSLParserTest, GlobalDecl_Function_Invalid) {
     auto p = parser("fn main() -> { return; }");
     p->global_decl();
     ASSERT_TRUE(p->has_error());
     EXPECT_EQ(p->error(), "1:14: unable to determine function return type");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_ParsesStruct) {
+TEST_F(WGSLParserTest, GlobalDecl_ParsesStruct) {
     auto p = parser("struct A { b: i32, c: f32}");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -182,7 +182,7 @@
     EXPECT_EQ(str->members.Length(), 2u);
 }
 
-TEST_F(ParserImplTest, GlobalDecl_Struct_Invalid) {
+TEST_F(WGSLParserTest, GlobalDecl_Struct_Invalid) {
     {
         auto p = parser("A {}");
         auto decl = p->global_decl();
@@ -199,7 +199,7 @@
     }
 }
 
-TEST_F(ParserImplTest, GlobalDecl_Struct_UnexpectedAttribute) {
+TEST_F(WGSLParserTest, GlobalDecl_Struct_UnexpectedAttribute) {
     auto p = parser("@vertex struct S { i : i32 }");
 
     auto s = p->global_decl();
@@ -210,7 +210,7 @@
     EXPECT_EQ(p->error(), "1:2: unexpected attributes");
 }
 
-TEST_F(ParserImplTest, GlobalDecl_ConstAssert_WithParen) {
+TEST_F(WGSLParserTest, GlobalDecl_ConstAssert_WithParen) {
     auto p = parser("const_assert(true);");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -230,7 +230,7 @@
     EXPECT_EQ(sa->condition->source.range.end.column, 18u);
 }
 
-TEST_F(ParserImplTest, GlobalDecl_ConstAssert_WithoutParen) {
+TEST_F(WGSLParserTest, GlobalDecl_ConstAssert_WithoutParen) {
     auto p = parser("const_assert  true;");
     p->global_decl();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -253,4 +253,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_global_variable_decl_test.cc b/src/tint/lang/wgsl/reader/parser/global_variable_decl_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_global_variable_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/global_variable_decl_test.cc
index 45cb31f..bff7fb6 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_global_variable_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/global_variable_decl_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, GlobalVariableDecl_WithoutInitializer) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_WithoutInitializer) {
     auto p = parser("var<private> a : f32");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -42,7 +42,7 @@
     ASSERT_EQ(var->initializer, nullptr);
 }
 
-TEST_F(ParserImplTest, GlobalVariableDecl_WithInitializer) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_WithInitializer) {
     auto p = parser("var<private> a : f32 = 1.");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -67,7 +67,7 @@
     ASSERT_TRUE(var->initializer->Is<ast::FloatLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_WithAttribute) {
     auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -96,7 +96,7 @@
     ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
 }
 
-TEST_F(ParserImplTest, GlobalVariableDecl_WithAttribute_MulitpleGroups) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_WithAttribute_MulitpleGroups) {
     auto p = parser("@binding(2) @group(1) var<uniform> a : f32");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -126,7 +126,7 @@
     ASSERT_TRUE(attributes[1]->Is<ast::GroupAttribute>());
 }
 
-TEST_F(ParserImplTest, GlobalVariableDecl_InvalidAttribute) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_InvalidAttribute) {
     auto p = parser("@binding() var<uniform> a : f32");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(attrs.errored);
@@ -141,7 +141,7 @@
     EXPECT_EQ(p->error(), "1:2: binding expects 1 argument");
 }
 
-TEST_F(ParserImplTest, GlobalVariableDecl_InvalidConstExpr) {
+TEST_F(WGSLParserTest, GlobalVariableDecl_InvalidConstExpr) {
     auto p = parser("var<private> a : f32 = if (a) {}");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(attrs.errored);
@@ -155,4 +155,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_if_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/if_stmt_test.cc
similarity index 83%
rename from src/tint/lang/wgsl/reader/parser_impl_if_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/if_stmt_test.cc
index 2a90b23..39ee1fd 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_if_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/if_stmt_test.cc
@@ -12,14 +12,14 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, IfStmt) {
+TEST_F(WGSLParserTest, IfStmt) {
     auto p = parser("if a == 4 { a = b; c = d; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -33,9 +33,9 @@
     EXPECT_EQ(e->else_statement, nullptr);
 }
 
-TEST_F(ParserImplTest, IfStmt_WithElse) {
+TEST_F(WGSLParserTest, IfStmt_WithElse) {
     auto p = parser("if a == 4 { a = b; c = d; } else if(c) { d = 2; } else {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -57,9 +57,9 @@
     EXPECT_EQ(el->statements.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, IfStmt_WithElse_WithParens) {
+TEST_F(WGSLParserTest, IfStmt_WithElse_WithParens) {
     auto p = parser("if(a==4) { a = b; c = d; } else if(c) { d = 2; } else {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -81,7 +81,7 @@
     EXPECT_EQ(el->statements.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, IfStmt_WithAttributes) {
+TEST_F(WGSLParserTest, IfStmt_WithAttributes) {
     auto p = parser(R"(@diagnostic(off, derivative_uniformity) if true { })");
     auto a = p->attribute_list();
     auto e = p->if_statement(a.value);
@@ -96,9 +96,9 @@
     EXPECT_TRUE(e->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, IfStmt_InvalidCondition) {
+TEST_F(WGSLParserTest, IfStmt_InvalidCondition) {
     auto p = parser("if a = 3 {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -107,9 +107,9 @@
     EXPECT_EQ(p->error(), "1:6: expected '{' for if statement");
 }
 
-TEST_F(ParserImplTest, IfStmt_MissingCondition) {
+TEST_F(WGSLParserTest, IfStmt_MissingCondition) {
     auto p = parser("if {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -118,9 +118,9 @@
     EXPECT_EQ(p->error(), "1:4: unable to parse condition expression");
 }
 
-TEST_F(ParserImplTest, IfStmt_InvalidBody) {
+TEST_F(WGSLParserTest, IfStmt_InvalidBody) {
     auto p = parser("if a { fn main() {}}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -129,9 +129,9 @@
     EXPECT_EQ(p->error(), "1:8: expected '}' for if statement");
 }
 
-TEST_F(ParserImplTest, IfStmt_MissingBody) {
+TEST_F(WGSLParserTest, IfStmt_MissingBody) {
     auto p = parser("if a");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -140,9 +140,9 @@
     EXPECT_EQ(p->error(), "1:5: expected '{' for if statement");
 }
 
-TEST_F(ParserImplTest, IfStmt_InvalidElseif) {
+TEST_F(WGSLParserTest, IfStmt_InvalidElseif) {
     auto p = parser("if a {} else if a { fn main() -> a{}}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -151,9 +151,9 @@
     EXPECT_EQ(p->error(), "1:21: expected '}' for if statement");
 }
 
-TEST_F(ParserImplTest, IfStmt_InvalidElse) {
+TEST_F(WGSLParserTest, IfStmt_InvalidElse) {
     auto p = parser("if a {} else { fn main() -> a{}}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->if_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -163,4 +163,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_increment_decrement_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/increment_decrement_stmt_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_increment_decrement_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/increment_decrement_stmt_test.cc
index 2274c2b..a8fab2e 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_increment_decrement_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/increment_decrement_stmt_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, IncrementDecrementStmt_Increment) {
+TEST_F(WGSLParserTest, IncrementDecrementStmt_Increment) {
     auto p = parser("a++");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -36,7 +36,7 @@
     EXPECT_TRUE(i->increment);
 }
 
-TEST_F(ParserImplTest, IncrementDecrementStmt_Decrement) {
+TEST_F(WGSLParserTest, IncrementDecrementStmt_Decrement) {
     auto p = parser("a--");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -55,7 +55,7 @@
     EXPECT_FALSE(i->increment);
 }
 
-TEST_F(ParserImplTest, IncrementDecrementStmt_Parenthesized) {
+TEST_F(WGSLParserTest, IncrementDecrementStmt_Parenthesized) {
     auto p = parser("(a)++");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -74,7 +74,7 @@
     EXPECT_TRUE(i->increment);
 }
 
-TEST_F(ParserImplTest, IncrementDecrementStmt_ToMember) {
+TEST_F(WGSLParserTest, IncrementDecrementStmt_ToMember) {
     auto p = parser("a.b.c[2].d++");
     auto e = p->variable_updating_statement();
     EXPECT_TRUE(e.matched);
@@ -112,7 +112,7 @@
     EXPECT_EQ(mem->member->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, IncrementDecrementStmt_InvalidLHS) {
+TEST_F(WGSLParserTest, IncrementDecrementStmt_InvalidLHS) {
     auto p = parser("{}++");
     auto e = p->variable_updating_statement();
     EXPECT_FALSE(e.matched);
@@ -122,4 +122,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/lexer.cc b/src/tint/lang/wgsl/reader/parser/lexer.cc
similarity index 99%
rename from src/tint/lang/wgsl/reader/lexer.cc
rename to src/tint/lang/wgsl/reader/parser/lexer.cc
index cc337fd..a75888b 100644
--- a/src/tint/lang/wgsl/reader/lexer.cc
+++ b/src/tint/lang/wgsl/reader/parser/lexer.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/lexer.h"
+#include "src/tint/lang/wgsl/reader/parser/lexer.h"
 
 #include <cctype>
 #include <charconv>
@@ -30,13 +30,13 @@
 #include "src/tint/utils/text/parse_num.h"
 #include "src/tint/utils/text/unicode.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 // Unicode parsing code assumes that the size of a single std::string element is
 // 1 byte.
 static_assert(sizeof(decltype(tint::Source::FileContent::data[0])) == sizeof(uint8_t),
-              "tint::reader::wgsl requires the size of a std::string element "
+              "tint::wgsl::reader requires the size of a std::string element "
               "to be a single byte");
 
 // A token is ~80bytes. The 4k here comes from looking at the number of tokens in the benchmark
@@ -1284,4 +1284,4 @@
     return std::nullopt;
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/lexer.h b/src/tint/lang/wgsl/reader/parser/lexer.h
similarity index 93%
rename from src/tint/lang/wgsl/reader/lexer.h
rename to src/tint/lang/wgsl/reader/parser/lexer.h
index 0e6dacf..b7768e0 100644
--- a/src/tint/lang/wgsl/reader/lexer.h
+++ b/src/tint/lang/wgsl/reader/parser/lexer.h
@@ -12,16 +12,16 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_LEXER_H_
-#define SRC_TINT_LANG_WGSL_READER_LEXER_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
 
 #include <optional>
 #include <string>
 #include <vector>
 
-#include "src/tint/lang/wgsl/reader/token.h"
+#include "src/tint/lang/wgsl/reader/parser/token.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 /// Converts the input stream into a series of Tokens
 class Lexer {
@@ -112,6 +112,6 @@
     Source::Location location_;
 };
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_LEXER_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
diff --git a/src/tint/lang/wgsl/reader/lexer_test.cc b/src/tint/lang/wgsl/reader/parser/lexer_test.cc
similarity index 99%
rename from src/tint/lang/wgsl/reader/lexer_test.cc
rename to src/tint/lang/wgsl/reader/parser/lexer_test.cc
index 80a0d62..4a7f74c 100644
--- a/src/tint/lang/wgsl/reader/lexer_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/lexer_test.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/lexer.h"
+#include "src/tint/lang/wgsl/reader/parser/lexer.h"
 
 #include <limits>
 #include <tuple>
@@ -21,7 +21,7 @@
 #include "gtest/gtest.h"
 #include "src/tint/lang/core/builtin/number.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 using LexerTest = testing::Test;
@@ -1135,4 +1135,4 @@
                                          TokenData{"while", Token::Type::kWhile}));
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_lhs_expression_test.cc b/src/tint/lang/wgsl/reader/parser/lhs_expression_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_lhs_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/lhs_expression_test.cc
index 8cc3e59..6e1e8cd 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_lhs_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/lhs_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, LHSExpression_NoPrefix) {
+TEST_F(WGSLParserTest, LHSExpression_NoPrefix) {
     auto p = parser("a");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -27,7 +27,7 @@
     ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, LHSExpression_NoMatch) {
+TEST_F(WGSLParserTest, LHSExpression_NoMatch) {
     auto p = parser("123");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -36,7 +36,7 @@
     ASSERT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, LHSExpression_And) {
+TEST_F(WGSLParserTest, LHSExpression_And) {
     auto p = parser("&a");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -50,7 +50,7 @@
     EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, LHSExpression_Star) {
+TEST_F(WGSLParserTest, LHSExpression_Star) {
     auto p = parser("*a");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -64,7 +64,7 @@
     EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, LHSExpression_InvalidCoreLHSExpr) {
+TEST_F(WGSLParserTest, LHSExpression_InvalidCoreLHSExpr) {
     auto p = parser("*123");
     auto e = p->lhs_expression();
     ASSERT_TRUE(p->has_error());
@@ -74,7 +74,7 @@
     EXPECT_EQ(p->error(), "1:2: missing expression");
 }
 
-TEST_F(ParserImplTest, LHSExpression_Multiple) {
+TEST_F(WGSLParserTest, LHSExpression_Multiple) {
     auto p = parser("*&********&&&&&&*a");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -103,7 +103,7 @@
     EXPECT_TRUE(expr->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, LHSExpression_PostfixExpression_Array) {
+TEST_F(WGSLParserTest, LHSExpression_PostfixExpression_Array) {
     auto p = parser("*a[0]");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -128,7 +128,7 @@
     EXPECT_EQ(0, idx->value);
 }
 
-TEST_F(ParserImplTest, LHSExpression_PostfixExpression) {
+TEST_F(WGSLParserTest, LHSExpression_PostfixExpression) {
     auto p = parser("*a.foo");
     auto e = p->lhs_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -150,7 +150,7 @@
     EXPECT_EQ(access->member->symbol, p->builder().Symbols().Get("foo"));
 }
 
-TEST_F(ParserImplTest, LHSExpression_InvalidPostfixExpression) {
+TEST_F(WGSLParserTest, LHSExpression_InvalidPostfixExpression) {
     auto p = parser("*a.if");
     auto e = p->lhs_expression();
     ASSERT_TRUE(p->has_error());
@@ -161,4 +161,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_loop_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/loop_stmt_test.cc
similarity index 81%
rename from src/tint/lang/wgsl/reader/parser_impl_loop_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/loop_stmt_test.cc
index 839dc5c..334bcc6 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_loop_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/loop_stmt_test.cc
@@ -13,14 +13,14 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, LoopStmt_BodyNoContinuing) {
+TEST_F(WGSLParserTest, LoopStmt_BodyNoContinuing) {
     auto p = parser("loop { discard; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -38,9 +38,9 @@
     EXPECT_EQ(e->continuing->statements.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, LoopStmt_BodyWithContinuing) {
+TEST_F(WGSLParserTest, LoopStmt_BodyWithContinuing) {
     auto p = parser("loop { discard; continuing { discard; }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -64,9 +64,9 @@
     EXPECT_EQ(e->continuing->source.range.end.column, 40u);
 }
 
-TEST_F(ParserImplTest, LoopStmt_NoBodyNoContinuing) {
+TEST_F(WGSLParserTest, LoopStmt_NoBodyNoContinuing) {
     auto p = parser("loop { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -76,9 +76,9 @@
     ASSERT_EQ(e->continuing->statements.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, LoopStmt_NoBodyWithContinuing) {
+TEST_F(WGSLParserTest, LoopStmt_NoBodyWithContinuing) {
     auto p = parser("loop { continuing { discard; }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -89,7 +89,7 @@
     EXPECT_TRUE(e->continuing->statements[0]->Is<ast::DiscardStatement>());
 }
 
-TEST_F(ParserImplTest, LoopStmt_StmtAttributes) {
+TEST_F(WGSLParserTest, LoopStmt_StmtAttributes) {
     auto p = parser("@diagnostic(off, derivative_uniformity) loop { }");
     auto attrs = p->attribute_list();
     auto l = p->loop_statement(attrs.value);
@@ -102,9 +102,9 @@
     EXPECT_TRUE(l->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, LoopStmt_BodyAttributes) {
+TEST_F(WGSLParserTest, LoopStmt_BodyAttributes) {
     auto p = parser("loop @diagnostic(off, derivative_uniformity) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -114,9 +114,9 @@
     EXPECT_TRUE(e->body->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, LoopStmt_MissingBracketLeft) {
+TEST_F(WGSLParserTest, LoopStmt_MissingBracketLeft) {
     auto p = parser("loop discard; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -125,9 +125,9 @@
     EXPECT_EQ(p->error(), "1:6: expected '{' for loop");
 }
 
-TEST_F(ParserImplTest, LoopStmt_MissingBracketRight) {
+TEST_F(WGSLParserTest, LoopStmt_MissingBracketRight) {
     auto p = parser("loop { discard; ");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -136,9 +136,9 @@
     EXPECT_EQ(p->error(), "1:17: expected '}' for loop");
 }
 
-TEST_F(ParserImplTest, LoopStmt_InvalidStatements) {
+TEST_F(WGSLParserTest, LoopStmt_InvalidStatements) {
     auto p = parser("loop { discard }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -147,9 +147,9 @@
     EXPECT_EQ(p->error(), "1:16: expected ';' for discard statement");
 }
 
-TEST_F(ParserImplTest, LoopStmt_InvalidContinuing) {
+TEST_F(WGSLParserTest, LoopStmt_InvalidContinuing) {
     auto p = parser("loop { continuing { discard }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -158,9 +158,9 @@
     EXPECT_EQ(p->error(), "1:29: expected ';' for discard statement");
 }
 
-TEST_F(ParserImplTest, LoopStmt_Continuing_BreakIf) {
+TEST_F(WGSLParserTest, LoopStmt_Continuing_BreakIf) {
     auto p = parser("loop { continuing { break if 1 + 2 < 5; }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -171,9 +171,9 @@
     EXPECT_TRUE(e->continuing->statements[0]->Is<ast::BreakIfStatement>());
 }
 
-TEST_F(ParserImplTest, LoopStmt_Continuing_BreakIf_MissingExpr) {
+TEST_F(WGSLParserTest, LoopStmt_Continuing_BreakIf_MissingExpr) {
     auto p = parser("loop { continuing { break if; }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -182,9 +182,9 @@
     EXPECT_EQ(p->error(), "1:21: expected expression for `break-if`");
 }
 
-TEST_F(ParserImplTest, LoopStmt_Continuing_BreakIf_InvalidExpr) {
+TEST_F(WGSLParserTest, LoopStmt_Continuing_BreakIf_InvalidExpr) {
     auto p = parser("loop { continuing { break if switch; }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -193,9 +193,9 @@
     EXPECT_EQ(p->error(), "1:21: expected expression for `break-if`");
 }
 
-TEST_F(ParserImplTest, LoopStmt_NoContinuing_BreakIf) {
+TEST_F(WGSLParserTest, LoopStmt_NoContinuing_BreakIf) {
     auto p = parser("loop { break if true; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -204,9 +204,9 @@
     EXPECT_EQ(p->error(), "1:14: expected ';' for break statement");
 }
 
-TEST_F(ParserImplTest, LoopStmt_Continuing_BreakIf_MissingSemicolon) {
+TEST_F(WGSLParserTest, LoopStmt_Continuing_BreakIf_MissingSemicolon) {
     auto p = parser("loop { continuing { break if 1 + 2 < 5 }}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->loop_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -216,4 +216,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_math_expression_test.cc b/src/tint/lang/wgsl/reader/parser/math_expression_test.cc
similarity index 91%
rename from src/tint/lang/wgsl/reader/parser_impl_math_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/math_expression_test.cc
index 9151a48..26d811d 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_math_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/math_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, MathExpression_Parses_Multiplicative) {
+TEST_F(WGSLParserTest, MathExpression_Parses_Multiplicative) {
     auto p = parser("a * b");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -38,7 +38,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MathExpression_Parses_Mixed_MultiplicativeStart) {
+TEST_F(WGSLParserTest, MathExpression_Parses_Mixed_MultiplicativeStart) {
     auto p = parser("a * b + c");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -73,7 +73,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MathExpression_Parses_Additive) {
+TEST_F(WGSLParserTest, MathExpression_Parses_Additive) {
     auto p = parser("a + b");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -94,7 +94,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MathExpression_Parses_Mixed_AdditiveStart) {
+TEST_F(WGSLParserTest, MathExpression_Parses_Mixed_AdditiveStart) {
     auto p = parser("a + b * c");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -129,7 +129,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("c"));
 }
 
-TEST_F(ParserImplTest, MathExpression_NoMatch_ReturnLHS) {
+TEST_F(WGSLParserTest, MathExpression_NoMatch_ReturnLHS) {
     auto p = parser("a if");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -139,7 +139,7 @@
     EXPECT_EQ(lhs.value, e.value);
 }
 
-TEST_F(ParserImplTest, MathExpression_InvalidRHS) {
+TEST_F(WGSLParserTest, MathExpression_InvalidRHS) {
     auto p = parser("a * if");
     auto lhs = p->unary_expression();
     auto e = p->expect_math_expression_post_unary_expression(lhs.value);
@@ -150,4 +150,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_multiplicative_expression_test.cc b/src/tint/lang/wgsl/reader/parser/multiplicative_expression_test.cc
similarity index 91%
rename from src/tint/lang/wgsl/reader/parser_impl_multiplicative_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/multiplicative_expression_test.cc
index c519229..f693563 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_multiplicative_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/multiplicative_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Multiply) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_Parses_Multiply) {
     auto p = parser("a * b");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -38,7 +38,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Multiply_UnaryIndirect) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_Parses_Multiply_UnaryIndirect) {
     auto p = parser("a **b");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -63,7 +63,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Divide) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_Parses_Divide) {
     auto p = parser("a / b");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -84,7 +84,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Modulo) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_Parses_Modulo) {
     auto p = parser("a % b");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -105,7 +105,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_Parses_Grouping) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_Parses_Grouping) {
     auto p = parser("a * b / c % d * e");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -162,7 +162,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_InvalidRHS) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_InvalidRHS) {
     auto p = parser("a * if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -172,7 +172,7 @@
     EXPECT_EQ(p->error(), "1:5: unable to parse right side of * expression");
 }
 
-TEST_F(ParserImplTest, MultiplicativeExpression_NoMatch_ReturnsLHS) {
+TEST_F(WGSLParserTest, MultiplicativeExpression_NoMatch_ReturnsLHS) {
     auto p = parser("a + b");
     auto lhs = p->unary_expression();
     auto e = p->expect_multiplicative_expression_post_unary_expression(lhs.value);
@@ -183,4 +183,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_param_list_test.cc b/src/tint/lang/wgsl/reader/parser/param_list_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_param_list_test.cc
rename to src/tint/lang/wgsl/reader/parser/param_list_test.cc
index 2318a13..bc58a79 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_param_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/param_list_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ParamList_Single) {
+TEST_F(WGSLParserTest, ParamList_Single) {
     auto p = parser("a : i32");
 
     auto e = p->expect_param_list();
@@ -36,7 +36,7 @@
     ASSERT_EQ(e.value[0]->source.range.end.column, 2u);
 }
 
-TEST_F(ParserImplTest, ParamList_Multiple) {
+TEST_F(WGSLParserTest, ParamList_Multiple) {
     auto p = parser("a : i32, b: f32, c: vec2<f32>");
 
     auto e = p->expect_param_list();
@@ -72,7 +72,7 @@
     ASSERT_EQ(e.value[2]->source.range.end.column, 19u);
 }
 
-TEST_F(ParserImplTest, ParamList_Empty) {
+TEST_F(WGSLParserTest, ParamList_Empty) {
     auto p = parser("");
     auto e = p->expect_param_list();
     ASSERT_FALSE(p->has_error());
@@ -80,7 +80,7 @@
     EXPECT_EQ(e.value.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, ParamList_TrailingComma) {
+TEST_F(WGSLParserTest, ParamList_TrailingComma) {
     auto p = parser("a : i32,");
     auto e = p->expect_param_list();
     ASSERT_FALSE(p->has_error());
@@ -88,7 +88,7 @@
     EXPECT_EQ(e.value.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, ParamList_Attributes) {
+TEST_F(WGSLParserTest, ParamList_Attributes) {
     auto p = parser("@builtin(position) coord : vec4<f32>, @location(1) loc1 : f32");
 
     auto e = p->expect_param_list();
@@ -128,4 +128,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_paren_expression_test.cc b/src/tint/lang/wgsl/reader/parser/paren_expression_test.cc
similarity index 81%
rename from src/tint/lang/wgsl/reader/parser_impl_paren_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/paren_expression_test.cc
index 25f1c6d..f3b19d0 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_paren_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/paren_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ParenRhsStmt) {
+TEST_F(WGSLParserTest, ParenRhsStmt) {
     auto p = parser("(a + b)");
     auto e = p->expect_paren_expression();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -26,7 +26,7 @@
     ASSERT_TRUE(e->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, ParenRhsStmt_MissingLeftParen) {
+TEST_F(WGSLParserTest, ParenRhsStmt_MissingLeftParen) {
     auto p = parser("true)");
     auto e = p->expect_paren_expression();
     ASSERT_TRUE(p->has_error());
@@ -35,7 +35,7 @@
     EXPECT_EQ(p->error(), "1:1: expected '('");
 }
 
-TEST_F(ParserImplTest, ParenRhsStmt_MissingRightParen) {
+TEST_F(WGSLParserTest, ParenRhsStmt_MissingRightParen) {
     auto p = parser("(true");
     auto e = p->expect_paren_expression();
     ASSERT_TRUE(p->has_error());
@@ -44,7 +44,7 @@
     EXPECT_EQ(p->error(), "1:6: expected ')'");
 }
 
-TEST_F(ParserImplTest, ParenRhsStmt_InvalidExpression) {
+TEST_F(WGSLParserTest, ParenRhsStmt_InvalidExpression) {
     auto p = parser("(if (a() {})");
     auto e = p->expect_paren_expression();
     ASSERT_TRUE(p->has_error());
@@ -53,7 +53,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse expression");
 }
 
-TEST_F(ParserImplTest, ParenRhsStmt_MissingExpression) {
+TEST_F(WGSLParserTest, ParenRhsStmt_MissingExpression) {
     auto p = parser("()");
     auto e = p->expect_paren_expression();
     ASSERT_TRUE(p->has_error());
@@ -63,4 +63,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl.cc b/src/tint/lang/wgsl/reader/parser/parser.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl.cc
rename to src/tint/lang/wgsl/reader/parser/parser.cc
index db7c57b..7efe47d 100644
--- a/src/tint/lang/wgsl/reader/parser_impl.cc
+++ b/src/tint/lang/wgsl/reader/parser/parser.cc
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 
 #include <limits>
 
@@ -40,27 +40,27 @@
 #include "src/tint/lang/wgsl/ast/unary_op_expression.h"
 #include "src/tint/lang/wgsl/ast/variable_decl_statement.h"
 #include "src/tint/lang/wgsl/ast/workgroup_attribute.h"
-#include "src/tint/lang/wgsl/reader/classify_template_args.h"
-#include "src/tint/lang/wgsl/reader/lexer.h"
+#include "src/tint/lang/wgsl/reader/parser/classify_template_args.h"
+#include "src/tint/lang/wgsl/reader/parser/lexer.h"
 #include "src/tint/utils/containers/reverse.h"
 #include "src/tint/utils/macros/defer.h"
 #include "src/tint/utils/text/string.h"
 #include "src/tint/utils/text/string_stream.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using Void = ParserImpl::Void;
+using Void = Parser::Void;
 
 /// An instance of Void that can be used to signal success for functions that return Expect<Void> or
 /// Maybe<NoError>.
 static constexpr Void kSuccess;
 
 template <typename T>
-using Expect = ParserImpl::Expect<T>;
+using Expect = Parser::Expect<T>;
 
 template <typename T>
-using Maybe = ParserImpl::Maybe<T>;
+using Maybe = Parser::Maybe<T>;
 
 /// Controls the maximum number of times we'll call into the sync() and
 /// unary_expression() functions from themselves. This is to guard against stack
@@ -146,18 +146,17 @@
 
 /// RAII helper that combines a Source on construction with the last token's
 /// source when implicitly converted to `Source`.
-class ParserImpl::MultiTokenSource {
+class Parser::MultiTokenSource {
   public:
     /// Constructor that starts with Source at the current peek position
     /// @param parser the parser
-    explicit MultiTokenSource(ParserImpl* parser)
+    explicit MultiTokenSource(Parser* parser)
         : MultiTokenSource(parser, parser->peek().source().Begin()) {}
 
     /// Constructor that starts with the input `start` Source
     /// @param parser the parser
     /// @param start the start source of the range
-    MultiTokenSource(ParserImpl* parser, const tint::Source& start)
-        : parser_(parser), start_(start) {}
+    MultiTokenSource(Parser* parser, const tint::Source& start) : parser_(parser), start_(start) {}
 
     /// @returns the Source that returns the combined source from start to the current last token's
     /// source.
@@ -174,46 +173,45 @@
     operator tint::Source() const { return Source(); }
 
   private:
-    ParserImpl* parser_;
+    Parser* parser_;
     tint::Source start_;
 };
 
-ParserImpl::TypedIdentifier::TypedIdentifier() = default;
+Parser::TypedIdentifier::TypedIdentifier() = default;
 
-ParserImpl::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default;
+Parser::TypedIdentifier::TypedIdentifier(const TypedIdentifier&) = default;
 
-ParserImpl::TypedIdentifier::TypedIdentifier(ast::Type type_in, const ast::Identifier* name_in)
+Parser::TypedIdentifier::TypedIdentifier(ast::Type type_in, const ast::Identifier* name_in)
     : type(type_in), name(name_in) {}
 
-ParserImpl::TypedIdentifier::~TypedIdentifier() = default;
+Parser::TypedIdentifier::~TypedIdentifier() = default;
 
-ParserImpl::FunctionHeader::FunctionHeader() = default;
+Parser::FunctionHeader::FunctionHeader() = default;
 
-ParserImpl::FunctionHeader::FunctionHeader(const FunctionHeader&) = default;
+Parser::FunctionHeader::FunctionHeader(const FunctionHeader&) = default;
 
-ParserImpl::FunctionHeader::FunctionHeader(Source src,
-                                           const ast::Identifier* n,
-                                           utils::VectorRef<const ast::Parameter*> p,
-                                           ast::Type ret_ty,
-                                           utils::VectorRef<const ast::Attribute*> ret_attrs)
+Parser::FunctionHeader::FunctionHeader(Source src,
+                                       const ast::Identifier* n,
+                                       utils::VectorRef<const ast::Parameter*> p,
+                                       ast::Type ret_ty,
+                                       utils::VectorRef<const ast::Attribute*> ret_attrs)
     : source(src),
       name(n),
       params(std::move(p)),
       return_type(ret_ty),
       return_type_attributes(std::move(ret_attrs)) {}
 
-ParserImpl::FunctionHeader::~FunctionHeader() = default;
+Parser::FunctionHeader::~FunctionHeader() = default;
 
-ParserImpl::FunctionHeader& ParserImpl::FunctionHeader::operator=(const FunctionHeader& rhs) =
-    default;
+Parser::FunctionHeader& Parser::FunctionHeader::operator=(const FunctionHeader& rhs) = default;
 
-ParserImpl::ParserImpl(Source::File const* file) : file_(file) {}
+Parser::Parser(Source::File const* file) : file_(file) {}
 
-ParserImpl::~ParserImpl() = default;
+Parser::~Parser() = default;
 
-ParserImpl::Failure::Errored ParserImpl::add_error(const Source& source,
-                                                   std::string_view err,
-                                                   std::string_view use) {
+Parser::Failure::Errored Parser::add_error(const Source& source,
+                                           std::string_view err,
+                                           std::string_view use) {
     if (silence_diags_ == 0) {
         utils::StringStream msg;
         msg << err;
@@ -225,25 +223,25 @@
     return Failure::kErrored;
 }
 
-ParserImpl::Failure::Errored ParserImpl::add_error(const Token& t, std::string_view err) {
+Parser::Failure::Errored Parser::add_error(const Token& t, std::string_view err) {
     add_error(t.source(), err);
     return Failure::kErrored;
 }
 
-ParserImpl::Failure::Errored ParserImpl::add_error(const Source& source, std::string_view err) {
+Parser::Failure::Errored Parser::add_error(const Source& source, std::string_view err) {
     if (silence_diags_ == 0) {
         builder_.Diagnostics().add_error(diag::System::Reader, err, source);
     }
     return Failure::kErrored;
 }
 
-void ParserImpl::add_note(const Source& source, std::string_view err) {
+void Parser::add_note(const Source& source, std::string_view err) {
     if (silence_diags_ == 0) {
         builder_.Diagnostics().add_note(diag::System::Reader, err, source);
     }
 }
 
-void ParserImpl::deprecated(const Source& source, std::string_view msg) {
+void Parser::deprecated(const Source& source, std::string_view msg) {
     if (silence_diags_ == 0) {
         builder_.Diagnostics().add_warning(
             diag::System::Reader, "use of deprecated language feature: " + std::string(msg),
@@ -251,7 +249,7 @@
     }
 }
 
-const Token& ParserImpl::next() {
+const Token& Parser::next() {
     // If the next token is already an error or the end of file, stay there.
     if (tokens_[next_token_idx_].IsEof() || tokens_[next_token_idx_].IsError()) {
         return tokens_[next_token_idx_];
@@ -272,7 +270,7 @@
     return tokens_[last_source_idx_];
 }
 
-const Token& ParserImpl::peek(size_t count) {
+const Token& Parser::peek(size_t count) {
     for (size_t idx = next_token_idx_; idx < tokens_.size(); idx++) {
         if (tokens_[idx].IsPlaceholder()) {
             continue;
@@ -286,11 +284,11 @@
     return tokens_[tokens_.size() - 1];
 }
 
-bool ParserImpl::peek_is(Token::Type tok, size_t idx) {
+bool Parser::peek_is(Token::Type tok, size_t idx) {
     return peek(idx).Is(tok);
 }
 
-void ParserImpl::split_token(Token::Type lhs, Token::Type rhs) {
+void Parser::split_token(Token::Type lhs, Token::Type rhs) {
     if (TINT_UNLIKELY(next_token_idx_ == 0)) {
         TINT_ICE(Reader, builder_.Diagnostics())
             << "attempt to update placeholder at beginning of tokens";
@@ -306,17 +304,17 @@
     tokens_[next_token_idx_].SetType(rhs);
 }
 
-Source ParserImpl::last_source() const {
+Source Parser::last_source() const {
     return tokens_[last_source_idx_].source();
 }
 
-void ParserImpl::InitializeLex() {
+void Parser::InitializeLex() {
     Lexer l{file_};
     tokens_ = l.Lex();
     ClassifyTemplateArguments(tokens_);
 }
 
-bool ParserImpl::Parse() {
+bool Parser::Parse() {
     InitializeLex();
     translation_unit();
     return !has_error();
@@ -324,7 +322,7 @@
 
 // translation_unit
 //  : global_directive* global_decl* EOF
-void ParserImpl::translation_unit() {
+void Parser::translation_unit() {
     bool after_global_decl = false;
     while (continue_parsing()) {
         auto& p = peek();
@@ -356,7 +354,7 @@
 //  : diagnostic_directive
 //  | requires_directive
 //  | enable_directive
-Maybe<Void> ParserImpl::global_directive(bool have_parsed_decl) {
+Maybe<Void> Parser::global_directive(bool have_parsed_decl) {
     auto& p = peek();
     Maybe<Void> result = diagnostic_directive();
     if (!result.errored && !result.matched) {
@@ -374,7 +372,7 @@
 
 // diagnostic_directive
 //  : diagnostic diagnostic_control SEMICOLON
-Maybe<Void> ParserImpl::diagnostic_directive() {
+Maybe<Void> Parser::diagnostic_directive() {
     auto decl = sync(Token::Type::kSemicolon, [&]() -> Maybe<Void> {
         if (!match(Token::Type::kDiagnostic)) {
             return Failure::kNoMatch;
@@ -404,7 +402,7 @@
 
 // enable_directive :
 // | 'enable' identifier (COMMA identifier)* COMMA? SEMICOLON
-Maybe<Void> ParserImpl::enable_directive() {
+Maybe<Void> Parser::enable_directive() {
     return sync(Token::Type::kSemicolon, [&]() -> Maybe<Void> {
         MultiTokenSource decl_source(this);
         if (!match(Token::Type::kEnable)) {
@@ -446,7 +444,7 @@
 
 // requires_directive
 //  : require identifier (COMMA identifier)* COMMA? SEMICOLON
-Maybe<Void> ParserImpl::requires_directive() {
+Maybe<Void> Parser::requires_directive() {
     return sync(Token::Type::kSemicolon, [&]() -> Maybe<Void> {
         if (!match(Token::Type::kRequires)) {
             return Failure::kNoMatch;
@@ -504,7 +502,7 @@
 //  | struct_decl
 //  | function_decl
 //  | const_assert_statement SEMICOLON
-Maybe<Void> ParserImpl::global_decl() {
+Maybe<Void> Parser::global_decl() {
     if (match(Token::Type::kSemicolon) || match(Token::Type::kEOF)) {
         return kSuccess;
     }
@@ -643,7 +641,7 @@
 
 // global_variable_decl
 //  : variable_attribute_list* variable_decl (EQUAL expression)?
-Maybe<const ast::Variable*> ParserImpl::global_variable_decl(AttributeList& attrs) {
+Maybe<const ast::Variable*> Parser::global_variable_decl(AttributeList& attrs) {
     auto decl = variable_decl();
     if (decl.errored) {
         return Failure::kErrored;
@@ -680,7 +678,7 @@
 //  | attribute* override optionally_typed_ident (equal expression)?
 // global_const_initializer
 //  : EQUAL const_expr
-Maybe<const ast::Variable*> ParserImpl::global_constant_decl(AttributeList& attrs) {
+Maybe<const ast::Variable*> Parser::global_constant_decl(AttributeList& attrs) {
     bool is_overridable = false;
     const char* use = nullptr;
     Source source;
@@ -742,7 +740,7 @@
 //
 // Note, the `( LESS_THAN address_space ( COMMA access_mode )? GREATER_THAN ) is pulled out into
 // a `variable_qualifier` helper.
-Maybe<ParserImpl::VarDeclInfo> ParserImpl::variable_decl() {
+Maybe<Parser::VarDeclInfo> Parser::variable_decl() {
     Source source;
     if (!match(Token::Type::kVar, &source)) {
         return Failure::kNoMatch;
@@ -765,7 +763,7 @@
     return VarDeclInfo{decl->name->source, decl->name, vq.address_space, vq.access, decl->type};
 }
 
-Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_optional_type_specifier(
+Expect<Parser::TypedIdentifier> Parser::expect_ident_with_optional_type_specifier(
     std::string_view use,
     bool allow_inferred) {
     auto ident = expect_ident(use);
@@ -795,21 +793,19 @@
 
 // optionally_typed_ident
 //   : ident ( COLON typed_decl ) ?
-Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_optionally_typed_ident(
-    std::string_view use) {
+Expect<Parser::TypedIdentifier> Parser::expect_optionally_typed_ident(std::string_view use) {
     return expect_ident_with_optional_type_specifier(use, /* allow_inferred */ true);
 }
 
 // ident_with_type_specifier
 //   : IDENT COLON type_specifier
-Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_ident_with_type_specifier(
-    std::string_view use) {
+Expect<Parser::TypedIdentifier> Parser::expect_ident_with_type_specifier(std::string_view use) {
     return expect_ident_with_optional_type_specifier(use, /* allow_inferred */ false);
 }
 
 // variable_qualifier
 //   : _template_args_start expression (COMMA expression)? _template_args_end
-Maybe<ParserImpl::VariableQualifier> ParserImpl::variable_qualifier() {
+Maybe<Parser::VariableQualifier> Parser::variable_qualifier() {
     if (!peek_is(Token::Type::kTemplateArgsLeft) && !peek_is(Token::Type::kLessThan)) {
         // Note: kLessThan will give a sensible error at expect_template_arg_block()
         return Failure::kNoMatch;
@@ -840,7 +836,7 @@
 
 // type_alias_decl
 //   : ALIAS IDENT EQUAL type_specifier
-Maybe<const ast::Alias*> ParserImpl::type_alias_decl() {
+Maybe<const ast::Alias*> Parser::type_alias_decl() {
     Source source;
     if (!match(Token::Type::kAlias, &source)) {
         return Failure::kNoMatch;
@@ -870,7 +866,7 @@
 
 // type_specifier
 //   : IDENTIFIER template_arguments?
-Maybe<ast::Type> ParserImpl::type_specifier() {
+Maybe<ast::Type> Parser::type_specifier() {
     MultiTokenSource source(this);
     auto& ident = peek();
     if (!match(Token::Type::kIdentifier)) {
@@ -892,10 +888,10 @@
 }
 
 template <typename ENUM, size_t N>
-Expect<ENUM> ParserImpl::expect_enum(std::string_view name,
-                                     ENUM (*parse)(std::string_view str),
-                                     const char* const (&strings)[N],
-                                     std::string_view use) {
+Expect<ENUM> Parser::expect_enum(std::string_view name,
+                                 ENUM (*parse)(std::string_view str),
+                                 const char* const (&strings)[N],
+                                 std::string_view use) {
     auto& t = peek();
     if (t.IsIdentifier()) {
         auto val = parse(t.to_str());
@@ -926,7 +922,7 @@
     return add_error(t.source(), err.str());
 }
 
-Expect<ast::Type> ParserImpl::expect_type(std::string_view use) {
+Expect<ast::Type> Parser::expect_type(std::string_view use) {
     auto type = type_specifier();
     if (type.errored) {
         return Failure::kErrored;
@@ -939,7 +935,7 @@
 
 // struct_decl
 //   : STRUCT IDENT struct_body_decl
-Maybe<const ast::Struct*> ParserImpl::struct_decl() {
+Maybe<const ast::Struct*> Parser::struct_decl() {
     auto& t = peek();
 
     if (!match(Token::Type::kStruct)) {
@@ -961,7 +957,7 @@
 
 // struct_body_decl
 //   : BRACE_LEFT (struct_member COMMA)* struct_member COMMA? BRACE_RIGHT
-Expect<ParserImpl::StructMemberList> ParserImpl::expect_struct_body_decl() {
+Expect<Parser::StructMemberList> Parser::expect_struct_body_decl() {
     return expect_brace_block("struct declaration", [&]() -> Expect<StructMemberList> {
         StructMemberList members;
         bool errored = false;
@@ -995,7 +991,7 @@
 
 // struct_member
 //   : attribute* ident_with_type_specifier
-Expect<const ast::StructMember*> ParserImpl::expect_struct_member() {
+Expect<const ast::StructMember*> Parser::expect_struct_member() {
     auto attrs = attribute_list();
     if (attrs.errored) {
         return Failure::kErrored;
@@ -1011,7 +1007,7 @@
 
 // const_assert_statement
 //   : STATIC_ASSERT expression
-Maybe<const ast::ConstAssert*> ParserImpl::const_assert_statement() {
+Maybe<const ast::ConstAssert*> Parser::const_assert_statement() {
     Source start;
     if (!match(Token::Type::kConstAssert, &start)) {
         return Failure::kNoMatch;
@@ -1031,7 +1027,7 @@
 
 // function_decl
 //   : function_header compound_statement
-Maybe<const ast::Function*> ParserImpl::function_decl(AttributeList& attrs) {
+Maybe<const ast::Function*> Parser::function_decl(AttributeList& attrs) {
     auto header = function_header();
     if (header.errored) {
         if (sync_to(Token::Type::kBraceLeft, /* consume: */ false)) {
@@ -1071,7 +1067,7 @@
 // return_type_specifier_optional
 //   :
 //   | ARROW attribute_list* type_specifier
-Maybe<ParserImpl::FunctionHeader> ParserImpl::function_header() {
+Maybe<Parser::FunctionHeader> Parser::function_header() {
     Source source;
     if (!match(Token::Type::kFn, &source)) {
         return Failure::kNoMatch;
@@ -1130,7 +1126,7 @@
 // param_list
 //   :
 //   | (param COMMA)* param COMMA?
-Expect<ParserImpl::ParameterList> ParserImpl::expect_param_list() {
+Expect<Parser::ParameterList> Parser::expect_param_list() {
     ParameterList ret;
     while (continue_parsing()) {
         // Check for the end of the list.
@@ -1155,7 +1151,7 @@
 
 // param
 //   : attribute_list* ident COLON type_specifier
-Expect<const ast::Parameter*> ParserImpl::expect_param() {
+Expect<const ast::Parameter*> Parser::expect_param() {
     auto attrs = attribute_list();
 
     auto decl = expect_ident_with_type_specifier("parameter");
@@ -1171,7 +1167,7 @@
 
 // compound_statement
 //   : attribute* BRACE_LEFT statement* BRACE_RIGHT
-Expect<ast::BlockStatement*> ParserImpl::expect_compound_statement(std::string_view use) {
+Expect<ast::BlockStatement*> Parser::expect_compound_statement(std::string_view use) {
     auto attrs = attribute_list();
     if (attrs.errored) {
         return Failure::kErrored;
@@ -1181,8 +1177,8 @@
 
 // compound_statement
 //   : attribute* BRACE_LEFT statement* BRACE_RIGHT
-Expect<ast::BlockStatement*> ParserImpl::expect_compound_statement(AttributeList& attrs,
-                                                                   std::string_view use) {
+Expect<ast::BlockStatement*> Parser::expect_compound_statement(AttributeList& attrs,
+                                                               std::string_view use) {
     auto source_start = peek().source();
     auto stmts =
         expect_brace_block(use, [&]() -> Expect<StatementList> { return expect_statements(); });
@@ -1197,7 +1193,7 @@
 
 // paren_expression
 //   : PAREN_LEFT expression PAREN_RIGHT
-Expect<const ast::Expression*> ParserImpl::expect_paren_expression() {
+Expect<const ast::Expression*> Parser::expect_paren_expression() {
     return expect_paren_block("", [&]() -> Expect<const ast::Expression*> {
         auto expr = expression();
         if (expr.errored) {
@@ -1213,7 +1209,7 @@
 
 // statements
 //   : statement*
-Expect<ParserImpl::StatementList> ParserImpl::expect_statements() {
+Expect<Parser::StatementList> Parser::expect_statements() {
     bool errored = false;
     StatementList stmts;
 
@@ -1244,7 +1240,7 @@
 //   | while_statement
 //   | compound_statement
 //   | non_block_statement   // Note, we inject an extra rule in here for simpler parsing
-Maybe<const ast::Statement*> ParserImpl::statement() {
+Maybe<const ast::Statement*> Parser::statement() {
     while (match(Token::Type::kSemicolon)) {
         // Skip empty statements
     }
@@ -1324,7 +1320,7 @@
 //   | DISCARD SEMICOLON
 //   | variable_updating_statement SEMICOLON
 //   | const_assert_statement SEMICOLON
-Maybe<const ast::Statement*> ParserImpl::non_block_statement() {
+Maybe<const ast::Statement*> Parser::non_block_statement() {
     auto stmt = [&]() -> Maybe<const ast::Statement*> {
         auto ret_stmt = return_statement();
         if (ret_stmt.errored) {
@@ -1399,7 +1395,7 @@
 
 // return_statement
 //   : RETURN expression?
-Maybe<const ast::ReturnStatement*> ParserImpl::return_statement() {
+Maybe<const ast::ReturnStatement*> Parser::return_statement() {
     Source source;
     if (!match(Token::Type::kReturn, &source)) {
         return Failure::kNoMatch;
@@ -1423,7 +1419,7 @@
 //   | variable_decl EQUAL expression
 //   | LET optionally_typed_ident EQUAL expression
 //   | CONST optionally_typed_ident EQUAL expression
-Maybe<const ast::VariableDeclStatement*> ParserImpl::variable_statement() {
+Maybe<const ast::VariableDeclStatement*> Parser::variable_statement() {
     auto decl_source_range = make_source_range();
     if (match(Token::Type::kConst)) {
         auto typed_ident = expect_optionally_typed_ident("'const' declaration");
@@ -1523,7 +1519,7 @@
 //   : ELSE IF expression compound_stmt
 // else_clause
 //   : ELSE compound_statement
-Maybe<const ast::IfStatement*> ParserImpl::if_statement(AttributeList& attrs) {
+Maybe<const ast::IfStatement*> Parser::if_statement(AttributeList& attrs) {
     // Parse if-else chains iteratively instead of recursively, to avoid
     // stack-overflow for long chains of if-else statements.
 
@@ -1605,7 +1601,7 @@
 
 // switch_statement
 //   : attribute* SWITCH expression BRACKET_LEFT switch_body+ BRACKET_RIGHT
-Maybe<const ast::SwitchStatement*> ParserImpl::switch_statement(AttributeList& attrs) {
+Maybe<const ast::SwitchStatement*> Parser::switch_statement(AttributeList& attrs) {
     Source source;
     if (!match(Token::Type::kSwitch, &source)) {
         return Failure::kNoMatch;
@@ -1656,7 +1652,7 @@
 // switch_body
 //   : CASE case_selectors COLON? compound_statement
 //   | DEFAULT COLON? compound_statement
-Maybe<const ast::CaseStatement*> ParserImpl::switch_body() {
+Maybe<const ast::CaseStatement*> Parser::switch_body() {
     if (!peek_is(Token::Type::kCase) && !peek_is(Token::Type::kDefault)) {
         return Failure::kNoMatch;
     }
@@ -1690,7 +1686,7 @@
 
 // case_selectors
 //   : case_selector (COMMA case_selector)* COMMA?
-Expect<ParserImpl::CaseSelectorList> ParserImpl::expect_case_selectors() {
+Expect<Parser::CaseSelectorList> Parser::expect_case_selectors() {
     CaseSelectorList selectors;
 
     while (continue_parsing()) {
@@ -1718,7 +1714,7 @@
 // case_selector
 //   : DEFAULT
 //   | expression
-Maybe<const ast::CaseSelector*> ParserImpl::case_selector() {
+Maybe<const ast::CaseSelector*> Parser::case_selector() {
     auto& p = peek();
 
     if (match(Token::Type::kDefault)) {
@@ -1737,7 +1733,7 @@
 
 // loop_statement
 //   : attribute* LOOP attribute* BRACKET_LEFT statements continuing_statement? BRACKET_RIGHT
-Maybe<const ast::LoopStatement*> ParserImpl::loop_statement(AttributeList& attrs) {
+Maybe<const ast::LoopStatement*> Parser::loop_statement(AttributeList& attrs) {
     Source source;
     if (!match(Token::Type::kLoop, &source)) {
         return Failure::kNoMatch;
@@ -1783,7 +1779,7 @@
 ForHeader::~ForHeader() = default;
 
 // (variable_statement | variable_updating_statement | func_call_statement)?
-Maybe<const ast::Statement*> ParserImpl::for_header_initializer() {
+Maybe<const ast::Statement*> Parser::for_header_initializer() {
     auto call = func_call_statement();
     if (call.errored) {
         return Failure::kErrored;
@@ -1812,7 +1808,7 @@
 }
 
 // (variable_updating_statement | func_call_statement)?
-Maybe<const ast::Statement*> ParserImpl::for_header_continuing() {
+Maybe<const ast::Statement*> Parser::for_header_continuing() {
     auto call_stmt = func_call_statement();
     if (call_stmt.errored) {
         return Failure::kErrored;
@@ -1834,7 +1830,7 @@
 
 // for_header
 //   : for_header_initializer? SEMICOLON expression? SEMICOLON for_header_continuing?
-Expect<std::unique_ptr<ForHeader>> ParserImpl::expect_for_header() {
+Expect<std::unique_ptr<ForHeader>> Parser::expect_for_header() {
     auto initializer = for_header_initializer();
     if (initializer.errored) {
         return Failure::kErrored;
@@ -1863,7 +1859,7 @@
 
 // for_statement
 //   : FOR PAREN_LEFT for_header PAREN_RIGHT compound_statement
-Maybe<const ast::ForLoopStatement*> ParserImpl::for_statement(AttributeList& attrs) {
+Maybe<const ast::ForLoopStatement*> Parser::for_statement(AttributeList& attrs) {
     Source source;
     if (!match(Token::Type::kFor, &source)) {
         return Failure::kNoMatch;
@@ -1886,7 +1882,7 @@
 
 // while_statement
 //   :  attribute* WHILE expression compound_statement
-Maybe<const ast::WhileStatement*> ParserImpl::while_statement(AttributeList& attrs) {
+Maybe<const ast::WhileStatement*> Parser::while_statement(AttributeList& attrs) {
     Source source;
     if (!match(Token::Type::kWhile, &source)) {
         return Failure::kNoMatch;
@@ -1911,7 +1907,7 @@
 
 // func_call_statement
 //    : IDENT argument_expression_list
-Maybe<const ast::CallStatement*> ParserImpl::func_call_statement() {
+Maybe<const ast::CallStatement*> Parser::func_call_statement() {
     auto& t = peek();
     auto& t2 = peek(1);
     if (!t.IsIdentifier() || !t2.Is(Token::Type::kParenLeft)) {
@@ -1932,7 +1928,7 @@
 
 // break_statement
 //   : BREAK
-Maybe<const ast::BreakStatement*> ParserImpl::break_statement() {
+Maybe<const ast::BreakStatement*> Parser::break_statement() {
     Source source;
     if (!match(Token::Type::kBreak, &source)) {
         return Failure::kNoMatch;
@@ -1943,7 +1939,7 @@
 
 // continue_statement
 //   : CONTINUE
-Maybe<const ast::ContinueStatement*> ParserImpl::continue_statement() {
+Maybe<const ast::ContinueStatement*> Parser::continue_statement() {
     Source source;
     if (!match(Token::Type::kContinue, &source)) {
         return Failure::kNoMatch;
@@ -1954,7 +1950,7 @@
 
 // break_if_statement:
 //    'break' 'if' expression semicolon
-Maybe<const ast::Statement*> ParserImpl::break_if_statement() {
+Maybe<const ast::Statement*> Parser::break_if_statement() {
     auto& t1 = peek();
     auto& t2 = peek(1);
 
@@ -1981,7 +1977,7 @@
 
 // continuing_compound_statement:
 //   attribute* BRACE_LEFT statement* break_if_statement? BRACE_RIGHT
-Maybe<const ast::BlockStatement*> ParserImpl::continuing_compound_statement() {
+Maybe<const ast::BlockStatement*> Parser::continuing_compound_statement() {
     auto attrs = attribute_list();
     if (attrs.errored) {
         return Failure::kErrored;
@@ -2025,7 +2021,7 @@
 
 // continuing_statement
 //   : CONTINUING continuing_compound_statement
-Maybe<const ast::BlockStatement*> ParserImpl::continuing_statement() {
+Maybe<const ast::BlockStatement*> Parser::continuing_statement() {
     if (!match(Token::Type::kContinuing)) {
         return create<ast::BlockStatement>(Source{}, utils::Empty, utils::Empty);
     }
@@ -2041,7 +2037,7 @@
 //
 // Note, PAREN_LEFT ( expression ( COMMA expression ) * COMMA? )? PAREN_RIGHT is replaced
 // with `argument_expression_list`.
-Maybe<const ast::Expression*> ParserImpl::primary_expression() {
+Maybe<const ast::Expression*> Parser::primary_expression() {
     auto& t = peek();
 
     if (match(Token::Type::kBitcast)) {
@@ -2113,7 +2109,7 @@
 //   | BRACE_LEFT expression BRACE_RIGHT component_or_swizzle_specifier?
 //   | PERIOD member_ident component_or_swizzle_specifier?
 //   | PERIOD swizzle_name component_or_swizzle_specifier?
-Maybe<const ast::Expression*> ParserImpl::component_or_swizzle_specifier(
+Maybe<const ast::Expression*> Parser::component_or_swizzle_specifier(
     const ast::Expression* prefix) {
     MultiTokenSource source(this, prefix->source);
 
@@ -2160,9 +2156,8 @@
 
 // argument_expression_list
 //   : PAREN_LEFT ((expression COMMA)* expression COMMA?)? PAREN_RIGHT
-Expect<ParserImpl::ExpressionList> ParserImpl::expect_argument_expression_list(
-    std::string_view use) {
-    return expect_paren_block(use, [&]() -> Expect<ParserImpl::ExpressionList> {  //
+Expect<Parser::ExpressionList> Parser::expect_argument_expression_list(std::string_view use) {
+    return expect_paren_block(use, [&]() -> Expect<Parser::ExpressionList> {  //
         auto list = expression_list(use, Token::Type::kParenRight);
         if (list.errored) {
             return Failure::kErrored;
@@ -2175,7 +2170,7 @@
 //   : AND unary_expression (AND unary_expression)*
 //   | OR unary_expression (OR unary_expression)*
 //   | XOR unary_expression (XOR unary_expression)*
-Maybe<const ast::Expression*> ParserImpl::bitwise_expression_post_unary_expression(
+Maybe<const ast::Expression*> Parser::bitwise_expression_post_unary_expression(
     const ast::Expression* lhs) {
     auto& t = peek();
 
@@ -2218,7 +2213,7 @@
 //   : FORWARD_SLASH
 //   | MODULO
 //   | STAR
-Maybe<ast::BinaryOp> ParserImpl::multiplicative_operator() {
+Maybe<ast::BinaryOp> Parser::multiplicative_operator() {
     if (match(Token::Type::kForwardSlash)) {
         return ast::BinaryOp::kDivide;
     }
@@ -2234,7 +2229,7 @@
 
 // multiplicative_expression.post.unary_expression
 //   : (multiplicative_operator unary_expression)*
-Expect<const ast::Expression*> ParserImpl::expect_multiplicative_expression_post_unary_expression(
+Expect<const ast::Expression*> Parser::expect_multiplicative_expression_post_unary_expression(
     const ast::Expression* lhs) {
     while (continue_parsing()) {
         auto& t = peek();
@@ -2267,7 +2262,7 @@
 //
 // Note, this also splits a `--` token. This is currently safe as the only way to get into
 // here is through additive expression and rules for where `--` are allowed are very restrictive.
-Maybe<ast::BinaryOp> ParserImpl::additive_operator() {
+Maybe<ast::BinaryOp> Parser::additive_operator() {
     if (match(Token::Type::kPlus)) {
         return ast::BinaryOp::kAdd;
     }
@@ -2290,7 +2285,7 @@
 //
 // This is `( additive_operator unary_expression ( multiplicative_operator unary_expression )* )*`
 // split apart.
-Expect<const ast::Expression*> ParserImpl::expect_additive_expression_post_unary_expression(
+Expect<const ast::Expression*> Parser::expect_additive_expression_post_unary_expression(
     const ast::Expression* lhs) {
     while (continue_parsing()) {
         auto& t = peek();
@@ -2329,7 +2324,7 @@
 //
 // This is `( multiplicative_operator unary_expression )* ( additive_operator unary_expression (
 // multiplicative_operator unary_expression )* )*` split apart.
-Expect<const ast::Expression*> ParserImpl::expect_math_expression_post_unary_expression(
+Expect<const ast::Expression*> Parser::expect_math_expression_post_unary_expression(
     const ast::Expression* lhs) {
     auto rhs = expect_multiplicative_expression_post_unary_expression(lhs);
     if (rhs.errored) {
@@ -2341,7 +2336,7 @@
 
 // shift_expression
 //   : unary_expression shift_expression.post.unary_expression
-Maybe<const ast::Expression*> ParserImpl::shift_expression() {
+Maybe<const ast::Expression*> Parser::shift_expression() {
     auto lhs = unary_expression();
     if (lhs.errored) {
         return Failure::kErrored;
@@ -2359,7 +2354,7 @@
 //
 // Note, add the `math_expression.post.unary_expression` is added here to make
 // implementation simpler.
-Expect<const ast::Expression*> ParserImpl::expect_shift_expression_post_unary_expression(
+Expect<const ast::Expression*> Parser::expect_shift_expression_post_unary_expression(
     const ast::Expression* lhs) {
     auto& t = peek();
     if (match(Token::Type::kShiftLeft) || match(Token::Type::kShiftRight)) {
@@ -2390,7 +2385,7 @@
 
 // relational_expression
 //   : unary_expression relational_expression.post.unary_expression
-Maybe<const ast::Expression*> ParserImpl::relational_expression() {
+Maybe<const ast::Expression*> Parser::relational_expression() {
     auto lhs = unary_expression();
     if (lhs.errored) {
         return Failure::kErrored;
@@ -2411,7 +2406,7 @@
 //   | shift_expression.post.unary_expression NOT_EQUAL shift_expression
 //
 // Note, a `shift_expression` element was added to simplify many of the right sides
-Expect<const ast::Expression*> ParserImpl::expect_relational_expression_post_unary_expression(
+Expect<const ast::Expression*> Parser::expect_relational_expression_post_unary_expression(
     const ast::Expression* lhs) {
     auto lhs_result = expect_shift_expression_post_unary_expression(lhs);
     if (lhs_result.errored) {
@@ -2460,7 +2455,7 @@
     return create<ast::BinaryExpression>(tok_op.source(), op, lhs, rhs.value);
 }
 
-Expect<const ast::Expression*> ParserImpl::expect_expression(std::string_view use) {
+Expect<const ast::Expression*> Parser::expect_expression(std::string_view use) {
     auto& t = peek();
     auto expr = expression();
     if (expr.errored) {
@@ -2472,8 +2467,8 @@
     return add_error(t, "expected expression for " + std::string(use));
 }
 
-Maybe<ParserImpl::ExpressionList> ParserImpl::expression_list(std::string_view use,
-                                                              Token::Type terminator) {
+Maybe<Parser::ExpressionList> Parser::expression_list(std::string_view use,
+                                                      Token::Type terminator) {
     if (peek_is(terminator)) {
         return Failure::kNoMatch;
     }
@@ -2484,9 +2479,9 @@
     return list.value;
 }
 
-Expect<ParserImpl::ExpressionList> ParserImpl::expect_expression_list(std::string_view use,
-                                                                      Token::Type terminator) {
-    ParserImpl::ExpressionList exprs;
+Expect<Parser::ExpressionList> Parser::expect_expression_list(std::string_view use,
+                                                              Token::Type terminator) {
+    Parser::ExpressionList exprs;
     while (continue_parsing()) {
         auto expr = expect_expression(use);
         if (expr.errored) {
@@ -2530,7 +2525,7 @@
 //        relational_expression ( or_or relational_expression )*
 //
 // Note, a `relational_expression` element was added to simplify many of the right sides
-Maybe<const ast::Expression*> ParserImpl::expression() {
+Maybe<const ast::Expression*> Parser::expression() {
     auto expr = [&]() -> Maybe<const ast::Expression*> {
         auto lhs = unary_expression();
         if (lhs.errored) {
@@ -2604,7 +2599,7 @@
 
 // singular_expression
 //   : primary_expression postfix_expr
-Maybe<const ast::Expression*> ParserImpl::singular_expression() {
+Maybe<const ast::Expression*> Parser::singular_expression() {
     auto prefix = primary_expression();
     if (prefix.errored) {
         return Failure::kErrored;
@@ -2626,7 +2621,7 @@
 //
 // The `primary_expression component_or_swizzle_specifier ?` is moved out into a
 // `singular_expression`
-Maybe<const ast::Expression*> ParserImpl::unary_expression() {
+Maybe<const ast::Expression*> Parser::unary_expression() {
     auto& t = peek();
 
     if (match(Token::Type::kPlusPlus) || match(Token::Type::kMinusMinus)) {
@@ -2685,7 +2680,7 @@
 //   | xor_equal
 //   | shift_right_equal
 //   | shift_left_equal
-Maybe<ast::BinaryOp> ParserImpl::compound_assignment_operator() {
+Maybe<ast::BinaryOp> Parser::compound_assignment_operator() {
     ast::BinaryOp compound_op = ast::BinaryOp::kNone;
     if (peek_is(Token::Type::kPlusEqual)) {
         compound_op = ast::BinaryOp::kAdd;
@@ -2718,7 +2713,7 @@
 // core_lhs_expression
 //   : ident
 //   | PAREN_LEFT lhs_expression PAREN_RIGHT
-Maybe<const ast::Expression*> ParserImpl::core_lhs_expression() {
+Maybe<const ast::Expression*> Parser::core_lhs_expression() {
     auto& t = peek();
     if (t.IsIdentifier()) {
         next();
@@ -2746,7 +2741,7 @@
 //   : core_lhs_expression component_or_swizzle_specifier ?
 //   | AND lhs_expression
 //   | STAR lhs_expression
-Maybe<const ast::Expression*> ParserImpl::lhs_expression() {
+Maybe<const ast::Expression*> Parser::lhs_expression() {
     auto core_expr = core_lhs_expression();
     if (core_expr.errored) {
         return Failure::kErrored;
@@ -2809,7 +2804,7 @@
 //
 // Note, this is a simplification of the recursive grammar statement with the `lhs_expression`
 // substituted back into the expression.
-Maybe<const ast::Statement*> ParserImpl::variable_updating_statement() {
+Maybe<const ast::Statement*> Parser::variable_updating_statement() {
     auto& t = peek();
 
     // tint:295 - Test for `ident COLON` - this is invalid grammar, and without
@@ -2887,7 +2882,7 @@
 // bool_literal
 //   : TRUE
 //   | FALSE
-Maybe<const ast::LiteralExpression*> ParserImpl::const_literal() {
+Maybe<const ast::LiteralExpression*> Parser::const_literal() {
     auto& t = peek();
     if (match(Token::Type::kIntLiteral)) {
         return create<ast::IntLiteralExpression>(t.source(), t.to_i64(),
@@ -2925,7 +2920,7 @@
     return Failure::kNoMatch;
 }
 
-Maybe<ParserImpl::AttributeList> ParserImpl::attribute_list() {
+Maybe<Parser::AttributeList> Parser::attribute_list() {
     bool errored = false;
     AttributeList attrs;
 
@@ -2952,7 +2947,7 @@
     return attrs;
 }
 
-Expect<const ast::Attribute*> ParserImpl::expect_attribute() {
+Expect<const ast::Attribute*> Parser::expect_attribute() {
     auto& t = peek();
     auto attr = attribute();
     if (attr.errored) {
@@ -2966,7 +2961,7 @@
 
 // attribute
 //   : ATTR identifier ( PAREN_LEFT expression ( COMMA expression )? COMMA? PAREN_RIGHT )?
-Maybe<const ast::Attribute*> ParserImpl::attribute() {
+Maybe<const ast::Attribute*> Parser::attribute() {
     // Note, the ATTR is matched by the called `attribute_list` in this case, so it is not matched
     // here and this has to be an attribute.
     auto& t = peek();
@@ -3091,7 +3086,7 @@
     }
 }
 
-Expect<Void> ParserImpl::expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> in) {
+Expect<Void> Parser::expect_attributes_consumed(utils::VectorRef<const ast::Attribute*> in) {
     if (in.IsEmpty()) {
         return kSuccess;
     }
@@ -3099,7 +3094,7 @@
     return Failure::kErrored;
 }
 
-Expect<Void> ParserImpl::expect_next_not_template_list(const Source& lhs_source) {
+Expect<Void> Parser::expect_next_not_template_list(const Source& lhs_source) {
     Source end;
     if (!match(Token::Type::kTemplateArgsLeft, &end)) {
         return kSuccess;
@@ -3124,7 +3119,7 @@
     return Failure::kErrored;
 }
 
-Expect<Void> ParserImpl::expect_not_templated_ident_expr(const ast::Expression* expr) {
+Expect<Void> Parser::expect_not_templated_ident_expr(const ast::Expression* expr) {
     auto* ident_expr = expr->As<ast::IdentifierExpression>();
     if (!ident_expr) {
         return kSuccess;
@@ -3150,14 +3145,14 @@
 //   | 'warning'
 //   | 'info'
 //   | 'off'
-Expect<builtin::DiagnosticSeverity> ParserImpl::expect_severity_control_name() {
+Expect<builtin::DiagnosticSeverity> Parser::expect_severity_control_name() {
     return expect_enum("severity control", builtin::ParseDiagnosticSeverity,
                        builtin::kDiagnosticSeverityStrings);
 }
 
 // diagnostic_control
 // : PAREN_LEFT severity_control_name COMMA diagnostic_rule_name COMMA ? PAREN_RIGHT
-Expect<ast::DiagnosticControl> ParserImpl::expect_diagnostic_control() {
+Expect<ast::DiagnosticControl> Parser::expect_diagnostic_control() {
     return expect_paren_block("diagnostic control", [&]() -> Expect<ast::DiagnosticControl> {
         auto severity_control = expect_severity_control_name();
         if (severity_control.errored) {
@@ -3181,7 +3176,7 @@
 // diagnostic_rule_name :
 // | diagnostic_name_token
 // | diagnostic_name_token '.' diagnostic_name_token
-Expect<const ast::DiagnosticRuleName*> ParserImpl::expect_diagnostic_rule_name() {
+Expect<const ast::DiagnosticRuleName*> Parser::expect_diagnostic_rule_name() {
     if (peek_is(Token::Type::kPeriod, 1)) {
         auto category = expect_ident("", "diagnostic rule category");
         if (category.errored) {
@@ -3203,7 +3198,7 @@
     return builder_.DiagnosticRuleName(name.value);
 }
 
-bool ParserImpl::match(Token::Type tok, Source* source /*= nullptr*/) {
+bool Parser::match(Token::Type tok, Source* source /*= nullptr*/) {
     auto& t = peek();
 
     if (source != nullptr) {
@@ -3217,7 +3212,7 @@
     return false;
 }
 
-bool ParserImpl::expect(std::string_view use, Token::Type tok) {
+bool Parser::expect(std::string_view use, Token::Type tok) {
     auto& t = peek();
     if (t.Is(tok)) {
         next();
@@ -3260,7 +3255,7 @@
     return false;
 }
 
-Expect<int32_t> ParserImpl::expect_sint(std::string_view use, Source* source /* = nullptr */) {
+Expect<int32_t> Parser::expect_sint(std::string_view use, Source* source /* = nullptr */) {
     auto& t = peek();
     if (source) {
         *source = t.source();
@@ -3280,7 +3275,7 @@
     return static_cast<int32_t>(t.to_i64());
 }
 
-Expect<uint32_t> ParserImpl::expect_positive_sint(std::string_view use) {
+Expect<uint32_t> Parser::expect_positive_sint(std::string_view use) {
     Source source;
     auto sint = expect_sint(use, &source);
     if (sint.errored) {
@@ -3294,7 +3289,7 @@
     return static_cast<uint32_t>(sint.value);
 }
 
-Expect<uint32_t> ParserImpl::expect_nonzero_positive_sint(std::string_view use) {
+Expect<uint32_t> Parser::expect_nonzero_positive_sint(std::string_view use) {
     Source source;
     auto sint = expect_sint(use, &source);
     if (sint.errored) {
@@ -3308,9 +3303,8 @@
     return static_cast<uint32_t>(sint.value);
 }
 
-Expect<const ast::Identifier*> ParserImpl::expect_ident(
-    std::string_view use,
-    std::string_view kind /* = "identifier" */) {
+Expect<const ast::Identifier*> Parser::expect_ident(std::string_view use,
+                                                    std::string_view kind /* = "identifier" */) {
     auto& t = peek();
     if (t.IsIdentifier()) {
         synchronized_ = true;
@@ -3330,7 +3324,7 @@
 }
 
 template <typename F, typename T>
-T ParserImpl::expect_block(Token::Type start, Token::Type end, std::string_view use, F&& body) {
+T Parser::expect_block(Token::Type start, Token::Type end, std::string_view use, F&& body) {
     if (!expect(use, start)) {
         return Failure::kErrored;
     }
@@ -3351,31 +3345,31 @@
 }
 
 template <typename F, typename T>
-T ParserImpl::expect_paren_block(std::string_view use, F&& body) {
+T Parser::expect_paren_block(std::string_view use, F&& body) {
     return expect_block(Token::Type::kParenLeft, Token::Type::kParenRight, use,
                         std::forward<F>(body));
 }
 
 template <typename F, typename T>
-T ParserImpl::expect_brace_block(std::string_view use, F&& body) {
+T Parser::expect_brace_block(std::string_view use, F&& body) {
     return expect_block(Token::Type::kBraceLeft, Token::Type::kBraceRight, use,
                         std::forward<F>(body));
 }
 
 template <typename F, typename T>
-T ParserImpl::expect_lt_gt_block(std::string_view use, F&& body) {
+T Parser::expect_lt_gt_block(std::string_view use, F&& body) {
     return expect_block(Token::Type::kLessThan, Token::Type::kGreaterThan, use,
                         std::forward<F>(body));
 }
 
 template <typename F, typename T>
-T ParserImpl::expect_template_arg_block(std::string_view use, F&& body) {
+T Parser::expect_template_arg_block(std::string_view use, F&& body) {
     return expect_block(Token::Type::kTemplateArgsLeft, Token::Type::kTemplateArgsRight, use,
                         std::forward<F>(body));
 }
 
 template <typename F, typename T>
-T ParserImpl::sync(Token::Type tok, F&& body) {
+T Parser::sync(Token::Type tok, F&& body) {
     if (parse_depth_ >= kMaxParseDepth) {
         // We've hit a maximum parser recursive depth.
         // We can't call into body() as we might stack overflow.
@@ -3406,7 +3400,7 @@
     return result;
 }
 
-bool ParserImpl::sync_to(Token::Type tok, bool consume) {
+bool Parser::sync_to(Token::Type tok, bool consume) {
     // Clear the synchronized state - gets set to true again on success.
     synchronized_ = false;
 
@@ -3443,7 +3437,7 @@
     return false;
 }
 
-bool ParserImpl::is_sync_token(const Token& t) const {
+bool Parser::is_sync_token(const Token& t) const {
     for (auto r : sync_tokens_) {
         if (t.Is(r)) {
             return true;
@@ -3452,7 +3446,7 @@
     return false;
 }
 
-bool ParserImpl::handle_error(const Token& t) {
+bool Parser::handle_error(const Token& t) {
     // The token might itself be an error.
     if (t.IsError()) {
         synchronized_ = false;
@@ -3463,19 +3457,19 @@
 }
 
 template <typename F, typename T>
-T ParserImpl::without_diag(F&& body) {
+T Parser::without_diag(F&& body) {
     silence_diags_++;
     auto result = body();
     silence_diags_--;
     return result;
 }
 
-ParserImpl::MultiTokenSource ParserImpl::make_source_range() {
+Parser::MultiTokenSource Parser::make_source_range() {
     return MultiTokenSource(this);
 }
 
-ParserImpl::MultiTokenSource ParserImpl::make_source_range_from(const Source& start) {
+Parser::MultiTokenSource Parser::make_source_range_from(const Source& start) {
     return MultiTokenSource(this, start);
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl.h b/src/tint/lang/wgsl/reader/parser/parser.h
similarity index 97%
rename from src/tint/lang/wgsl/reader/parser_impl.h
rename to src/tint/lang/wgsl/reader/parser/parser.h
index 14e4c5a..a617511 100644
--- a/src/tint/lang/wgsl/reader/parser_impl.h
+++ b/src/tint/lang/wgsl/reader/parser/parser.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_H_
-#define SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_PARSER_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_PARSER_H_
 
 #include <memory>
 #include <string>
@@ -24,8 +24,8 @@
 
 #include "src/tint/lang/core/builtin/access.h"
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_detail.h"
-#include "src/tint/lang/wgsl/reader/token.h"
+#include "src/tint/lang/wgsl/reader/parser/detail.h"
+#include "src/tint/lang/wgsl/reader/parser/token.h"
 
 namespace tint::ast {
 class BreakStatement;
@@ -38,7 +38,7 @@
 class VariableDeclStatement;
 }  // namespace tint::ast
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 class Lexer;
 
@@ -60,8 +60,8 @@
     const ast::Statement* continuing = nullptr;
 };
 
-/// ParserImpl for WGSL source data
-class ParserImpl {
+/// Parser for WGSL source data
+class Parser {
     /// Failure holds enumerator values used for the constructing an Expect and
     /// Match in an errored state.
     struct Failure {
@@ -121,9 +121,9 @@
         /// std::unique_ptr, operator->() automatically dereferences so that the
         /// return type will always be a pointer to a non-pointer type. #errored
         /// must be false to call.
-        inline typename wgsl::detail::OperatorArrow<T>::type operator->() {
+        inline typename detail::OperatorArrow<T>::type operator->() {
             TINT_ASSERT(Reader, !errored);
-            return wgsl::detail::OperatorArrow<T>::ptr(value);
+            return detail::OperatorArrow<T>::ptr(value);
         }
 
         /// The expected value of a successful parse.
@@ -183,9 +183,9 @@
         /// std::unique_ptr, operator->() automatically dereferences so that the
         /// return type will always be a pointer to a non-pointer type. #errored
         /// must be false to call.
-        inline typename wgsl::detail::OperatorArrow<T>::type operator->() {
+        inline typename detail::OperatorArrow<T>::type operator->() {
             TINT_ASSERT(Reader, !errored);
-            return wgsl::detail::OperatorArrow<T>::ptr(value);
+            return detail::OperatorArrow<T>::ptr(value);
         }
 
         /// The value of a successful parse.
@@ -287,8 +287,8 @@
 
     /// Creates a new parser using the given file
     /// @param file the input source file to parse
-    explicit ParserImpl(Source::File const* file);
-    ~ParserImpl();
+    explicit Parser(Source::File const* file);
+    ~Parser();
 
     /// Reads tokens from the source file. This will be called automatically
     /// by |parse|.
@@ -562,13 +562,13 @@
     /// @param use the use of the expression list
     /// @param terminator the terminating token for the list
     /// @returns the parsed expression list or error
-    Maybe<ParserImpl::ExpressionList> expression_list(std::string_view use, Token::Type terminator);
+    Maybe<Parser::ExpressionList> expression_list(std::string_view use, Token::Type terminator);
     /// Parses a comma separated expression list, with at least one expression
     /// @param use the use of the expression list
     /// @param terminator the terminating token for the list
     /// @returns the parsed expression list or error
-    Expect<ParserImpl::ExpressionList> expect_expression_list(std::string_view use,
-                                                              Token::Type terminator);
+    Expect<Parser::ExpressionList> expect_expression_list(std::string_view use,
+                                                          Token::Type terminator);
     /// Parses the `bitwise_expression.post.unary_expression` grammar element
     /// @param lhs the left side of the expression
     /// @returns the parsed expression or nullptr
@@ -890,6 +890,6 @@
     size_t max_errors_ = 25;
 };
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_PARSER_H_
diff --git a/src/tint/lang/wgsl/reader/parser_impl_test.cc b/src/tint/lang/wgsl/reader/parser/parser_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_test.cc
rename to src/tint/lang/wgsl/reader/parser/parser_test.cc
index ec72bb2..21b9389 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/parser_test.cc
@@ -12,17 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Empty) {
+TEST_F(WGSLParserTest, Empty) {
     auto p = parser("");
     ASSERT_TRUE(p->Parse()) << p->error();
 }
 
-TEST_F(ParserImplTest, Parses) {
+TEST_F(WGSLParserTest, Parses) {
     auto p = parser(R"(
 @fragment
 fn main() -> @location(0) vec4<f32> {
@@ -35,7 +35,7 @@
     ASSERT_EQ(1u, program.AST().Functions().Length());
 }
 
-TEST_F(ParserImplTest, Parses_ExtraSemicolons) {
+TEST_F(WGSLParserTest, Parses_ExtraSemicolons) {
     auto p = parser(R"(
 ;
 struct S {
@@ -56,7 +56,7 @@
     ASSERT_EQ(1u, program.AST().TypeDecls().Length());
 }
 
-TEST_F(ParserImplTest, HandlesError) {
+TEST_F(WGSLParserTest, HandlesError) {
     auto p = parser(R"(
 fn main() ->  {  // missing return type
   return;
@@ -67,7 +67,7 @@
     EXPECT_EQ(p->error(), "2:15: unable to determine function return type");
 }
 
-TEST_F(ParserImplTest, HandlesUnexpectedToken) {
+TEST_F(WGSLParserTest, HandlesUnexpectedToken) {
     auto p = parser(R"(
 fn main() {
 }
@@ -79,7 +79,7 @@
     EXPECT_EQ(p->error(), "4:1: unexpected token");
 }
 
-TEST_F(ParserImplTest, HandlesBadToken_InMiddle) {
+TEST_F(WGSLParserTest, HandlesBadToken_InMiddle) {
     auto p = parser(R"(
 fn main() {
   let f = 0x1p10000000000000000000; // Exponent too big for hex float
@@ -91,7 +91,7 @@
     EXPECT_EQ(p->error(), "3:11: exponent is too large for hex float");
 }
 
-TEST_F(ParserImplTest, HandlesBadToken_AtModuleScope) {
+TEST_F(WGSLParserTest, HandlesBadToken_AtModuleScope) {
     auto p = parser(R"(
 fn main() {
   return;
@@ -104,7 +104,7 @@
     EXPECT_EQ(p->error(), "5:1: exponent is too large for hex float");
 }
 
-TEST_F(ParserImplTest, Comments_TerminatedBlockComment) {
+TEST_F(WGSLParserTest, Comments_TerminatedBlockComment) {
     auto p = parser(R"(
 /**
  * Here is my shader.
@@ -124,7 +124,7 @@
     ASSERT_EQ(1u, p->program().AST().Functions().Length());
 }
 
-TEST_F(ParserImplTest, Comments_UnterminatedBlockComment) {
+TEST_F(WGSLParserTest, Comments_UnterminatedBlockComment) {
     auto p = parser(R"(
 @fragment
 fn main() -> @location(0) vec4<f32> {
@@ -136,20 +136,20 @@
     EXPECT_EQ(p->error(), "5:3: unterminated block comment") << p->error();
 }
 
-TEST_F(ParserImplTest, Peek) {
+TEST_F(WGSLParserTest, Peek) {
     auto p = parser("a == if");
     EXPECT_TRUE(p->peek_is(Token::Type::kIdentifier));
     EXPECT_TRUE(p->peek_is(Token::Type::kEqualEqual, 1));
     EXPECT_TRUE(p->peek_is(Token::Type::kIf, 2));
 }
 
-TEST_F(ParserImplTest, Peek_Placeholder) {
+TEST_F(WGSLParserTest, Peek_Placeholder) {
     auto p = parser(">> if");
     EXPECT_TRUE(p->peek_is(Token::Type::kShiftRight));
     EXPECT_TRUE(p->peek_is(Token::Type::kIf, 1));
 }
 
-TEST_F(ParserImplTest, Peek_PastPlaceholder) {
+TEST_F(WGSLParserTest, Peek_PastPlaceholder) {
     auto p = parser(">= vec2<u32>");
     auto& n = p->next();
     ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
@@ -159,7 +159,7 @@
         << "expected: < got: " << p->peek(1).to_name();
 }
 
-TEST_F(ParserImplTest, Peek_MultiplePlaceholder) {
+TEST_F(WGSLParserTest, Peek_MultiplePlaceholder) {
     auto p = parser(">= >= vec2<u32>");
     auto& n = p->next();
     ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
@@ -171,14 +171,14 @@
         << "expected: < got: " << p->peek(2).to_name();
 }
 
-TEST_F(ParserImplTest, Peek_PastEnd) {
+TEST_F(WGSLParserTest, Peek_PastEnd) {
     auto p = parser(">");
     EXPECT_TRUE(p->peek_is(Token::Type::kGreaterThan));
     EXPECT_TRUE(p->peek_is(Token::Type::kEOF, 1));
     EXPECT_TRUE(p->peek_is(Token::Type::kEOF, 2));
 }
 
-TEST_F(ParserImplTest, Peek_PastEnd_WalkingPlaceholders) {
+TEST_F(WGSLParserTest, Peek_PastEnd_WalkingPlaceholders) {
     auto p = parser(">= >=");
     auto& n = p->next();
     ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
@@ -187,7 +187,7 @@
     EXPECT_TRUE(p->peek_is(Token::Type::kEOF, 1)) << "expected: EOF got: " << p->peek(1).to_name();
 }
 
-TEST_F(ParserImplTest, Peek_AfterSplit) {
+TEST_F(WGSLParserTest, Peek_AfterSplit) {
     auto p = parser(">= vec2<u32>");
     auto& n = p->next();
     ASSERT_TRUE(n.Is(Token::Type::kGreaterThanEqual));
@@ -200,4 +200,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_primary_expression_test.cc b/src/tint/lang/wgsl/reader/parser/primary_expression_test.cc
similarity index 86%
rename from src/tint/lang/wgsl/reader/parser_impl_primary_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/primary_expression_test.cc
index a7862a3..b44af1e 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_primary_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/primary_expression_test.cc
@@ -14,12 +14,12 @@
 
 #include "src/tint/lang/wgsl/ast/bitcast_expression.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, PrimaryExpression_Ident) {
+TEST_F(WGSLParserTest, PrimaryExpression_Ident) {
     auto p = parser("a");
     auto e = p->primary_expression();
     EXPECT_TRUE(e.matched);
@@ -30,7 +30,7 @@
     ast::CheckIdentifier(e.value, "a");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl) {
     auto p = parser("vec4<i32>(1, 2, 3, 4))");
     auto e = p->primary_expression();
     EXPECT_TRUE(e.matched);
@@ -63,7 +63,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_ZeroInitializer) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl_ZeroInitializer) {
     auto p = parser("vec4<i32>()");
     auto e = p->primary_expression();
     EXPECT_TRUE(e.matched);
@@ -77,7 +77,7 @@
     ASSERT_EQ(call->args.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_MissingRightParen) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl_MissingRightParen) {
     auto p = parser("vec4<f32>(2., 3., 4., 5.");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -87,7 +87,7 @@
     EXPECT_EQ(p->error(), "1:25: expected ',' for function call");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_InvalidValue) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl_InvalidValue) {
     auto p = parser("i32(if(a) {})");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -97,7 +97,7 @@
     EXPECT_EQ(p->error(), "1:5: expected expression for function call");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructInitializer_Empty) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl_StructInitializer_Empty) {
     auto p = parser(R"(
   struct S { a : i32, b : f32, }
   S()
@@ -121,7 +121,7 @@
     ASSERT_EQ(call->args.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_TypeDecl_StructInitializer_NotEmpty) {
+TEST_F(WGSLParserTest, PrimaryExpression_TypeDecl_StructInitializer_NotEmpty) {
     auto p = parser(R"(
   struct S { a : i32, b : f32, }
   S(1u, 2.0)
@@ -153,7 +153,7 @@
     EXPECT_EQ(call->args[1]->As<ast::FloatLiteralExpression>()->value, 2.f);
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_ConstLiteral_True) {
+TEST_F(WGSLParserTest, PrimaryExpression_ConstLiteral_True) {
     auto p = parser("true");
     auto e = p->primary_expression();
     EXPECT_TRUE(e.matched);
@@ -164,7 +164,7 @@
     EXPECT_TRUE(e->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_ParenExpr) {
+TEST_F(WGSLParserTest, PrimaryExpression_ParenExpr) {
     auto p = parser("(a == b)");
     auto e = p->primary_expression();
     EXPECT_TRUE(e.matched);
@@ -174,7 +174,7 @@
     ASSERT_TRUE(e->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_MissingRightParen) {
+TEST_F(WGSLParserTest, PrimaryExpression_ParenExpr_MissingRightParen) {
     auto p = parser("(a == b");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -184,7 +184,7 @@
     EXPECT_EQ(p->error(), "1:8: expected ')'");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_MissingExpr) {
+TEST_F(WGSLParserTest, PrimaryExpression_ParenExpr_MissingExpr) {
     auto p = parser("()");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -194,7 +194,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse expression");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_ParenExpr_InvalidExpr) {
+TEST_F(WGSLParserTest, PrimaryExpression_ParenExpr_InvalidExpr) {
     auto p = parser("(if (a) {})");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -204,7 +204,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse expression");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Cast) {
+TEST_F(WGSLParserTest, PrimaryExpression_Cast) {
     auto p = parser("f32(1)");
 
     auto e = p->primary_expression();
@@ -221,7 +221,7 @@
     ASSERT_TRUE(call->args[0]->Is<ast::IntLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast) {
     auto p = parser("bitcast<f32>(1)");
 
     auto e = p->primary_expression();
@@ -238,7 +238,7 @@
     ASSERT_TRUE(c->expr->Is<ast::IntLiteralExpression>());
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingGreaterThan) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast_MissingGreaterThan) {
     auto p = parser("bitcast<f32(1)");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -248,7 +248,7 @@
     EXPECT_EQ(p->error(), "1:8: missing closing '>' for bitcast expression");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingType) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast_MissingType) {
     auto p = parser("bitcast<>(1)");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -258,7 +258,7 @@
     EXPECT_EQ(p->error(), "1:9: invalid type for bitcast expression");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingLeftParen) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast_MissingLeftParen) {
     auto p = parser("bitcast<f32>1)");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -268,7 +268,7 @@
     EXPECT_EQ(p->error(), "1:13: expected '('");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingRightParen) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast_MissingRightParen) {
     auto p = parser("bitcast<f32>(1");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -278,7 +278,7 @@
     EXPECT_EQ(p->error(), "1:15: expected ')'");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_Bitcast_MissingExpression) {
+TEST_F(WGSLParserTest, PrimaryExpression_Bitcast_MissingExpression) {
     auto p = parser("bitcast<f32>()");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -288,7 +288,7 @@
     EXPECT_EQ(p->error(), "1:14: unable to parse expression");
 }
 
-TEST_F(ParserImplTest, PrimaryExpression_bitcast_InvalidExpression) {
+TEST_F(WGSLParserTest, PrimaryExpression_bitcast_InvalidExpression) {
     auto p = parser("bitcast<f32>(if (a) {})");
     auto e = p->primary_expression();
     EXPECT_FALSE(e.matched);
@@ -299,4 +299,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_relational_expression_test.cc b/src/tint/lang/wgsl/reader/parser/relational_expression_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_relational_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/relational_expression_test.cc
index 54b142b..57b062b 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_relational_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/relational_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_LessThan) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_LessThan) {
     auto p = parser("a < true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -42,7 +42,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_GreaterThan) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_GreaterThan) {
     auto p = parser("a > true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -67,7 +67,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_LessThanEqual) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_LessThanEqual) {
     auto p = parser("a <= true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -92,7 +92,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_GreaterThanEqual) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_GreaterThanEqual) {
     auto p = parser("a >= true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -117,7 +117,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_Equal) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_Equal) {
     auto p = parser("a == true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -142,7 +142,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_Parses_NotEqual) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_Parses_NotEqual) {
     auto p = parser("a != true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -167,7 +167,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_InvalidRHS) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_InvalidRHS) {
     auto p = parser("true < if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -176,7 +176,7 @@
     EXPECT_EQ(p->error(), "1:8: unable to parse right side of < expression");
 }
 
-TEST_F(ParserImplTest, RelationalExpression_PostUnary_NoMatch_ReturnsLHS) {
+TEST_F(WGSLParserTest, RelationalExpression_PostUnary_NoMatch_ReturnsLHS) {
     auto p = parser("a true");
     auto lhs = p->unary_expression();
     auto e = p->expect_relational_expression_post_unary_expression(lhs.value);
@@ -186,7 +186,7 @@
     EXPECT_EQ(lhs.value, e.value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_Matches) {
+TEST_F(WGSLParserTest, RelationalExpression_Matches) {
     auto p = parser("a >= true");
     auto e = p->relational_expression();
     EXPECT_TRUE(e.matched);
@@ -206,7 +206,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_InvalidLHS) {
+TEST_F(WGSLParserTest, RelationalExpression_InvalidLHS) {
     auto p = parser("if (a) {}< 3");
     auto e = p->relational_expression();
     ASSERT_FALSE(e.matched);
@@ -215,7 +215,7 @@
     EXPECT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_InvalidRHS) {
+TEST_F(WGSLParserTest, RelationalExpression_InvalidRHS) {
     auto p = parser("true < if (a) {}");
     auto e = p->relational_expression();
     ASSERT_FALSE(e.matched);
@@ -225,7 +225,7 @@
     EXPECT_EQ(p->error(), "1:8: unable to parse right side of < expression");
 }
 
-TEST_F(ParserImplTest, RelationalExpression_Parses_Equal) {
+TEST_F(WGSLParserTest, RelationalExpression_Parses_Equal) {
     auto p = parser("a == true");
     auto e = p->relational_expression();
     EXPECT_TRUE(e.matched);
@@ -250,7 +250,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_Parses_NotEqual) {
+TEST_F(WGSLParserTest, RelationalExpression_Parses_NotEqual) {
     auto p = parser("a != true");
     auto e = p->relational_expression();
     EXPECT_TRUE(e.matched);
@@ -275,7 +275,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, RelationalExpression_Equal_InvalidRHS) {
+TEST_F(WGSLParserTest, RelationalExpression_Equal_InvalidRHS) {
     auto p = parser("true == if (a) {}");
     auto e = p->relational_expression();
     EXPECT_FALSE(e.matched);
@@ -286,4 +286,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_require_directive_test.cc b/src/tint/lang/wgsl/reader/parser/require_directive_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_require_directive_test.cc
rename to src/tint/lang/wgsl/reader/parser/require_directive_test.cc
index d6d3531..261672a 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_require_directive_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/require_directive_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using RequiresDirectiveTest = ParserImplTest;
+using RequiresDirectiveTest = WGSLParserTest;
 
 // Test a valid require directive.
 // There currently are no valid require directives
@@ -68,4 +68,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_reserved_keyword_test.cc b/src/tint/lang/wgsl/reader/parser/reserved_keyword_test.cc
similarity index 97%
rename from src/tint/lang/wgsl/reader/parser_impl_reserved_keyword_test.cc
rename to src/tint/lang/wgsl/reader/parser/reserved_keyword_test.cc
index 60f7ab9..f233b1a 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_reserved_keyword_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/reserved_keyword_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using ParserImplReservedKeywordTest = ParserImplTestWithParam<std::string>;
+using ParserImplReservedKeywordTest = WGSLParserTestWithParam<std::string>;
 TEST_P(ParserImplReservedKeywordTest, Function) {
     auto name = GetParam();
     auto p = parser("fn " + name + "() {}");
@@ -231,4 +231,4 @@
                                          ));
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_shift_expression_test.cc b/src/tint/lang/wgsl/reader/parser/shift_expression_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_shift_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/shift_expression_test.cc
index ecbebf34..311ab98 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_shift_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/shift_expression_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_Parses_ShiftLeft) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_Parses_ShiftLeft) {
     auto p = parser("a << true");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -42,7 +42,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_Parses_ShiftRight) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_Parses_ShiftRight) {
     auto p = parser("a >> true");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -67,7 +67,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_Parses_Additive) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_Parses_Additive) {
     auto p = parser("a + b");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -88,7 +88,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_Parses_Multiplicative) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_Parses_Multiplicative) {
     auto p = parser("a * b");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -109,7 +109,7 @@
     EXPECT_EQ(ident_expr->identifier->symbol, p->builder().Symbols().Get("b"));
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_InvalidSpaceLeft) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_InvalidSpaceLeft) {
     auto p = parser("a < < true");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -118,7 +118,7 @@
     EXPECT_FALSE(e.value->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_InvalidSpaceRight) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_InvalidSpaceRight) {
     auto p = parser("a > > true");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -127,7 +127,7 @@
     EXPECT_FALSE(e.value->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_InvalidRHS) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_InvalidRHS) {
     auto p = parser("a << if (a) {}");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -137,7 +137,7 @@
     EXPECT_EQ(p->error(), "1:6: unable to parse right side of << expression");
 }
 
-TEST_F(ParserImplTest, ShiftExpression_PostUnary_NoOr_ReturnsLHS) {
+TEST_F(WGSLParserTest, ShiftExpression_PostUnary_NoOr_ReturnsLHS) {
     auto p = parser("a true");
     auto lhs = p->unary_expression();
     auto e = p->expect_shift_expression_post_unary_expression(lhs.value);
@@ -147,7 +147,7 @@
     ASSERT_EQ(lhs.value, e.value);
 }
 
-TEST_F(ParserImplTest, ShiftExpression_Parses) {
+TEST_F(WGSLParserTest, ShiftExpression_Parses) {
     auto p = parser("a << true");
     auto e = p->shift_expression();
     EXPECT_TRUE(e.matched);
@@ -167,7 +167,7 @@
     ASSERT_TRUE(rel->rhs->As<ast::BoolLiteralExpression>()->value);
 }
 
-TEST_F(ParserImplTest, ShiftExpression_Invalid_Unary) {
+TEST_F(WGSLParserTest, ShiftExpression_Invalid_Unary) {
     auto p = parser("if >> true");
     auto e = p->shift_expression();
     EXPECT_FALSE(e.matched);
@@ -176,7 +176,7 @@
     ASSERT_EQ(e.value, nullptr);
 }
 
-TEST_F(ParserImplTest, ShiftExpression_Inavlid_ShiftExpressionPostUnary) {
+TEST_F(WGSLParserTest, ShiftExpression_Inavlid_ShiftExpressionPostUnary) {
     auto p = parser("a * if (a) {}");
     auto e = p->shift_expression();
     EXPECT_FALSE(e.matched);
@@ -188,4 +188,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_singular_expression_test.cc b/src/tint/lang/wgsl/reader/parser/singular_expression_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_singular_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/singular_expression_test.cc
index 18c8f3a..9087e2f 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_singular_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/singular_expression_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, SingularExpression_Array_ConstantIndex) {
+TEST_F(WGSLParserTest, SingularExpression_Array_ConstantIndex) {
     auto p = parser("a[1]");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -39,7 +39,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SingularExpression_Array_ExpressionIndex) {
+TEST_F(WGSLParserTest, SingularExpression_Array_ExpressionIndex) {
     auto p = parser("a[1 + b / 4]");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -62,7 +62,7 @@
     EXPECT_EQ(e->source.range.end.column, 13u);
 }
 
-TEST_F(ParserImplTest, SingularExpression_Array_MissingIndex) {
+TEST_F(WGSLParserTest, SingularExpression_Array_MissingIndex) {
     auto p = parser("a[]");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -72,7 +72,7 @@
     EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
 }
 
-TEST_F(ParserImplTest, SingularExpression_Array_MissingRightBrace) {
+TEST_F(WGSLParserTest, SingularExpression_Array_MissingRightBrace) {
     auto p = parser("a[1");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -82,7 +82,7 @@
     EXPECT_EQ(p->error(), "1:4: expected ']' for index accessor");
 }
 
-TEST_F(ParserImplTest, SingularExpression_Array_InvalidIndex) {
+TEST_F(WGSLParserTest, SingularExpression_Array_InvalidIndex) {
     auto p = parser("a[if(a() {})]");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -92,7 +92,7 @@
     EXPECT_EQ(p->error(), "1:3: unable to parse expression inside []");
 }
 
-TEST_F(ParserImplTest, SingularExpression_Call_Empty) {
+TEST_F(WGSLParserTest, SingularExpression_Call_Empty) {
     auto p = parser("a()");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -108,7 +108,7 @@
     EXPECT_EQ(c->args.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, SingularExpression_Call_WithArgs) {
+TEST_F(WGSLParserTest, SingularExpression_Call_WithArgs) {
     auto p = parser("test(1, b, 2 + 3 / b)");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -127,7 +127,7 @@
     EXPECT_TRUE(c->args[2]->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, SingularExpression_Call_TrailingComma) {
+TEST_F(WGSLParserTest, SingularExpression_Call_TrailingComma) {
     auto p = parser("a(b, )");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -139,7 +139,7 @@
     EXPECT_EQ(c->args.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, SingularExpression_Call_InvalidArg) {
+TEST_F(WGSLParserTest, SingularExpression_Call_InvalidArg) {
     auto p = parser("a(if(a) {})");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -149,7 +149,7 @@
     EXPECT_EQ(p->error(), "1:3: expected expression for function call");
 }
 
-TEST_F(ParserImplTest, SingularExpression_Call_MissingRightParen) {
+TEST_F(WGSLParserTest, SingularExpression_Call_MissingRightParen) {
     auto p = parser("a(");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -159,7 +159,7 @@
     EXPECT_EQ(p->error(), "1:3: expected expression for function call");
 }
 
-TEST_F(ParserImplTest, SingularExpression_MemberAccessor) {
+TEST_F(WGSLParserTest, SingularExpression_MemberAccessor) {
     auto p = parser("a.b");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -181,7 +181,7 @@
     EXPECT_EQ(e->source.range.end.column, 4u);
 }
 
-TEST_F(ParserImplTest, SingularExpression_MemberAccesssor_InvalidIdent) {
+TEST_F(WGSLParserTest, SingularExpression_MemberAccesssor_InvalidIdent) {
     auto p = parser("a.if");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -191,7 +191,7 @@
     EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
 }
 
-TEST_F(ParserImplTest, SingularExpression_MemberAccessor_MissingIdent) {
+TEST_F(WGSLParserTest, SingularExpression_MemberAccessor_MissingIdent) {
     auto p = parser("a.");
     auto e = p->singular_expression();
     EXPECT_FALSE(e.matched);
@@ -201,7 +201,7 @@
     EXPECT_EQ(p->error(), "1:3: expected identifier for member accessor");
 }
 
-TEST_F(ParserImplTest, SingularExpression_NonMatch_returnLHS) {
+TEST_F(WGSLParserTest, SingularExpression_NonMatch_returnLHS) {
     auto p = parser("a b");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -211,7 +211,7 @@
     ASSERT_TRUE(e->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, SingularExpression_Array_NestedIndexAccessor) {
+TEST_F(WGSLParserTest, SingularExpression_Array_NestedIndexAccessor) {
     auto p = parser("a[b[c]]");
     auto e = p->singular_expression();
     EXPECT_TRUE(e.matched);
@@ -264,4 +264,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_statement_test.cc b/src/tint/lang/wgsl/reader/parser/statement_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_statement_test.cc
rename to src/tint/lang/wgsl/reader/parser/statement_test.cc
index d0ff3e9..bdec111 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_statement_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/statement_test.cc
@@ -15,12 +15,12 @@
 #include "src/tint/lang/wgsl/ast/break_statement.h"
 #include "src/tint/lang/wgsl/ast/continue_statement.h"
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Statement) {
+TEST_F(WGSLParserTest, Statement) {
     auto p = parser("return;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -29,13 +29,13 @@
     ASSERT_TRUE(e->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Semicolon) {
+TEST_F(WGSLParserTest, Statement_Semicolon) {
     auto p = parser(";");
     p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
 }
 
-TEST_F(ParserImplTest, Statement_Return_NoValue) {
+TEST_F(WGSLParserTest, Statement_Return_NoValue) {
     auto p = parser("return;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -46,7 +46,7 @@
     ASSERT_EQ(ret->value, nullptr);
 }
 
-TEST_F(ParserImplTest, Statement_Return_Value) {
+TEST_F(WGSLParserTest, Statement_Return_Value) {
     auto p = parser("return a + b * (.1 - .2);");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -59,7 +59,7 @@
     EXPECT_TRUE(ret->value->Is<ast::BinaryExpression>());
 }
 
-TEST_F(ParserImplTest, Statement_Return_MissingSemi) {
+TEST_F(WGSLParserTest, Statement_Return_MissingSemi) {
     auto p = parser("return");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -69,7 +69,7 @@
     EXPECT_EQ(p->error(), "1:7: expected ';' for return statement");
 }
 
-TEST_F(ParserImplTest, Statement_Return_Invalid) {
+TEST_F(WGSLParserTest, Statement_Return_Invalid) {
     auto p = parser("return if(a) {};");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -79,7 +79,7 @@
     EXPECT_EQ(p->error(), "1:8: expected ';' for return statement");
 }
 
-TEST_F(ParserImplTest, Statement_If) {
+TEST_F(WGSLParserTest, Statement_If) {
     auto p = parser("if (a) {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -88,7 +88,7 @@
     ASSERT_TRUE(e->Is<ast::IfStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_If_Invalid) {
+TEST_F(WGSLParserTest, Statement_If_Invalid) {
     auto p = parser("if (a) { fn main() -> {}}");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -98,7 +98,7 @@
     EXPECT_EQ(p->error(), "1:10: expected '}' for if statement");
 }
 
-TEST_F(ParserImplTest, Statement_Variable) {
+TEST_F(WGSLParserTest, Statement_Variable) {
     auto p = parser("var a : i32 = 1;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -107,7 +107,7 @@
     ASSERT_TRUE(e->Is<ast::VariableDeclStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Variable_Invalid) {
+TEST_F(WGSLParserTest, Statement_Variable_Invalid) {
     auto p = parser("var a : i32 =;");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -117,7 +117,7 @@
     EXPECT_EQ(p->error(), "1:14: missing initializer for 'var' declaration");
 }
 
-TEST_F(ParserImplTest, Statement_Variable_MissingSemicolon) {
+TEST_F(WGSLParserTest, Statement_Variable_MissingSemicolon) {
     auto p = parser("var a : i32");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -127,7 +127,7 @@
     EXPECT_EQ(p->error(), "1:12: expected ';' for variable declaration");
 }
 
-TEST_F(ParserImplTest, Statement_Switch) {
+TEST_F(WGSLParserTest, Statement_Switch) {
     auto p = parser("switch (a) {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -136,7 +136,7 @@
     ASSERT_TRUE(e->Is<ast::SwitchStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Switch_Invalid) {
+TEST_F(WGSLParserTest, Statement_Switch_Invalid) {
     auto p = parser("switch (a) { case: {}}");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -146,7 +146,7 @@
     EXPECT_EQ(p->error(), "1:18: expected case selector expression or `default`");
 }
 
-TEST_F(ParserImplTest, Statement_Loop) {
+TEST_F(WGSLParserTest, Statement_Loop) {
     auto p = parser("loop {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -155,7 +155,7 @@
     ASSERT_TRUE(e->Is<ast::LoopStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Loop_Invalid) {
+TEST_F(WGSLParserTest, Statement_Loop_Invalid) {
     auto p = parser("loop discard; }");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -165,7 +165,7 @@
     EXPECT_EQ(p->error(), "1:6: expected '{' for loop");
 }
 
-TEST_F(ParserImplTest, Statement_Assignment) {
+TEST_F(WGSLParserTest, Statement_Assignment) {
     auto p = parser("a = b;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -174,7 +174,7 @@
     ASSERT_TRUE(e->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Assignment_Invalid) {
+TEST_F(WGSLParserTest, Statement_Assignment_Invalid) {
     auto p = parser("a = if(b) {};");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -184,7 +184,7 @@
     EXPECT_EQ(p->error(), "1:5: unable to parse right side of assignment");
 }
 
-TEST_F(ParserImplTest, Statement_Assignment_MissingSemicolon) {
+TEST_F(WGSLParserTest, Statement_Assignment_MissingSemicolon) {
     auto p = parser("a = b");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -194,7 +194,7 @@
     EXPECT_EQ(p->error(), "1:6: expected ';' for assignment statement");
 }
 
-TEST_F(ParserImplTest, Statement_Break) {
+TEST_F(WGSLParserTest, Statement_Break) {
     auto p = parser("break;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -203,7 +203,7 @@
     ASSERT_TRUE(e->Is<ast::BreakStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Break_MissingSemicolon) {
+TEST_F(WGSLParserTest, Statement_Break_MissingSemicolon) {
     auto p = parser("break");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -213,7 +213,7 @@
     EXPECT_EQ(p->error(), "1:6: expected ';' for break statement");
 }
 
-TEST_F(ParserImplTest, Statement_Continue) {
+TEST_F(WGSLParserTest, Statement_Continue) {
     auto p = parser("continue;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -222,7 +222,7 @@
     ASSERT_TRUE(e->Is<ast::ContinueStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Continue_MissingSemicolon) {
+TEST_F(WGSLParserTest, Statement_Continue_MissingSemicolon) {
     auto p = parser("continue");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -232,7 +232,7 @@
     EXPECT_EQ(p->error(), "1:9: expected ';' for continue statement");
 }
 
-TEST_F(ParserImplTest, Statement_Discard) {
+TEST_F(WGSLParserTest, Statement_Discard) {
     auto p = parser("discard;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -242,7 +242,7 @@
     ASSERT_TRUE(e->Is<ast::DiscardStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Discard_MissingSemicolon) {
+TEST_F(WGSLParserTest, Statement_Discard_MissingSemicolon) {
     auto p = parser("discard");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -252,7 +252,7 @@
     EXPECT_EQ(p->error(), "1:8: expected ';' for discard statement");
 }
 
-TEST_F(ParserImplTest, Statement_Body) {
+TEST_F(WGSLParserTest, Statement_Body) {
     auto p = parser("{ var i: i32; }");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -262,7 +262,7 @@
     EXPECT_TRUE(e->As<ast::BlockStatement>()->statements[0]->Is<ast::VariableDeclStatement>());
 }
 
-TEST_F(ParserImplTest, Statement_Body_Invalid) {
+TEST_F(WGSLParserTest, Statement_Body_Invalid) {
     auto p = parser("{ fn main() -> {}}");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -272,7 +272,7 @@
     EXPECT_EQ(p->error(), "1:3: expected '}' for block statement");
 }
 
-TEST_F(ParserImplTest, Statement_ConstAssert_WithParen) {
+TEST_F(WGSLParserTest, Statement_ConstAssert_WithParen) {
     auto p = parser("const_assert(true);");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -293,7 +293,7 @@
     EXPECT_EQ(sa->condition->source.range.end.column, 18u);
 }
 
-TEST_F(ParserImplTest, Statement_ConstAssert_WithoutParen) {
+TEST_F(WGSLParserTest, Statement_ConstAssert_WithoutParen) {
     auto p = parser("const_assert  true;");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -314,7 +314,7 @@
     EXPECT_EQ(sa->condition->source.range.end.column, 19u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_Block) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_Block) {
     auto p = parser("@diagnostic(off, derivative_uniformity) {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -326,7 +326,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_For) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_For) {
     auto p = parser("@diagnostic(off, derivative_uniformity) for (;false;) {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -338,7 +338,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_If) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_If) {
     auto p = parser("@diagnostic(off, derivative_uniformity) if true {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -350,7 +350,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_Loop) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_Loop) {
     auto p = parser("@diagnostic(off, derivative_uniformity) loop {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -362,7 +362,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_Switch) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_Switch) {
     auto p = parser("@diagnostic(off, derivative_uniformity) switch (0) { default{} }");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -374,7 +374,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_ConsumedAttributes_While) {
+TEST_F(WGSLParserTest, Statement_ConsumedAttributes_While) {
     auto p = parser("@diagnostic(off, derivative_uniformity) while (false) {}");
     auto e = p->statement();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -386,7 +386,7 @@
     EXPECT_EQ(s->attributes.Length(), 1u);
 }
 
-TEST_F(ParserImplTest, Statement_UnexpectedAttributes) {
+TEST_F(WGSLParserTest, Statement_UnexpectedAttributes) {
     auto p = parser("@diagnostic(off, derivative_uniformity) return;");
     auto e = p->statement();
     EXPECT_TRUE(p->has_error());
@@ -397,4 +397,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_statements_test.cc b/src/tint/lang/wgsl/reader/parser/statements_test.cc
similarity index 84%
rename from src/tint/lang/wgsl/reader/parser_impl_statements_test.cc
rename to src/tint/lang/wgsl/reader/parser/statements_test.cc
index 385aa9c..ea02bc7b 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_statements_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/statements_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Statements) {
+TEST_F(WGSLParserTest, Statements) {
     auto p = parser("discard; return;");
     auto e = p->expect_statements();
     EXPECT_FALSE(e.errored);
@@ -28,7 +28,7 @@
     EXPECT_TRUE(e.value[1]->Is<ast::ReturnStatement>());
 }
 
-TEST_F(ParserImplTest, Statements_Empty) {
+TEST_F(WGSLParserTest, Statements_Empty) {
     auto p = parser("");
     auto e = p->expect_statements();
     EXPECT_FALSE(e.errored);
@@ -37,4 +37,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_attribute_decl_test.cc b/src/tint/lang/wgsl/reader/parser/struct_attribute_decl_test.cc
similarity index 83%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_attribute_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_attribute_decl_test.cc
index a33f632..d6a7284 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_attribute_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_attribute_decl_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/invariant_attribute.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AttributeDecl_Parses) {
+TEST_F(WGSLParserTest, AttributeDecl_Parses) {
     auto p = parser("@invariant");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error());
@@ -29,7 +29,7 @@
     EXPECT_TRUE(invariant->Is<ast::InvariantAttribute>());
 }
 
-TEST_F(ParserImplTest, AttributeDecl_MissingParenLeft) {
+TEST_F(WGSLParserTest, AttributeDecl_MissingParenLeft) {
     auto p = parser("@location 1)");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -39,7 +39,7 @@
     EXPECT_EQ(p->error(), "1:11: expected '(' for location attribute");
 }
 
-TEST_F(ParserImplTest, AttributeDecl_MissingValue) {
+TEST_F(WGSLParserTest, AttributeDecl_MissingValue) {
     auto p = parser("@location()");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -49,7 +49,7 @@
     EXPECT_EQ(p->error(), "1:2: location expects 1 argument");
 }
 
-TEST_F(ParserImplTest, AttributeDecl_MissingParenRight) {
+TEST_F(WGSLParserTest, AttributeDecl_MissingParenRight) {
     auto p = parser("@location(1");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -59,7 +59,7 @@
     EXPECT_EQ(p->error(), "1:12: expected ')' for location attribute");
 }
 
-TEST_F(ParserImplTest, AttributeDecl_Invalidattribute) {
+TEST_F(WGSLParserTest, AttributeDecl_Invalidattribute) {
     auto p = parser("@invalid");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -69,4 +69,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_body_decl_test.cc b/src/tint/lang/wgsl/reader/parser/struct_body_decl_test.cc
similarity index 82%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_body_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_body_decl_test.cc
index ba36f9a..8621bdf 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_body_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_body_decl_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, StructBodyDecl_Parses) {
+TEST_F(WGSLParserTest, StructBodyDecl_Parses) {
     auto p = parser("{a : i32}");
 
     auto& builder = p->builder();
@@ -34,7 +34,7 @@
     EXPECT_EQ(mem->attributes.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_Parses_TrailingComma) {
+TEST_F(WGSLParserTest, StructBodyDecl_Parses_TrailingComma) {
     auto p = parser("{a : i32,}");
 
     auto& builder = p->builder();
@@ -50,7 +50,7 @@
     EXPECT_EQ(mem->attributes.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_ParsesEmpty) {
+TEST_F(WGSLParserTest, StructBodyDecl_ParsesEmpty) {
     auto p = parser("{}");
     auto m = p->expect_struct_body_decl();
     ASSERT_FALSE(p->has_error());
@@ -58,7 +58,7 @@
     ASSERT_EQ(m.value.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_InvalidAlign) {
+TEST_F(WGSLParserTest, StructBodyDecl_InvalidAlign) {
     auto p = parser(R"(
 {
   @align(if) a : i32,
@@ -69,7 +69,7 @@
     EXPECT_EQ(p->error(), "3:10: expected expression for align");
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_InvalidSize) {
+TEST_F(WGSLParserTest, StructBodyDecl_InvalidSize) {
     auto p = parser(R"(
 {
   @size(if) a : i32,
@@ -80,7 +80,7 @@
     EXPECT_EQ(p->error(), "3:9: expected expression for size");
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_MissingClosingBracket) {
+TEST_F(WGSLParserTest, StructBodyDecl_MissingClosingBracket) {
     auto p = parser("{a : i32,");
     auto m = p->expect_struct_body_decl();
     ASSERT_TRUE(p->has_error());
@@ -88,7 +88,7 @@
     EXPECT_EQ(p->error(), "1:10: expected '}' for struct declaration");
 }
 
-TEST_F(ParserImplTest, StructBodyDecl_InvalidToken) {
+TEST_F(WGSLParserTest, StructBodyDecl_InvalidToken) {
     auto p = parser(R"(
 {
   a : i32,
@@ -101,4 +101,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_decl_test.cc b/src/tint/lang/wgsl/reader/parser/struct_decl_test.cc
similarity index 89%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_decl_test.cc
index 1281eef..85a7836 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_decl_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 #include "src/tint/utils/text/string.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, StructDecl_Parses) {
+TEST_F(WGSLParserTest, StructDecl_Parses) {
     auto p = parser(R"(
 struct S {
   a : i32,
@@ -35,7 +35,7 @@
     EXPECT_EQ(s->members[1]->name->symbol, p->builder().Symbols().Register("b"));
 }
 
-TEST_F(ParserImplTest, StructDecl_Unicode_Parses) {
+TEST_F(WGSLParserTest, StructDecl_Unicode_Parses) {
     const std::string struct_ident =  // "𝓼𝓽𝓻𝓾𝓬𝓽𝓾𝓻𝓮"
         "\xf0\x9d\x93\xbc\xf0\x9d\x93\xbd\xf0\x9d\x93\xbb\xf0\x9d\x93\xbe\xf0\x9d"
         "\x93\xac\xf0\x9d\x93\xbd\xf0\x9d\x93\xbe\xf0\x9d\x93\xbb\xf0\x9d\x93"
@@ -69,7 +69,7 @@
     EXPECT_EQ(s->members[1]->name->symbol, p->builder().Symbols().Register(member_b_ident));
 }
 
-TEST_F(ParserImplTest, StructDecl_EmptyMembers) {
+TEST_F(WGSLParserTest, StructDecl_EmptyMembers) {
     auto p = parser("struct S {}");
 
     auto s = p->struct_decl();
@@ -80,7 +80,7 @@
     ASSERT_EQ(s->members.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, StructDecl_MissingIdent) {
+TEST_F(WGSLParserTest, StructDecl_MissingIdent) {
     auto p = parser("struct {}");
 
     auto s = p->struct_decl();
@@ -92,7 +92,7 @@
     EXPECT_EQ(p->error(), "1:8: expected identifier for struct declaration");
 }
 
-TEST_F(ParserImplTest, StructDecl_MissingBracketLeft) {
+TEST_F(WGSLParserTest, StructDecl_MissingBracketLeft) {
     auto p = parser("struct S }");
 
     auto s = p->struct_decl();
@@ -105,4 +105,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_decl_test.cc b/src/tint/lang/wgsl/reader/parser/struct_member_attribute_decl_test.cc
similarity index 83%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_member_attribute_decl_test.cc
index bc9658c..1924172 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_member_attribute_decl_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AttributeDecl_EmptyStr) {
+TEST_F(WGSLParserTest, AttributeDecl_EmptyStr) {
     auto p = parser("");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error());
@@ -26,7 +26,7 @@
     EXPECT_EQ(attrs.value.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, AttributeDecl_Single) {
+TEST_F(WGSLParserTest, AttributeDecl_Single) {
     auto p = parser("@size(4)");
     auto attrs = p->attribute_list();
     EXPECT_FALSE(p->has_error());
@@ -38,7 +38,7 @@
     EXPECT_TRUE(attr->Is<ast::StructMemberSizeAttribute>());
 }
 
-TEST_F(ParserImplTest, AttributeDecl_InvalidAttribute) {
+TEST_F(WGSLParserTest, AttributeDecl_InvalidAttribute) {
     auto p = parser("@size(if)");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error()) << p->error();
@@ -48,4 +48,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_test.cc b/src/tint/lang/wgsl/reader/parser/struct_member_attribute_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_member_attribute_test.cc
index ff06686..7ba309d 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_member_attribute_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_member_attribute_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Attribute_Size) {
+TEST_F(WGSLParserTest, Attribute_Size) {
     auto p = parser("size(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -34,7 +34,7 @@
     EXPECT_EQ(o->expr->As<ast::IntLiteralExpression>()->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Size_Expression) {
+TEST_F(WGSLParserTest, Attribute_Size_Expression) {
     auto p = parser("size(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -60,7 +60,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_Size_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Size_TrailingComma) {
     auto p = parser("size(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -77,7 +77,7 @@
     EXPECT_EQ(o->expr->As<ast::IntLiteralExpression>()->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Size_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Size_MissingLeftParen) {
     auto p = parser("size 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -87,7 +87,7 @@
     EXPECT_EQ(p->error(), "1:6: expected '(' for size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Size_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Size_MissingRightParen) {
     auto p = parser("size(4");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -97,7 +97,7 @@
     EXPECT_EQ(p->error(), "1:7: expected ')' for size attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Size_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Size_MissingValue) {
     auto p = parser("size()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -107,7 +107,7 @@
     EXPECT_EQ(p->error(), "1:1: size expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Size_MissingInvalid) {
+TEST_F(WGSLParserTest, Attribute_Size_MissingInvalid) {
     auto p = parser("size(if)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -117,7 +117,7 @@
     EXPECT_EQ(p->error(), "1:6: expected expression for size");
 }
 
-TEST_F(ParserImplTest, Attribute_Align) {
+TEST_F(WGSLParserTest, Attribute_Align) {
     auto p = parser("align(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -136,7 +136,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Align_Expression) {
+TEST_F(WGSLParserTest, Attribute_Align_Expression) {
     auto p = parser("align(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -162,7 +162,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_Align_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Align_TrailingComma) {
     auto p = parser("align(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -182,7 +182,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Align_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Align_MissingLeftParen) {
     auto p = parser("align 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -192,7 +192,7 @@
     EXPECT_EQ(p->error(), "1:7: expected '(' for align attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Align_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Align_MissingRightParen) {
     auto p = parser("align(4");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -202,7 +202,7 @@
     EXPECT_EQ(p->error(), "1:8: expected ')' for align attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Align_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Align_MissingValue) {
     auto p = parser("align()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -212,7 +212,7 @@
     EXPECT_EQ(p->error(), "1:1: align expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Align_ExpressionInvalid) {
+TEST_F(WGSLParserTest, Attribute_Align_ExpressionInvalid) {
     auto p = parser("align(4 + 5 << 6)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -223,7 +223,7 @@
     EXPECT_EQ(p->error(), "1:9: mixing '+' and '<<' requires parenthesis");
 }
 
-TEST_F(ParserImplTest, Attribute_Index) {
+TEST_F(WGSLParserTest, Attribute_Index) {
     auto p = parser("index(1)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -241,4 +241,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_struct_member_test.cc b/src/tint/lang/wgsl/reader/parser/struct_member_test.cc
similarity index 90%
rename from src/tint/lang/wgsl/reader/parser_impl_struct_member_test.cc
rename to src/tint/lang/wgsl/reader/parser/struct_member_test.cc
index 6f4da06..535a08d 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_struct_member_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/struct_member_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, StructMember_Parses) {
+TEST_F(WGSLParserTest, StructMember_Parses) {
     auto p = parser("a : i32,");
 
     auto m = p->expect_struct_member();
@@ -34,7 +34,7 @@
     EXPECT_EQ(m->type->source.range, (Source::Range{{1u, 5u}, {1u, 8u}}));
 }
 
-TEST_F(ParserImplTest, StructMember_ParsesWithAlignAttribute) {
+TEST_F(WGSLParserTest, StructMember_ParsesWithAlignAttribute) {
     auto p = parser("@align(2) a : i32,");
 
     auto m = p->expect_struct_member();
@@ -57,7 +57,7 @@
     EXPECT_EQ(m->type->source.range, (Source::Range{{1u, 15u}, {1u, 18u}}));
 }
 
-TEST_F(ParserImplTest, StructMember_ParsesWithSizeAttribute) {
+TEST_F(WGSLParserTest, StructMember_ParsesWithSizeAttribute) {
     auto p = parser("@size(2) a : i32,");
 
     auto m = p->expect_struct_member();
@@ -78,7 +78,7 @@
     EXPECT_EQ(m->type->source.range, (Source::Range{{1u, 14u}, {1u, 17u}}));
 }
 
-TEST_F(ParserImplTest, StructMember_ParsesWithMultipleattributes) {
+TEST_F(WGSLParserTest, StructMember_ParsesWithMultipleattributes) {
     auto p = parser(R"(@size(2)
 @align(4) a : i32,)");
 
@@ -107,7 +107,7 @@
     EXPECT_EQ(m->type->source.range, (Source::Range{{2u, 15u}, {2u, 18u}}));
 }
 
-TEST_F(ParserImplTest, StructMember_InvalidAttribute) {
+TEST_F(WGSLParserTest, StructMember_InvalidAttribute) {
     auto p = parser("@size(if) a : i32,");
 
     auto m = p->expect_struct_member();
@@ -119,4 +119,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_switch_body_test.cc b/src/tint/lang/wgsl/reader/parser/switch_body_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_switch_body_test.cc
rename to src/tint/lang/wgsl/reader/parser/switch_body_test.cc
index e2cac93..85623a3 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_switch_body_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/switch_body_test.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, SwitchBody_Case) {
+TEST_F(WGSLParserTest, SwitchBody_Case) {
     auto p = parser("case 1 { a = 4; }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -41,7 +41,7 @@
     EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_Expression) {
+TEST_F(WGSLParserTest, SwitchBody_Case_Expression) {
     auto p = parser("case 1 + 2 { a = 4; }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -73,7 +73,7 @@
     EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Case_WithColon) {
     auto p = parser("case 1: { a = 4; }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -97,7 +97,7 @@
     EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma) {
+TEST_F(WGSLParserTest, SwitchBody_Case_TrailingComma) {
     auto p = parser("case 1, 2, { }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -123,7 +123,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_TrailingComma_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Case_TrailingComma_WithColon) {
     auto p = parser("case 1, 2,: { }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -149,7 +149,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_Invalid) {
+TEST_F(WGSLParserTest, SwitchBody_Case_Invalid) {
     auto p = parser("case if: { a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -159,7 +159,7 @@
     EXPECT_EQ(p->error(), "1:6: expected case selector expression or `default`");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MissingConstLiteral) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MissingConstLiteral) {
     auto p = parser("case: { a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -169,7 +169,7 @@
     EXPECT_EQ(p->error(), "1:5: expected case selector expression or `default`");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MissingBracketLeft) {
     auto p = parser("case 1 a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -179,7 +179,7 @@
     EXPECT_EQ(p->error(), "1:8: expected '{' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketLeft_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MissingBracketLeft_WithColon) {
     auto p = parser("case 1: a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -189,7 +189,7 @@
     EXPECT_EQ(p->error(), "1:9: expected '{' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MissingBracketRight) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MissingBracketRight) {
     auto p = parser("case 1: { a = 4; ");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -199,7 +199,7 @@
     EXPECT_EQ(p->error(), "1:18: expected '}' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_InvalidCaseBody) {
+TEST_F(WGSLParserTest, SwitchBody_Case_InvalidCaseBody) {
     auto p = parser("case 1: { fn main() {} }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -209,7 +209,7 @@
     EXPECT_EQ(p->error(), "1:11: expected '}' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MultipleSelectors) {
     auto p = parser("case 1, 2 { }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -234,7 +234,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_with_default) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MultipleSelectors_with_default) {
     auto p = parser("case 1, default, 2 { }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -261,7 +261,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectors_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MultipleSelectors_WithColon) {
     auto p = parser("case 1, 2: { }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -286,7 +286,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MultipleSelectorsMissingComma) {
     auto p = parser("case 1 2: { }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -296,7 +296,7 @@
     EXPECT_EQ(p->error(), "1:8: expected '{' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
+TEST_F(WGSLParserTest, SwitchBody_Case_MultipleSelectorsStartsWithComma) {
     auto p = parser("case , 1, 2: { }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -306,7 +306,7 @@
     EXPECT_EQ(p->error(), "1:6: expected case selector expression or `default`");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default) {
+TEST_F(WGSLParserTest, SwitchBody_Default) {
     auto p = parser("default { a = 4; }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -319,7 +319,7 @@
     EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Default_WithColon) {
     auto p = parser("default: { a = 4; }");
     auto e = p->switch_body();
     EXPECT_FALSE(p->has_error()) << p->error();
@@ -332,7 +332,7 @@
     EXPECT_TRUE(e->body->statements[0]->Is<ast::AssignmentStatement>());
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketLeft) {
+TEST_F(WGSLParserTest, SwitchBody_Default_MissingBracketLeft) {
     auto p = parser("default a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -342,7 +342,7 @@
     EXPECT_EQ(p->error(), "1:9: expected '{' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketLeft_WithColon) {
+TEST_F(WGSLParserTest, SwitchBody_Default_MissingBracketLeft_WithColon) {
     auto p = parser("default: a = 4; }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -352,7 +352,7 @@
     EXPECT_EQ(p->error(), "1:10: expected '{' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default_MissingBracketRight) {
+TEST_F(WGSLParserTest, SwitchBody_Default_MissingBracketRight) {
     auto p = parser("default: { a = 4; ");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -362,7 +362,7 @@
     EXPECT_EQ(p->error(), "1:19: expected '}' for case statement");
 }
 
-TEST_F(ParserImplTest, SwitchBody_Default_InvalidCaseBody) {
+TEST_F(WGSLParserTest, SwitchBody_Default_InvalidCaseBody) {
     auto p = parser("default: { fn main() {} }");
     auto e = p->switch_body();
     EXPECT_TRUE(p->has_error());
@@ -373,4 +373,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_switch_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/switch_stmt_test.cc
similarity index 80%
rename from src/tint/lang/wgsl/reader/parser_impl_switch_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/switch_stmt_test.cc
index 2346df4..d8e97c3 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_switch_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/switch_stmt_test.cc
@@ -12,17 +12,17 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, SwitchStmt_WithoutDefault) {
+TEST_F(WGSLParserTest, SwitchStmt_WithoutDefault) {
     auto p = parser(R"(switch a {
   case 1: {}
   case 2: {}
 })");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -34,9 +34,9 @@
     EXPECT_FALSE(e->body[1]->ContainsDefault());
 }
 
-TEST_F(ParserImplTest, SwitchStmt_Empty) {
+TEST_F(WGSLParserTest, SwitchStmt_Empty) {
     auto p = parser("switch a { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -46,13 +46,13 @@
     ASSERT_EQ(e->body.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, SwitchStmt_DefaultInMiddle) {
+TEST_F(WGSLParserTest, SwitchStmt_DefaultInMiddle) {
     auto p = parser(R"(switch a {
   case 1: {}
   default: {}
   case 2: {}
 })");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -66,11 +66,11 @@
     ASSERT_FALSE(e->body[2]->ContainsDefault());
 }
 
-TEST_F(ParserImplTest, SwitchStmt_Default_Mixed) {
+TEST_F(WGSLParserTest, SwitchStmt_Default_Mixed) {
     auto p = parser(R"(switch a {
   case 1, default, 2: {}
 })");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -82,9 +82,9 @@
     ASSERT_TRUE(e->body[0]->ContainsDefault());
 }
 
-TEST_F(ParserImplTest, SwitchStmt_WithParens) {
+TEST_F(WGSLParserTest, SwitchStmt_WithParens) {
     auto p = parser("switch(a+b) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -94,7 +94,7 @@
     ASSERT_EQ(e->body.Length(), 0u);
 }
 
-TEST_F(ParserImplTest, SwitchStmt_WithAttributes) {
+TEST_F(WGSLParserTest, SwitchStmt_WithAttributes) {
     auto p = parser("@diagnostic(off, derivative_uniformity) switch a { default{} }");
     auto a = p->attribute_list();
     auto e = p->switch_statement(a.value);
@@ -109,9 +109,9 @@
     EXPECT_TRUE(e->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, SwitchStmt_WithBodyAttributes) {
+TEST_F(WGSLParserTest, SwitchStmt_WithBodyAttributes) {
     auto p = parser("switch a @diagnostic(off, derivative_uniformity) { default{} }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_TRUE(e.matched);
     EXPECT_FALSE(e.errored);
@@ -124,9 +124,9 @@
     EXPECT_TRUE(e->body_attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-TEST_F(ParserImplTest, SwitchStmt_InvalidExpression) {
+TEST_F(WGSLParserTest, SwitchStmt_InvalidExpression) {
     auto p = parser("switch a=b {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -135,9 +135,9 @@
     EXPECT_EQ(p->error(), "1:9: expected '{' for switch statement");
 }
 
-TEST_F(ParserImplTest, SwitchStmt_MissingExpression) {
+TEST_F(WGSLParserTest, SwitchStmt_MissingExpression) {
     auto p = parser("switch {}");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -146,9 +146,9 @@
     EXPECT_EQ(p->error(), "1:8: unable to parse selector expression");
 }
 
-TEST_F(ParserImplTest, SwitchStmt_MissingBracketLeft) {
+TEST_F(WGSLParserTest, SwitchStmt_MissingBracketLeft) {
     auto p = parser("switch a }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -157,9 +157,9 @@
     EXPECT_EQ(p->error(), "1:10: expected '{' for switch statement");
 }
 
-TEST_F(ParserImplTest, SwitchStmt_MissingBracketRight) {
+TEST_F(WGSLParserTest, SwitchStmt_MissingBracketRight) {
     auto p = parser("switch a {");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -168,11 +168,11 @@
     EXPECT_EQ(p->error(), "1:11: expected '}' for switch statement");
 }
 
-TEST_F(ParserImplTest, SwitchStmt_InvalidBody) {
+TEST_F(WGSLParserTest, SwitchStmt_InvalidBody) {
     auto p = parser(R"(switch a {
   case: {}
 })");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto e = p->switch_statement(attrs);
     EXPECT_FALSE(e.matched);
     EXPECT_TRUE(e.errored);
@@ -182,4 +182,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_test_helper.cc b/src/tint/lang/wgsl/reader/parser/test_helper.cc
similarity index 73%
rename from src/tint/lang/wgsl/reader/parser_impl_test_helper.cc
rename to src/tint/lang/wgsl/reader/parser/test_helper.cc
index 9daac1c..1f92adc 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_test_helper.cc
+++ b/src/tint/lang/wgsl/reader/parser/test_helper.cc
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
-ParserImplTest::ParserImplTest() = default;
+WGSLParserTest::WGSLParserTest() = default;
 
-ParserImplTest::~ParserImplTest() = default;
+WGSLParserTest::~WGSLParserTest() = default;
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_test_helper.h b/src/tint/lang/wgsl/reader/parser/test_helper.h
similarity index 66%
rename from src/tint/lang/wgsl/reader/parser_impl_test_helper.h
rename to src/tint/lang/wgsl/reader/parser/test_helper.h
index 21638b0..57958ec 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_test_helper.h
+++ b/src/tint/lang/wgsl/reader/parser/test_helper.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_TEST_HELPER_H_
-#define SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_TEST_HELPER_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_TEST_HELPER_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_TEST_HELPER_H_
 
 #include <memory>
 #include <string>
@@ -21,23 +21,23 @@
 #include <vector>
 
 #include "gtest/gtest.h"
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 /// WGSL Parser test class
-class ParserImplTest : public testing::Test {
+class WGSLParserTest : public testing::Test {
   public:
     /// Constructor
-    ParserImplTest();
-    ~ParserImplTest() override;
+    WGSLParserTest();
+    ~WGSLParserTest() override;
 
     /// Retrieves the parser from the helper
     /// @param str the string to parse
     /// @returns the parser implementation
-    std::unique_ptr<ParserImpl> parser(const std::string& str) {
+    std::unique_ptr<Parser> parser(const std::string& str) {
         auto file = std::make_unique<Source::File>("test.wgsl", str);
-        auto impl = std::make_unique<ParserImpl>(file.get());
+        auto impl = std::make_unique<Parser>(file.get());
         impl->InitializeLex();
         files_.emplace_back(std::move(file));
         return impl;
@@ -49,18 +49,18 @@
 
 /// WGSL Parser test class with param
 template <typename T>
-class ParserImplTestWithParam : public testing::TestWithParam<T>, public ProgramBuilder {
+class WGSLParserTestWithParam : public testing::TestWithParam<T>, public ProgramBuilder {
   public:
     /// Constructor
-    ParserImplTestWithParam() = default;
-    ~ParserImplTestWithParam() override = default;
+    WGSLParserTestWithParam() = default;
+    ~WGSLParserTestWithParam() override = default;
 
     /// Retrieves the parser from the helper
     /// @param str the string to parse
     /// @returns the parser implementation
-    std::unique_ptr<ParserImpl> parser(const std::string& str) {
+    std::unique_ptr<Parser> parser(const std::string& str) {
         auto file = std::make_unique<Source::File>("test.wgsl", str);
-        auto impl = std::make_unique<ParserImpl>(file.get());
+        auto impl = std::make_unique<Parser>(file.get());
         impl->InitializeLex();
         files_.emplace_back(std::move(file));
         return impl;
@@ -70,6 +70,6 @@
     std::vector<std::unique_ptr<Source::File>> files_;
 };
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_IMPL_TEST_HELPER_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_TEST_HELPER_H_
diff --git a/src/tint/lang/wgsl/reader/token.cc b/src/tint/lang/wgsl/reader/parser/token.cc
similarity index 98%
rename from src/tint/lang/wgsl/reader/token.cc
rename to src/tint/lang/wgsl/reader/parser/token.cc
index fc7fc22..250c7cf 100644
--- a/src/tint/lang/wgsl/reader/token.cc
+++ b/src/tint/lang/wgsl/reader/parser/token.cc
@@ -12,9 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/token.h"
+#include "src/tint/lang/wgsl/reader/parser/token.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 // static
 std::string_view Token::TypeToName(Type type) {
@@ -276,4 +276,4 @@
     return std::get<int64_t>(value_);
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/token.h b/src/tint/lang/wgsl/reader/parser/token.h
similarity index 97%
rename from src/tint/lang/wgsl/reader/token.h
rename to src/tint/lang/wgsl/reader/parser/token.h
index fd2f6f9..a2a6bc2 100644
--- a/src/tint/lang/wgsl/reader/token.h
+++ b/src/tint/lang/wgsl/reader/parser/token.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_TOKEN_H_
-#define SRC_TINT_LANG_WGSL_READER_TOKEN_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_TOKEN_H_
+#define SRC_TINT_LANG_WGSL_READER_PARSER_TOKEN_H_
 
 #include <string>
 #include <string_view>
@@ -21,7 +21,7 @@
 
 #include "src/tint/utils/diagnostic/source.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 /// Stores tokens generated by the Lexer
 class Token {
@@ -364,6 +364,6 @@
     return out;
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_TOKEN_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_TOKEN_H_
diff --git a/src/tint/lang/wgsl/reader/token_test.cc b/src/tint/lang/wgsl/reader/parser/token_test.cc
similarity index 96%
rename from src/tint/lang/wgsl/reader/token_test.cc
rename to src/tint/lang/wgsl/reader/parser/token_test.cc
index 6635adb..1be56a9 100644
--- a/src/tint/lang/wgsl/reader/token_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/token_test.cc
@@ -12,13 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/token.h"
+#include "src/tint/lang/wgsl/reader/parser/token.h"
 
 #include <limits>
 
 #include "gmock/gmock.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 using ::testing::EndsWith;
@@ -95,4 +95,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_type_alias_test.cc b/src/tint/lang/wgsl/reader/parser/type_alias_test.cc
similarity index 87%
rename from src/tint/lang/wgsl/reader/parser_impl_type_alias_test.cc
rename to src/tint/lang/wgsl/reader/parser/type_alias_test.cc
index c8b8595..de66950 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_type_alias_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/type_alias_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, TypeDecl_ParsesType) {
+TEST_F(WGSLParserTest, TypeDecl_ParsesType) {
     auto p = parser("alias a = i32");
 
     auto t = p->type_alias_decl();
@@ -32,7 +32,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 14u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Parses_Ident) {
+TEST_F(WGSLParserTest, TypeDecl_Parses_Ident) {
     auto p = parser("alias a = B");
 
     auto t = p->type_alias_decl();
@@ -47,7 +47,7 @@
     EXPECT_EQ(alias->source.range, (Source::Range{{1u, 1u}, {1u, 12u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Unicode_Parses_Ident) {
+TEST_F(WGSLParserTest, TypeDecl_Unicode_Parses_Ident) {
     const std::string ident =  // "𝓶𝔂_𝓽𝔂𝓹𝓮"
         "\xf0\x9d\x93\xb6\xf0\x9d\x94\x82\x5f\xf0\x9d\x93\xbd\xf0\x9d\x94\x82\xf0"
         "\x9d\x93\xb9\xf0\x9d\x93\xae";
@@ -66,7 +66,7 @@
     EXPECT_EQ(alias->source.range, (Source::Range{{1u, 1u}, {1u, 38u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_MissingIdent) {
+TEST_F(WGSLParserTest, TypeDecl_MissingIdent) {
     auto p = parser("alias = i32");
     auto t = p->type_alias_decl();
     EXPECT_TRUE(t.errored);
@@ -76,7 +76,7 @@
     EXPECT_EQ(p->error(), R"(1:7: expected identifier for type alias)");
 }
 
-TEST_F(ParserImplTest, TypeDecl_InvalidIdent) {
+TEST_F(WGSLParserTest, TypeDecl_InvalidIdent) {
     auto p = parser("alias 123 = i32");
     auto t = p->type_alias_decl();
     EXPECT_TRUE(t.errored);
@@ -86,7 +86,7 @@
     EXPECT_EQ(p->error(), R"(1:7: expected identifier for type alias)");
 }
 
-TEST_F(ParserImplTest, TypeDecl_MissingEqual) {
+TEST_F(WGSLParserTest, TypeDecl_MissingEqual) {
     auto p = parser("alias a i32");
     auto t = p->type_alias_decl();
     EXPECT_TRUE(t.errored);
@@ -97,4 +97,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_type_decl_test.cc b/src/tint/lang/wgsl/reader/parser/type_decl_test.cc
similarity index 87%
rename from src/tint/lang/wgsl/reader/parser_impl_type_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/type_decl_test.cc
index 1de4a12..3b7684c 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_type_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/type_decl_test.cc
@@ -15,14 +15,14 @@
 #include "src/tint/lang/core/type/sampled_texture.h"
 #include "src/tint/lang/wgsl/ast/alias.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 using namespace tint::number_suffixes;  // NOLINT
 
-TEST_F(ParserImplTest, TypeDecl_Invalid) {
+TEST_F(WGSLParserTest, TypeDecl_Invalid) {
     auto p = parser("1234");
     auto t = p->type_specifier();
     EXPECT_EQ(t.errored, false);
@@ -31,7 +31,7 @@
     EXPECT_FALSE(p->has_error());
 }
 
-TEST_F(ParserImplTest, TypeDecl_Identifier) {
+TEST_F(WGSLParserTest, TypeDecl_Identifier) {
     auto p = parser("A");
 
     auto t = p->type_specifier();
@@ -42,7 +42,7 @@
     EXPECT_EQ(t->expr->source.range, (Source::Range{{1u, 1u}, {1u, 2u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Bool) {
+TEST_F(WGSLParserTest, TypeDecl_Bool) {
     auto p = parser("bool");
 
     auto t = p->type_specifier();
@@ -53,7 +53,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 5u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_F16) {
+TEST_F(WGSLParserTest, TypeDecl_F16) {
     auto p = parser("f16");
 
     auto t = p->type_specifier();
@@ -64,7 +64,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_F32) {
+TEST_F(WGSLParserTest, TypeDecl_F32) {
     auto p = parser("f32");
 
     auto t = p->type_specifier();
@@ -75,7 +75,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_I32) {
+TEST_F(WGSLParserTest, TypeDecl_I32) {
     auto p = parser("i32");
 
     auto t = p->type_specifier();
@@ -86,7 +86,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 4u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_U32) {
+TEST_F(WGSLParserTest, TypeDecl_U32) {
     auto p = parser("u32");
 
     auto t = p->type_specifier();
@@ -107,7 +107,7 @@
     return out;
 }
 
-class VecTest : public ParserImplTestWithParam<VecData> {};
+class VecTest : public WGSLParserTestWithParam<VecData> {};
 
 TEST_P(VecTest, Parse) {
     auto params = GetParam();
@@ -120,13 +120,13 @@
     ast::CheckIdentifier(t.value, ast::Template("vec" + std::to_string(params.count), "f32"));
     EXPECT_EQ(t.value->source.range, params.range);
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          VecTest,
                          testing::Values(VecData{"vec2<f32>", 2, {{1u, 1u}, {1u, 10u}}},
                                          VecData{"vec3<f32>", 3, {{1u, 1u}, {1u, 10u}}},
                                          VecData{"vec4<f32>", 4, {{1u, 1u}, {1u, 10u}}}));
 
-class VecMissingType : public ParserImplTestWithParam<VecData> {};
+class VecMissingType : public WGSLParserTestWithParam<VecData> {};
 
 TEST_P(VecMissingType, Handles_Missing_Type) {
     auto params = GetParam();
@@ -138,13 +138,13 @@
     ASSERT_TRUE(p->has_error());
     ASSERT_EQ(p->error(), "1:6: expected expression for type template argument list");
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          VecMissingType,
                          testing::Values(VecData{"vec2<>", 2, {}},
                                          VecData{"vec3<>", 3, {}},
                                          VecData{"vec4<>", 4, {}}));
 
-TEST_F(ParserImplTest, TypeDecl_Ptr) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr) {
     auto p = parser("ptr<function, f32>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -156,7 +156,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 19u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_WithAccess) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_WithAccess) {
     auto p = parser("ptr<function, f32, read>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -168,7 +168,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_ToVec) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_ToVec) {
     auto p = parser("ptr<function, vec2<f32>>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -181,7 +181,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 25}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_MissingCommaAfterAddressSpace) {
     auto p = parser("ptr<function f32>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -191,7 +191,7 @@
     ASSERT_EQ(p->error(), "1:14: expected ',' for type template argument list");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingCommaAfterAccess) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_MissingCommaAfterAccess) {
     auto p = parser("ptr<function, f32 read>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -201,7 +201,7 @@
     ASSERT_EQ(p->error(), "1:19: expected ',' for type template argument list");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingAddressSpace) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_MissingAddressSpace) {
     auto p = parser("ptr<, f32>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -211,7 +211,7 @@
     ASSERT_EQ(p->error(), R"(1:5: expected expression for type template argument list)");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
+TEST_F(WGSLParserTest, TypeDecl_Ptr_MissingParams) {
     auto p = parser("ptr<>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -221,7 +221,7 @@
     ASSERT_EQ(p->error(), R"(1:5: expected expression for type template argument list)");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Atomic) {
+TEST_F(WGSLParserTest, TypeDecl_Atomic) {
     auto p = parser("atomic<f32>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -233,7 +233,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 12u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Atomic_ToVec) {
+TEST_F(WGSLParserTest, TypeDecl_Atomic_ToVec) {
     auto p = parser("atomic<vec2<f32>>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -245,7 +245,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 18u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Atomic_MissingType) {
+TEST_F(WGSLParserTest, TypeDecl_Atomic_MissingType) {
     auto p = parser("atomic<>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -255,7 +255,7 @@
     ASSERT_EQ(p->error(), "1:8: expected expression for type template argument list");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_AbstractIntLiteralSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_AbstractIntLiteralSize) {
     auto p = parser("array<f32, 5>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -266,7 +266,7 @@
     ast::CheckIdentifier(t.value, ast::Template("array", "f32", 5_a));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_SintLiteralSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_SintLiteralSize) {
     auto p = parser("array<f32, 5i>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -277,7 +277,7 @@
     ast::CheckIdentifier(t.value, ast::Template("array", "f32", 5_i));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_UintLiteralSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_UintLiteralSize) {
     auto p = parser("array<f32, 5u>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -288,7 +288,7 @@
     ast::CheckIdentifier(t.value, ast::Template("array", "f32", 5_u));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_ConstantSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_ConstantSize) {
     auto p = parser("array<f32, size>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -299,7 +299,7 @@
     ast::CheckIdentifier(t.value, ast::Template("array", "f32", "size"));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_ExpressionSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_ExpressionSize) {
     auto p = parser("array<f32, size + 2>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -330,7 +330,7 @@
     EXPECT_EQ(count_rhs->value, static_cast<int64_t>(2));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_Runtime) {
+TEST_F(WGSLParserTest, TypeDecl_Array_Runtime) {
     auto p = parser("array<u32>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -342,7 +342,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 11u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_Runtime_Vec) {
+TEST_F(WGSLParserTest, TypeDecl_Array_Runtime_Vec) {
     auto p = parser("array<vec4<u32>>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.matched);
@@ -354,7 +354,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 17u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_BadSize) {
+TEST_F(WGSLParserTest, TypeDecl_Array_BadSize) {
     auto p = parser("array<f32, !>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -364,7 +364,7 @@
     ASSERT_EQ(p->error(), "1:13: unable to parse right side of ! expression");
 }
 
-TEST_F(ParserImplTest, TypeDecl_Array_MissingComma) {
+TEST_F(WGSLParserTest, TypeDecl_Array_MissingComma) {
     auto p = parser("array<f32 3>");
     auto t = p->type_specifier();
     EXPECT_TRUE(t.errored);
@@ -385,7 +385,7 @@
     return out;
 }
 
-class MatrixTest : public ParserImplTestWithParam<MatrixData> {};
+class MatrixTest : public WGSLParserTestWithParam<MatrixData> {};
 
 TEST_P(MatrixTest, Parse) {
     auto params = GetParam();
@@ -402,7 +402,7 @@
     ast::CheckIdentifier(t.value, ast::Template(expected_name, "f32"));
     EXPECT_EQ(t.value->source.range, params.range);
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          MatrixTest,
                          testing::Values(MatrixData{"mat2x2<f32>", 2, 2, {{1u, 1u}, {1u, 12u}}},
                                          MatrixData{"mat2x3<f32>", 2, 3, {{1u, 1u}, {1u, 12u}}},
@@ -414,7 +414,7 @@
                                          MatrixData{"mat4x3<f32>", 4, 3, {{1u, 1u}, {1u, 12u}}},
                                          MatrixData{"mat4x4<f32>", 4, 4, {{1u, 1u}, {1u, 12u}}}));
 
-class MatrixMissingType : public ParserImplTestWithParam<MatrixData> {};
+class MatrixMissingType : public WGSLParserTestWithParam<MatrixData> {};
 
 TEST_P(MatrixMissingType, Handles_Missing_Type) {
     auto params = GetParam();
@@ -426,7 +426,7 @@
     ASSERT_TRUE(p->has_error());
     ASSERT_EQ(p->error(), "1:8: expected expression for type template argument list");
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          MatrixMissingType,
                          testing::Values(MatrixData{"mat2x2<>", 2, 2, {}},
                                          MatrixData{"mat2x3<>", 2, 3, {}},
@@ -438,7 +438,7 @@
                                          MatrixData{"mat4x3<>", 4, 3, {}},
                                          MatrixData{"mat4x4<>", 4, 4, {}}));
 
-TEST_F(ParserImplTest, TypeDecl_Sampler) {
+TEST_F(WGSLParserTest, TypeDecl_Sampler) {
     auto p = parser("sampler");
 
     auto t = p->type_specifier();
@@ -450,7 +450,7 @@
     EXPECT_EQ(t.value->source.range, (Source::Range{{1u, 1u}, {1u, 8u}}));
 }
 
-TEST_F(ParserImplTest, TypeDecl_Texture) {
+TEST_F(WGSLParserTest, TypeDecl_Texture) {
     auto p = parser("texture_cube<f32>");
 
     auto t = p->type_specifier();
@@ -463,4 +463,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_unary_expression_test.cc b/src/tint/lang/wgsl/reader/parser/unary_expression_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_unary_expression_test.cc
rename to src/tint/lang/wgsl/reader/parser/unary_expression_test.cc
index 0f5201f..6877572 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_unary_expression_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/unary_expression_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/unary_op_expression.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, UnaryExpression_Postix) {
+TEST_F(WGSLParserTest, UnaryExpression_Postix) {
     auto p = parser("a[2]");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -38,7 +38,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Minus) {
+TEST_F(WGSLParserTest, UnaryExpression_Minus) {
     auto p = parser("- 1");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -56,7 +56,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, UnaryExpression_AddressOf) {
+TEST_F(WGSLParserTest, UnaryExpression_AddressOf) {
     auto p = parser("&x");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -70,7 +70,7 @@
     EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Dereference) {
+TEST_F(WGSLParserTest, UnaryExpression_Dereference) {
     auto p = parser("*x");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -84,7 +84,7 @@
     EXPECT_TRUE(u->expr->Is<ast::IdentifierExpression>());
 }
 
-TEST_F(ParserImplTest, UnaryExpression_AddressOf_Precedence) {
+TEST_F(WGSLParserTest, UnaryExpression_AddressOf_Precedence) {
     auto p = parser("&x.y");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -98,7 +98,7 @@
     EXPECT_TRUE(u->expr->Is<ast::MemberAccessorExpression>());
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Dereference_Precedence) {
+TEST_F(WGSLParserTest, UnaryExpression_Dereference_Precedence) {
     auto p = parser("*x.y");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -112,7 +112,7 @@
     EXPECT_TRUE(u->expr->Is<ast::MemberAccessorExpression>());
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Minus_InvalidRHS) {
+TEST_F(WGSLParserTest, UnaryExpression_Minus_InvalidRHS) {
     auto p = parser("-if(a) {}");
     auto e = p->unary_expression();
     EXPECT_FALSE(e.matched);
@@ -122,7 +122,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse right side of - expression");
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Bang) {
+TEST_F(WGSLParserTest, UnaryExpression_Bang) {
     auto p = parser("!1");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -140,7 +140,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Bang_InvalidRHS) {
+TEST_F(WGSLParserTest, UnaryExpression_Bang_InvalidRHS) {
     auto p = parser("!if (a) {}");
     auto e = p->unary_expression();
     EXPECT_FALSE(e.matched);
@@ -150,7 +150,7 @@
     EXPECT_EQ(p->error(), "1:2: unable to parse right side of ! expression");
 }
 
-TEST_F(ParserImplTest, UnaryExpression_Tilde) {
+TEST_F(WGSLParserTest, UnaryExpression_Tilde) {
     auto p = parser("~1");
     auto e = p->unary_expression();
     EXPECT_TRUE(e.matched);
@@ -168,7 +168,7 @@
               ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, UnaryExpression_PrefixPlusPlus) {
+TEST_F(WGSLParserTest, UnaryExpression_PrefixPlusPlus) {
     auto p = parser("++a");
     auto e = p->unary_expression();
     EXPECT_FALSE(e.matched);
@@ -180,7 +180,7 @@
               "future WGSL version");
 }
 
-TEST_F(ParserImplTest, UnaryExpression_PrefixMinusMinus) {
+TEST_F(WGSLParserTest, UnaryExpression_PrefixMinusMinus) {
     auto p = parser("--a");
     auto e = p->unary_expression();
     EXPECT_FALSE(e.matched);
@@ -193,4 +193,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_attribute_list_test.cc b/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
similarity index 89%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_attribute_list_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
index a888506..9e96959 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_attribute_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, AttributeList_Parses) {
+TEST_F(WGSLParserTest, AttributeList_Parses) {
     auto p = parser(R"(@location(4) @builtin(position))");
     auto attrs = p->attribute_list();
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -42,7 +42,7 @@
     ast::CheckIdentifier(attr_1->As<ast::BuiltinAttribute>()->builtin, "position");
 }
 
-TEST_F(ParserImplTest, AttributeList_Invalid) {
+TEST_F(WGSLParserTest, AttributeList_Invalid) {
     auto p = parser(R"(@invalid)");
     auto attrs = p->attribute_list();
     EXPECT_TRUE(p->has_error());
@@ -55,4 +55,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_attribute_test.cc b/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
similarity index 88%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_attribute_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
index 0310053..35c8460 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_attribute_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
@@ -14,12 +14,12 @@
 
 #include "src/tint/lang/core/builtin/builtin_value.h"
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, Attribute_Id) {
+TEST_F(WGSLParserTest, Attribute_Id) {
     auto p = parser("id(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -36,7 +36,7 @@
     EXPECT_EQ(exp->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Id_Expression) {
+TEST_F(WGSLParserTest, Attribute_Id_Expression) {
     auto p = parser("id(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -61,7 +61,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_Id_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Id_TrailingComma) {
     auto p = parser("id(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -78,7 +78,7 @@
     EXPECT_EQ(exp->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Id_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Id_MissingLeftParen) {
     auto p = parser("id 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -88,7 +88,7 @@
     EXPECT_EQ(p->error(), "1:4: expected '(' for id attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Id_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Id_MissingRightParen) {
     auto p = parser("id(4");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -98,7 +98,7 @@
     EXPECT_EQ(p->error(), "1:5: expected ')' for id attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Id_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Id_MissingValue) {
     auto p = parser("id()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -108,7 +108,7 @@
     EXPECT_EQ(p->error(), "1:1: id expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Id_MissingInvalid) {
+TEST_F(WGSLParserTest, Attribute_Id_MissingInvalid) {
     auto p = parser("id(if)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -118,7 +118,7 @@
     EXPECT_EQ(p->error(), "1:4: expected expression for id");
 }
 
-TEST_F(ParserImplTest, Attribute_Location) {
+TEST_F(WGSLParserTest, Attribute_Location) {
     auto p = parser("location(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -135,7 +135,7 @@
     EXPECT_EQ(exp->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Location_Expression) {
+TEST_F(WGSLParserTest, Attribute_Location_Expression) {
     auto p = parser("location(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -160,7 +160,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_Location_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Location_TrailingComma) {
     auto p = parser("location(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -177,7 +177,7 @@
     EXPECT_EQ(exp->value, 4u);
 }
 
-TEST_F(ParserImplTest, Attribute_Location_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Location_MissingLeftParen) {
     auto p = parser("location 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -187,7 +187,7 @@
     EXPECT_EQ(p->error(), "1:10: expected '(' for location attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Location_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Location_MissingRightParen) {
     auto p = parser("location(4");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -197,7 +197,7 @@
     EXPECT_EQ(p->error(), "1:11: expected ')' for location attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Location_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Location_MissingValue) {
     auto p = parser("location()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -207,7 +207,7 @@
     EXPECT_EQ(p->error(), "1:1: location expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Location_MissingInvalid) {
+TEST_F(WGSLParserTest, Attribute_Location_MissingInvalid) {
     auto p = parser("location(if)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -217,7 +217,7 @@
     EXPECT_EQ(p->error(), "1:10: expected expression for location");
 }
 
-class BuiltinTest : public ParserImplTestWithParam<builtin::BuiltinValue> {};
+class BuiltinTest : public WGSLParserTestWithParam<builtin::BuiltinValue> {};
 
 TEST_P(BuiltinTest, Attribute_Builtin) {
     auto str = utils::ToString(GetParam());
@@ -251,7 +251,7 @@
     auto* builtin = var_attr->As<ast::BuiltinAttribute>();
     ast::CheckIdentifier(builtin->builtin, str);
 }
-INSTANTIATE_TEST_SUITE_P(ParserImplTest,
+INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
                          BuiltinTest,
                          testing::Values(builtin::BuiltinValue::kPosition,
                                          builtin::BuiltinValue::kVertexIndex,
@@ -266,7 +266,7 @@
                                          builtin::BuiltinValue::kSampleIndex,
                                          builtin::BuiltinValue::kSampleMask));
 
-TEST_F(ParserImplTest, Attribute_Builtin_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Builtin_MissingLeftParen) {
     auto p = parser("builtin position)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -276,7 +276,7 @@
     EXPECT_EQ(p->error(), "1:9: expected '(' for builtin attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Builtin_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Builtin_MissingRightParen) {
     auto p = parser("builtin(position");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -286,7 +286,7 @@
     EXPECT_EQ(p->error(), "1:17: expected ')' for builtin attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Builtin_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Builtin_MissingValue) {
     auto p = parser("builtin()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -296,7 +296,7 @@
     EXPECT_EQ(p->error(), "1:1: builtin expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Flat) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Flat) {
     auto p = parser("interpolate(flat)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -312,7 +312,7 @@
     EXPECT_EQ(interp->sampling, nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Single_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Single_TrailingComma) {
     auto p = parser("interpolate(flat,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -328,7 +328,7 @@
     EXPECT_EQ(interp->sampling, nullptr);
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Single_DoubleTrailingComma) {
     auto p = parser("interpolate(flat,,)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -338,7 +338,7 @@
     EXPECT_EQ(p->error(), "1:18: expected expression for interpolate");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Center) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Perspective_Center) {
     auto p = parser("interpolate(perspective, center)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -354,7 +354,7 @@
     ast::CheckIdentifier(interp->sampling, "center");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Double_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Double_TrailingComma) {
     auto p = parser("interpolate(perspective, center,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -370,7 +370,7 @@
     ast::CheckIdentifier(interp->sampling, "center");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Perspective_Centroid) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Perspective_Centroid) {
     auto p = parser("interpolate(perspective, centroid)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -386,7 +386,7 @@
     ast::CheckIdentifier(interp->sampling, "centroid");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_Linear_Sample) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_Linear_Sample) {
     auto p = parser("interpolate(linear, sample)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -402,7 +402,7 @@
     ast::CheckIdentifier(interp->sampling, "sample");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_MissingLeftParen) {
     auto p = parser("interpolate flat)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -412,7 +412,7 @@
     EXPECT_EQ(p->error(), "1:13: expected '(' for interpolate attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_MissingRightParen) {
     auto p = parser("interpolate(flat");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -422,7 +422,7 @@
     EXPECT_EQ(p->error(), "1:17: expected ')' for interpolate attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Interpolate_MissingFirstValue) {
+TEST_F(WGSLParserTest, Attribute_Interpolate_MissingFirstValue) {
     auto p = parser("interpolate()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -432,7 +432,7 @@
     EXPECT_EQ(p->error(), "1:1: interpolate expects at least 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Binding) {
+TEST_F(WGSLParserTest, Attribute_Binding) {
     auto p = parser("binding(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -450,7 +450,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_Expression) {
+TEST_F(WGSLParserTest, Attribute_Binding_Expression) {
     auto p = parser("binding(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -475,7 +475,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_Binding_TrailingComma) {
     auto p = parser("binding(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -493,7 +493,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Binding_MissingLeftParen) {
     auto p = parser("binding 4)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -503,7 +503,7 @@
     EXPECT_EQ(p->error(), "1:9: expected '(' for binding attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Binding_MissingRightParen) {
     auto p = parser("binding(4");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -513,7 +513,7 @@
     EXPECT_EQ(p->error(), "1:10: expected ')' for binding attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Binding_MissingValue) {
     auto p = parser("binding()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -523,7 +523,7 @@
     EXPECT_EQ(p->error(), "1:1: binding expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Binding_MissingInvalid) {
+TEST_F(WGSLParserTest, Attribute_Binding_MissingInvalid) {
     auto p = parser("binding(if)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -533,7 +533,7 @@
     EXPECT_EQ(p->error(), "1:9: expected expression for binding");
 }
 
-TEST_F(ParserImplTest, Attribute_group) {
+TEST_F(WGSLParserTest, Attribute_group) {
     auto p = parser("group(4)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -551,7 +551,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_group_expression) {
+TEST_F(WGSLParserTest, Attribute_group_expression) {
     auto p = parser("group(4 + 5)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -576,7 +576,7 @@
     EXPECT_EQ(v->value, 5u);
 }
 
-TEST_F(ParserImplTest, Attribute_group_TrailingComma) {
+TEST_F(WGSLParserTest, Attribute_group_TrailingComma) {
     auto p = parser("group(4,)");
     auto attr = p->attribute();
     EXPECT_TRUE(attr.matched);
@@ -594,7 +594,7 @@
     EXPECT_EQ(expr->suffix, ast::IntLiteralExpression::Suffix::kNone);
 }
 
-TEST_F(ParserImplTest, Attribute_Group_MissingLeftParen) {
+TEST_F(WGSLParserTest, Attribute_Group_MissingLeftParen) {
     auto p = parser("group 2)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -604,7 +604,7 @@
     EXPECT_EQ(p->error(), "1:7: expected '(' for group attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Group_MissingRightParen) {
+TEST_F(WGSLParserTest, Attribute_Group_MissingRightParen) {
     auto p = parser("group(2");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -614,7 +614,7 @@
     EXPECT_EQ(p->error(), "1:8: expected ')' for group attribute");
 }
 
-TEST_F(ParserImplTest, Attribute_Group_MissingValue) {
+TEST_F(WGSLParserTest, Attribute_Group_MissingValue) {
     auto p = parser("group()");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -624,7 +624,7 @@
     EXPECT_EQ(p->error(), "1:1: group expects 1 argument");
 }
 
-TEST_F(ParserImplTest, Attribute_Group_MissingInvalid) {
+TEST_F(WGSLParserTest, Attribute_Group_MissingInvalid) {
     auto p = parser("group(if)");
     auto attr = p->attribute();
     EXPECT_FALSE(attr.matched);
@@ -635,4 +635,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_decl_test.cc b/src/tint/lang/wgsl/reader/parser/variable_decl_test.cc
similarity index 87%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_decl_test.cc
index 8448452..70e7c31 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_decl_test.cc
@@ -13,11 +13,11 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
-TEST_F(ParserImplTest, VariableDecl_Parses) {
+TEST_F(WGSLParserTest, VariableDecl_Parses) {
     auto p = parser("var my_var : f32");
     auto v = p->variable_decl();
     EXPECT_FALSE(p->has_error());
@@ -32,7 +32,7 @@
     EXPECT_EQ(v->type->source.range, (Source::Range{{1u, 14u}, {1u, 17u}}));
 }
 
-TEST_F(ParserImplTest, VariableDecl_Unicode_Parses) {
+TEST_F(WGSLParserTest, VariableDecl_Unicode_Parses) {
     const std::string ident =  // "𝖎𝖉𝖊𝖓𝖙𝖎𝖋𝖎𝖊𝖗123"
         "\xf0\x9d\x96\x8e\xf0\x9d\x96\x89\xf0\x9d\x96\x8a\xf0\x9d\x96\x93"
         "\xf0\x9d\x96\x99\xf0\x9d\x96\x8e\xf0\x9d\x96\x8b\xf0\x9d\x96\x8e"
@@ -52,7 +52,7 @@
     EXPECT_EQ(v->type->source.range, (Source::Range{{1u, 51u}, {1u, 54u}}));
 }
 
-TEST_F(ParserImplTest, VariableDecl_Inferred_Parses) {
+TEST_F(WGSLParserTest, VariableDecl_Inferred_Parses) {
     auto p = parser("var my_var = 1.0");
     auto v = p->variable_decl();
     EXPECT_FALSE(p->has_error());
@@ -64,7 +64,7 @@
     EXPECT_EQ(v->source.range, (Source::Range{{1u, 5u}, {1u, 11u}}));
 }
 
-TEST_F(ParserImplTest, VariableDecl_MissingVar) {
+TEST_F(WGSLParserTest, VariableDecl_MissingVar) {
     auto p = parser("my_var : f32");
     auto v = p->variable_decl();
     EXPECT_FALSE(v.matched);
@@ -75,7 +75,7 @@
     ASSERT_TRUE(t.IsIdentifier());
 }
 
-TEST_F(ParserImplTest, VariableDecl_WithAddressSpace) {
+TEST_F(WGSLParserTest, VariableDecl_WithAddressSpace) {
     auto p = parser("var<private> my_var : f32");
     auto v = p->variable_decl();
     EXPECT_TRUE(v.matched);
@@ -92,7 +92,7 @@
     EXPECT_EQ(v->source.range.end.column, 20u);
 }
 
-TEST_F(ParserImplTest, VariableDecl_WithPushConstant) {
+TEST_F(WGSLParserTest, VariableDecl_WithPushConstant) {
     auto p = parser("var<push_constant> my_var : f32");
     auto v = p->variable_decl();
     EXPECT_TRUE(v.matched);
@@ -105,4 +105,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_ident_decl_test.cc b/src/tint/lang/wgsl/reader/parser/variable_ident_decl_test.cc
similarity index 82%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_ident_decl_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_ident_decl_test.cc
index 0891ca4..245b28e 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_ident_decl_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_ident_decl_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, VariableIdentDecl_Parses) {
+TEST_F(WGSLParserTest, VariableIdentDecl_Parses) {
     auto p = parser("my_var : f32");
     auto decl = p->expect_ident_with_type_specifier("test");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -31,7 +31,7 @@
     EXPECT_EQ(decl->type->source.range, (Source::Range{{1u, 10u}, {1u, 13u}}));
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_Parses_AllowInferredType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_Parses_AllowInferredType) {
     auto p = parser("my_var : f32");
     auto decl = p->expect_optionally_typed_ident("test");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -44,14 +44,14 @@
     EXPECT_EQ(decl->type->source.range, (Source::Range{{1u, 10u}, {1u, 13u}}));
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parse_Failure) {
+TEST_F(WGSLParserTest, VariableIdentDecl_Inferred_Parse_Failure) {
     auto p = parser("my_var = 1.0");
     auto decl = p->expect_ident_with_type_specifier("test");
     ASSERT_TRUE(p->has_error());
     ASSERT_EQ(p->error(), "1:8: expected ':' for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_Inferred_Parses_AllowInferredType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_Inferred_Parses_AllowInferredType) {
     auto p = parser("my_var = 1.0");
     auto decl = p->expect_optionally_typed_ident("test");
     ASSERT_FALSE(p->has_error()) << p->error();
@@ -62,7 +62,7 @@
     EXPECT_EQ(decl->name->source.range, (Source::Range{{1u, 1u}, {1u, 7u}}));
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent) {
+TEST_F(WGSLParserTest, VariableIdentDecl_MissingIdent) {
     auto p = parser(": f32");
     auto decl = p->expect_ident_with_type_specifier("test");
     ASSERT_TRUE(p->has_error());
@@ -70,7 +70,7 @@
     ASSERT_EQ(p->error(), "1:1: expected identifier for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_MissingIdent_AllowInferredType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_MissingIdent_AllowInferredType) {
     auto p = parser(": f32");
     auto decl = p->expect_optionally_typed_ident("test");
     ASSERT_TRUE(p->has_error());
@@ -78,7 +78,7 @@
     ASSERT_EQ(p->error(), "1:1: expected identifier for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_MissingType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_MissingType) {
     auto p = parser("my_var :");
     auto decl = p->expect_ident_with_type_specifier("test");
     ASSERT_TRUE(p->has_error());
@@ -86,7 +86,7 @@
     ASSERT_EQ(p->error(), "1:9: invalid type for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_MissingType_AllowInferredType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_MissingType_AllowInferredType) {
     auto p = parser("my_var :");
     auto decl = p->expect_optionally_typed_ident("test");
     ASSERT_TRUE(p->has_error());
@@ -94,7 +94,7 @@
     ASSERT_EQ(p->error(), "1:9: invalid type for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent) {
+TEST_F(WGSLParserTest, VariableIdentDecl_InvalidIdent) {
     auto p = parser("123 : f32");
     auto decl = p->expect_ident_with_type_specifier("test");
     ASSERT_TRUE(p->has_error());
@@ -102,7 +102,7 @@
     ASSERT_EQ(p->error(), "1:1: expected identifier for test");
 }
 
-TEST_F(ParserImplTest, VariableIdentDecl_InvalidIdent_AllowInferredType) {
+TEST_F(WGSLParserTest, VariableIdentDecl_InvalidIdent_AllowInferredType) {
     auto p = parser("123 : f32");
     auto decl = p->expect_optionally_typed_ident("test");
     ASSERT_TRUE(p->has_error());
@@ -111,4 +111,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_qualifier_test.cc b/src/tint/lang/wgsl/reader/parser/variable_qualifier_test.cc
similarity index 89%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_qualifier_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_qualifier_test.cc
index ccfc78c..8f792ab 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_qualifier_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_qualifier_test.cc
@@ -13,9 +13,9 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 struct VariableStorageData {
@@ -28,7 +28,7 @@
     return out;
 }
 
-class VariableQualifierTest : public ParserImplTestWithParam<VariableStorageData> {};
+class VariableQualifierTest : public WGSLParserTestWithParam<VariableStorageData> {};
 
 TEST_P(VariableQualifierTest, ParsesAddressSpace) {
     auto params = GetParam();
@@ -53,7 +53,7 @@
     EXPECT_TRUE(t.IsEof());
 }
 INSTANTIATE_TEST_SUITE_P(
-    ParserImplTest,
+    WGSLParserTest,
     VariableQualifierTest,
     testing::Values(VariableStorageData{"uniform", builtin::AddressSpace::kUniform,
                                         builtin::Access::kUndefined},
@@ -72,7 +72,7 @@
                     VariableStorageData{"storage, read_write", builtin::AddressSpace::kStorage,
                                         builtin::Access::kReadWrite}));
 
-TEST_F(ParserImplTest, VariableQualifier_Empty) {
+TEST_F(WGSLParserTest, VariableQualifier_Empty) {
     auto p = parser("var<> name");
     auto sc = p->variable_decl();
     EXPECT_TRUE(p->has_error());
@@ -81,7 +81,7 @@
     EXPECT_EQ(p->error(), R"(1:5: expected expression for 'var' address space)");
 }
 
-TEST_F(ParserImplTest, VariableQualifier_MissingLessThan) {
+TEST_F(WGSLParserTest, VariableQualifier_MissingLessThan) {
     auto p = parser("private>");
     auto sc = p->variable_qualifier();
     EXPECT_FALSE(p->has_error());
@@ -92,7 +92,7 @@
     ASSERT_TRUE(t.Is(Token::Type::kIdentifier));
 }
 
-TEST_F(ParserImplTest, VariableQualifier_MissingLessThan_AfterSC) {
+TEST_F(WGSLParserTest, VariableQualifier_MissingLessThan_AfterSC) {
     auto p = parser("private, >");
     auto sc = p->variable_qualifier();
     EXPECT_FALSE(p->has_error());
@@ -103,7 +103,7 @@
     ASSERT_TRUE(t.Is(Token::Type::kIdentifier));
 }
 
-TEST_F(ParserImplTest, VariableQualifier_MissingGreaterThan) {
+TEST_F(WGSLParserTest, VariableQualifier_MissingGreaterThan) {
     auto p = parser("<private");
     auto sc = p->variable_qualifier();
     EXPECT_TRUE(p->has_error());
@@ -113,4 +113,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_variable_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/variable_stmt_test.cc
similarity index 89%
rename from src/tint/lang/wgsl/reader/parser_impl_variable_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/variable_stmt_test.cc
index 06b1f74..3db2df1 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_variable_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_stmt_test.cc
@@ -13,12 +13,12 @@
 // limitations under the License.
 
 #include "src/tint/lang/wgsl/ast/test_helper.h"
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl) {
     auto p = parser("var a : i32;");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -37,7 +37,7 @@
     EXPECT_EQ(e->variable->initializer, nullptr);
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_WithInit) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_WithInit) {
     auto p = parser("var a : i32 = 1;");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -57,7 +57,7 @@
     EXPECT_TRUE(e->variable->initializer->Is<ast::LiteralExpression>());
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_InitializerInvalid) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_InitializerInvalid) {
     auto p = parser("var a : i32 = if(a) {}");
     auto e = p->variable_statement();
     EXPECT_FALSE(e.matched);
@@ -67,7 +67,7 @@
     EXPECT_EQ(p->error(), "1:15: missing initializer for 'var' declaration");
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_ArrayInit) {
     auto p = parser("var a : array<i32> = array<i32>();");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -84,7 +84,7 @@
     ast::CheckIdentifier(call->target, ast::Template("array", "i32"));
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_ArrayInit_NoSpace) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_ArrayInit_NoSpace) {
     auto p = parser("var a : array<i32>=array<i32>();");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -101,7 +101,7 @@
     ast::CheckIdentifier(call->target, ast::Template("array", "i32"));
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_VecInit) {
     auto p = parser("var a : vec2<i32> = vec2<i32>();");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -117,7 +117,7 @@
     ast::CheckIdentifier(call->target, ast::Template("vec2", "i32"));
 }
 
-TEST_F(ParserImplTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
+TEST_F(WGSLParserTest, VariableStmt_VariableDecl_VecInit_NoSpace) {
     auto p = parser("var a : vec2<i32>=vec2<i32>();");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -134,7 +134,7 @@
     ast::CheckIdentifier(call->target, ast::Template("vec2", "i32"));
 }
 
-TEST_F(ParserImplTest, VariableStmt_Let) {
+TEST_F(WGSLParserTest, VariableStmt_Let) {
     auto p = parser("let a : i32 = 1");
     auto e = p->variable_statement();
     EXPECT_TRUE(e.matched);
@@ -149,7 +149,7 @@
     EXPECT_EQ(e->source.range.end.column, 12u);
 }
 
-TEST_F(ParserImplTest, VariableStmt_Let_ComplexExpression) {
+TEST_F(WGSLParserTest, VariableStmt_Let_ComplexExpression) {
     auto p = parser("let x = collide + collide_1;");
     // Parse as `statement` to validate the `;` at the end so we know we parsed the whole expression
     auto e = p->statement();
@@ -175,7 +175,7 @@
     ast::CheckIdentifier(ident_expr->identifier, "collide_1");
 }
 
-TEST_F(ParserImplTest, VariableStmt_Let_MissingEqual) {
+TEST_F(WGSLParserTest, VariableStmt_Let_MissingEqual) {
     auto p = parser("let a : i32 1");
     auto e = p->variable_statement();
     EXPECT_FALSE(e.matched);
@@ -185,7 +185,7 @@
     EXPECT_EQ(p->error(), "1:13: expected '=' for 'let' declaration");
 }
 
-TEST_F(ParserImplTest, VariableStmt_Let_MissingInitializer) {
+TEST_F(WGSLParserTest, VariableStmt_Let_MissingInitializer) {
     auto p = parser("let a : i32 =");
     auto e = p->variable_statement();
     EXPECT_FALSE(e.matched);
@@ -195,7 +195,7 @@
     EXPECT_EQ(p->error(), "1:14: missing initializer for 'let' declaration");
 }
 
-TEST_F(ParserImplTest, VariableStmt_Let_InvalidInitializer) {
+TEST_F(WGSLParserTest, VariableStmt_Let_InvalidInitializer) {
     auto p = parser("let a : i32 = if (a) {}");
     auto e = p->variable_statement();
     EXPECT_FALSE(e.matched);
@@ -206,4 +206,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_impl_while_stmt_test.cc b/src/tint/lang/wgsl/reader/parser/while_stmt_test.cc
similarity index 92%
rename from src/tint/lang/wgsl/reader/parser_impl_while_stmt_test.cc
rename to src/tint/lang/wgsl/reader/parser/while_stmt_test.cc
index f38669a..ffda977 100644
--- a/src/tint/lang/wgsl/reader/parser_impl_while_stmt_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/while_stmt_test.cc
@@ -12,19 +12,19 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser_impl_test_helper.h"
+#include "src/tint/lang/wgsl/reader/parser/test_helper.h"
 
 #include "src/tint/lang/wgsl/ast/discard_statement.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
-using WhileStmtTest = ParserImplTest;
+using WhileStmtTest = WGSLParserTest;
 
 // Test an empty while loop.
 TEST_F(WhileStmtTest, Empty) {
     auto p = parser("while true { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto wl = p->while_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(wl.errored);
@@ -36,7 +36,7 @@
 // Test an empty while loop with parentheses.
 TEST_F(WhileStmtTest, EmptyWithParentheses) {
     auto p = parser("while (true) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto wl = p->while_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(wl.errored);
@@ -48,7 +48,7 @@
 // Test a while loop with non-empty body.
 TEST_F(WhileStmtTest, Body) {
     auto p = parser("while (true) { discard; }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto wl = p->while_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(wl.errored);
@@ -61,7 +61,7 @@
 // Test a while loop with complex condition.
 TEST_F(WhileStmtTest, ComplexCondition) {
     auto p = parser("while (a + 1 - 2) == 3 { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto wl = p->while_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(wl.errored);
@@ -73,7 +73,7 @@
 // Test a while loop with complex condition, with parentheses.
 TEST_F(WhileStmtTest, ComplexConditionWithParentheses) {
     auto p = parser("while ((a + 1 - 2) == 3) { }");
-    ParserImpl::AttributeList attrs;
+    Parser::AttributeList attrs;
     auto wl = p->while_statement(attrs);
     EXPECT_FALSE(p->has_error()) << p->error();
     EXPECT_FALSE(wl.errored);
@@ -96,11 +96,11 @@
     EXPECT_TRUE(wl->attributes[0]->Is<ast::DiagnosticAttribute>());
 }
 
-class WhileStmtErrorTest : public ParserImplTest {
+class WhileStmtErrorTest : public WGSLParserTest {
   public:
     void TestWhileWithError(std::string for_str, std::string error_str) {
         auto p_for = parser(for_str);
-        ParserImpl::AttributeList attrs;
+        Parser::AttributeList attrs;
         auto e_for = p_for->while_statement(attrs);
 
         EXPECT_FALSE(e_for.matched);
@@ -185,4 +185,4 @@
 }
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser_test.cc b/src/tint/lang/wgsl/reader/parser_test.cc
deleted file mode 100644
index 12c37f9..0000000
--- a/src/tint/lang/wgsl/reader/parser_test.cc
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2020 The Tint Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "src/tint/lang/wgsl/reader/parser.h"
-
-#include "gtest/gtest.h"
-
-#include "src/tint/lang/wgsl/ast/module.h"
-
-namespace tint::reader::wgsl {
-namespace {
-
-using ParserTest = testing::Test;
-
-TEST_F(ParserTest, Empty) {
-    Source::File file("test.wgsl", "");
-    auto program = Parse(&file);
-    auto errs = diag::Formatter().format(program.Diagnostics());
-    ASSERT_TRUE(program.IsValid()) << errs;
-}
-
-TEST_F(ParserTest, Parses) {
-    Source::File file("test.wgsl", R"(
-@fragment
-fn main() -> @location(0) vec4<f32> {
-  return vec4<f32>(.4, .2, .3, 1.);
-}
-)");
-    auto program = Parse(&file);
-    auto errs = diag::Formatter().format(program.Diagnostics());
-    ASSERT_TRUE(program.IsValid()) << errs;
-
-    ASSERT_EQ(1u, program.AST().Functions().Length());
-}
-
-TEST_F(ParserTest, HandlesError) {
-    Source::File file("test.wgsl", R"(
-fn main() ->  {  // missing return type
-  return;
-})");
-
-    auto program = Parse(&file);
-    auto errs = diag::Formatter().format(program.Diagnostics());
-    ASSERT_FALSE(program.IsValid()) << errs;
-    EXPECT_EQ(errs,
-              R"(test.wgsl:2:15 error: unable to determine function return type
-fn main() ->  {  // missing return type
-              ^
-
-)");
-}
-
-}  // namespace
-}  // namespace tint::reader::wgsl
diff --git a/src/tint/lang/wgsl/reader/parser.cc b/src/tint/lang/wgsl/reader/reader.cc
similarity index 79%
rename from src/tint/lang/wgsl/reader/parser.cc
rename to src/tint/lang/wgsl/reader/reader.cc
index c8a318a7..f41cdce 100644
--- a/src/tint/lang/wgsl/reader/parser.cc
+++ b/src/tint/lang/wgsl/reader/reader.cc
@@ -12,18 +12,18 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 
 #include <utility>
 
-#include "src/tint/lang/wgsl/reader/parser_impl.h"
+#include "src/tint/lang/wgsl/reader/parser/parser.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 Program Parse(Source::File const* file) {
-    ParserImpl parser(file);
+    Parser parser(file);
     parser.Parse();
     return Program(std::move(parser.builder()));
 }
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/parser.h b/src/tint/lang/wgsl/reader/reader.h
similarity index 82%
rename from src/tint/lang/wgsl/reader/parser.h
rename to src/tint/lang/wgsl/reader/reader.h
index 14bc7ba..4c96cb0 100644
--- a/src/tint/lang/wgsl/reader/parser.h
+++ b/src/tint/lang/wgsl/reader/reader.h
@@ -12,12 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_H_
-#define SRC_TINT_LANG_WGSL_READER_PARSER_H_
+#ifndef SRC_TINT_LANG_WGSL_READER_READER_H_
+#define SRC_TINT_LANG_WGSL_READER_READER_H_
 
 #include "src/tint/lang/wgsl/program/program.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 
 /// Parses the WGSL source, returning the parsed program.
 /// If the source fails to parse then the returned
@@ -27,6 +27,6 @@
 /// @returns the parsed program
 Program Parse(Source::File const* file);
 
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
 
-#endif  // SRC_TINT_LANG_WGSL_READER_PARSER_H_
+#endif  // SRC_TINT_LANG_WGSL_READER_READER_H_
diff --git a/src/tint/lang/wgsl/reader/parser_bench.cc b/src/tint/lang/wgsl/reader/reader_bench.cc
similarity index 94%
rename from src/tint/lang/wgsl/reader/parser_bench.cc
rename to src/tint/lang/wgsl/reader/reader_bench.cc
index a7a04d6..9ba155d 100644
--- a/src/tint/lang/wgsl/reader/parser_bench.cc
+++ b/src/tint/lang/wgsl/reader/reader_bench.cc
@@ -16,7 +16,7 @@
 
 #include "src/tint/bench/benchmark.h"
 
-namespace tint::reader::wgsl {
+namespace tint::wgsl::reader {
 namespace {
 
 void ParseWGSL(benchmark::State& state, std::string input_name) {
@@ -37,4 +37,4 @@
 TINT_BENCHMARK_PROGRAMS(ParseWGSL);
 
 }  // namespace
-}  // namespace tint::reader::wgsl
+}  // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/resolver/const_eval_binary_op_test.cc b/src/tint/lang/wgsl/resolver/const_eval_binary_op_test.cc
index f94114b..6dcb4bd 100644
--- a/src/tint/lang/wgsl/resolver/const_eval_binary_op_test.cc
+++ b/src/tint/lang/wgsl/resolver/const_eval_binary_op_test.cc
@@ -14,7 +14,7 @@
 
 #include "src/tint/lang/wgsl/resolver/const_eval_test.h"
 
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/utils/result/result.h"
 
 using namespace tint::builtin::fluent_types;  // NOLINT
@@ -2162,7 +2162,7 @@
 )";
 
     auto file = std::make_unique<Source::File>("test", src);
-    auto program = reader::wgsl::Parse(file.get());
+    auto program = wgsl::reader::Parse(file.get());
     EXPECT_FALSE(program.IsValid());
 
     diag::Formatter::Style style;
@@ -2183,7 +2183,7 @@
 )";
 
     auto file = std::make_unique<Source::File>("test", src);
-    auto program = reader::wgsl::Parse(file.get());
+    auto program = wgsl::reader::Parse(file.get());
     EXPECT_FALSE(program.IsValid());
 
     diag::Formatter::Style style;
@@ -2393,7 +2393,7 @@
 const result = )");
     src = src + expr + ";";
     auto file = std::make_unique<Source::File>("test", src);
-    auto program = reader::wgsl::Parse(file.get());
+    auto program = wgsl::reader::Parse(file.get());
 
     if (should_pass) {
         diag::Formatter::Style style;
diff --git a/src/tint/lang/wgsl/resolver/uniformity_test.cc b/src/tint/lang/wgsl/resolver/uniformity_test.cc
index 8db80cb..8977062 100644
--- a/src/tint/lang/wgsl/resolver/uniformity_test.cc
+++ b/src/tint/lang/wgsl/resolver/uniformity_test.cc
@@ -18,7 +18,7 @@
 #include <utility>
 
 #include "src/tint/lang/wgsl/program/program_builder.h"
-#include "src/tint/lang/wgsl/reader/parser.h"
+#include "src/tint/lang/wgsl/reader/reader.h"
 #include "src/tint/lang/wgsl/resolver/uniformity.h"
 #include "src/tint/utils/text/string_stream.h"
 
@@ -59,7 +59,7 @@
     /// @param should_pass true if `src` should pass the analysis, otherwise false
     void RunTest(std::string src, bool should_pass) {
         auto file = std::make_unique<Source::File>("test", src);
-        auto program = reader::wgsl::Parse(file.get());
+        auto program = wgsl::reader::Parse(file.get());
         return RunTest(std::move(program), should_pass);
     }