wsgl parser: expect for storage_class

All the call sites of `storage_class()` add their own error handling, so transform this into `expect_storage_class()`.

Also makes error messages more consistent.

Bug: tint:282
Change-Id: I5131acd84f91fc7494ed6b90965853b7d0fc37f0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32104
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index d209256..a312d1d 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -773,13 +773,11 @@
   if (!match(Token::Type::kLessThan))
     return ast::StorageClass::kNone;
 
-  auto sc = storage_class();
+  const char* use = "variable decoration";
+
+  auto sc = expect_storage_class(use);
   if (has_error())
     return sc;
-  if (sc == ast::StorageClass::kNone) {
-    add_error(peek(), "invalid storage class for variable decoration");
-    return sc;
-  }
 
   auto t = next();
   if (!t.IsGreaterThan()) {
@@ -912,19 +910,17 @@
 ast::type::Type* ParserImpl::expect_type_decl_pointer(Token t) {
   next();  // Consume the peek
 
+  const char* use = "ptr declaration";
+
   t = next();
   if (!t.IsLessThan()) {
     add_error(t, "missing < for ptr declaration");
     return nullptr;
   }
 
-  auto sc = storage_class();
+  auto sc = expect_storage_class(use);
   if (has_error())
     return nullptr;
-  if (sc == ast::StorageClass::kNone) {
-    add_error(peek(), "missing storage class for ptr declaration");
-    return nullptr;
-  }
 
   t = next();
   if (!t.IsComma()) {
@@ -1062,44 +1058,35 @@
 //  | IMAGE
 //  | PRIVATE
 //  | FUNCTION
-ast::StorageClass ParserImpl::storage_class() {
-  auto t = peek();
-  if (t.IsIn()) {
-    next();  // consume the peek
+ast::StorageClass ParserImpl::expect_storage_class(const std::string& use) {
+  if (match(Token::Type::kIn))
     return ast::StorageClass::kInput;
-  }
-  if (t.IsOut()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kOut))
     return ast::StorageClass::kOutput;
-  }
-  if (t.IsUniform()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kUniform))
     return ast::StorageClass::kUniform;
-  }
-  if (t.IsWorkgroup()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kWorkgroup))
     return ast::StorageClass::kWorkgroup;
-  }
-  if (t.IsUniformConstant()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kUniformConstant))
     return ast::StorageClass::kUniformConstant;
-  }
-  if (t.IsStorageBuffer()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kStorageBuffer))
     return ast::StorageClass::kStorageBuffer;
-  }
-  if (t.IsImage()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kImage))
     return ast::StorageClass::kImage;
-  }
-  if (t.IsPrivate()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kPrivate))
     return ast::StorageClass::kPrivate;
-  }
-  if (t.IsFunction()) {
-    next();  // consume the peek
+
+  if (match(Token::Type::kFunction))
     return ast::StorageClass::kFunction;
-  }
+
+  add_error(peek().source(), "invalid storage class", use);
   return ast::StorageClass::kNone;
 }
 
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index da2f724..ba008bb 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -184,8 +184,9 @@
   /// @returns the parsed Type or nullptr if none matched.
   ast::type::Type* type_decl();
   /// Parses a `storage_class` grammar element
+  /// @param use a description of what was being parsed if an error was raised
   /// @returns the storage class or StorageClass::kNone if none matched
-  ast::StorageClass storage_class();
+  ast::StorageClass expect_storage_class(const std::string& use);
   /// Parses a `struct_decl` grammar element with the initial
   /// `struct_decoration_decl*` provided as |decos|.
   /// @returns the struct type or nullptr on error
diff --git a/src/reader/wgsl/parser_impl_error_msg_test.cc b/src/reader/wgsl/parser_impl_error_msg_test.cc
index f07df6d..163219c 100644
--- a/src/reader/wgsl/parser_impl_error_msg_test.cc
+++ b/src/reader/wgsl/parser_impl_error_msg_test.cc
@@ -1044,7 +1044,7 @@
 
 TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) {
   EXPECT("var i : ptr<meow, u32>;",
-         "test.wgsl:1:13 error: missing storage class for ptr declaration\n"
+         "test.wgsl:1:13 error: invalid storage class for ptr declaration\n"
          "var i : ptr<meow, u32>;\n"
          "            ^^^^\n");
 }
diff --git a/src/reader/wgsl/parser_impl_storage_class_test.cc b/src/reader/wgsl/parser_impl_storage_class_test.cc
index f595120..bca0a66 100644
--- a/src/reader/wgsl/parser_impl_storage_class_test.cc
+++ b/src/reader/wgsl/parser_impl_storage_class_test.cc
@@ -37,7 +37,7 @@
   auto params = GetParam();
   auto* p = parser(params.input);
 
-  auto sc = p->storage_class();
+  auto sc = p->expect_storage_class("test");
   ASSERT_FALSE(p->has_error());
   EXPECT_EQ(sc, params.result);
 
@@ -61,8 +61,10 @@
 
 TEST_F(ParserImplTest, StorageClass_NoMatch) {
   auto* p = parser("not-a-storage-class");
-  auto sc = p->storage_class();
+  auto sc = p->expect_storage_class("test");
   ASSERT_EQ(sc, ast::StorageClass::kNone);
+  ASSERT_TRUE(p->has_error());
+  EXPECT_EQ(p->error(), "1:1: invalid storage class for test");
 
   auto t = p->next();
   EXPECT_TRUE(t.IsIdentifier());
diff --git a/src/reader/wgsl/parser_impl_type_decl_test.cc b/src/reader/wgsl/parser_impl_type_decl_test.cc
index e9a6af8..e3c56c7 100644
--- a/src/reader/wgsl/parser_impl_type_decl_test.cc
+++ b/src/reader/wgsl/parser_impl_type_decl_test.cc
@@ -262,7 +262,7 @@
   auto* t = p->type_decl();
   ASSERT_EQ(t, nullptr);
   ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration");
+  ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
@@ -270,7 +270,7 @@
   auto* t = p->type_decl();
   ASSERT_EQ(t, nullptr);
   ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration");
+  ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_MissingType) {
@@ -286,7 +286,7 @@
   auto* t = p->type_decl();
   ASSERT_EQ(t, nullptr);
   ASSERT_TRUE(p->has_error());
-  ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration");
+  ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
 }
 
 TEST_F(ParserImplTest, TypeDecl_Ptr_BadType) {