[wgsl-reader] Parsing depth texture type

Change-Id: Ie886c85db52b934331abe2d5675d9d0e6cdd7210
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/28001
Commit-Queue: Tomek Ponitka <tommek@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index a154634..690cb9b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -883,6 +883,7 @@
     "src/reader/wgsl/parser_impl_const_literal_test.cc",
     "src/reader/wgsl/parser_impl_continue_stmt_test.cc",
     "src/reader/wgsl/parser_impl_continuing_stmt_test.cc",
+    "src/reader/wgsl/parser_impl_depth_texture_type_test.cc",
     "src/reader/wgsl/parser_impl_else_stmt_test.cc",
     "src/reader/wgsl/parser_impl_elseif_stmt_test.cc",
     "src/reader/wgsl/parser_impl_entry_point_decl_test.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index be615c8..2f755c2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -414,6 +414,7 @@
     reader/wgsl/parser_impl_const_literal_test.cc
     reader/wgsl/parser_impl_continue_stmt_test.cc
     reader/wgsl/parser_impl_continuing_stmt_test.cc
+    reader/wgsl/parser_impl_depth_texture_type_test.cc
     reader/wgsl/parser_impl_else_stmt_test.cc
     reader/wgsl/parser_impl_elseif_stmt_test.cc
     reader/wgsl/parser_impl_entry_point_decl_test.cc
diff --git a/src/reader/wgsl/lexer.cc b/src/reader/wgsl/lexer.cc
index 71da0f6..c2126a8 100644
--- a/src/reader/wgsl/lexer.cc
+++ b/src/reader/wgsl/lexer.cc
@@ -575,6 +575,18 @@
     return {Token::Type::kStruct, source, "struct"};
   if (str == "switch")
     return {Token::Type::kSwitch, source, "switch"};
+  if (str == "texture_depth_2d")
+    return {Token::Type::kTextureDepth2d, source, "texture_depth_2d"};
+  if (str == "texture_depth_2d_array") {
+    return {Token::Type::kTextureDepth2dArray, source,
+            "texture_depth_2d_array"};
+  }
+  if (str == "texture_depth_cube")
+    return {Token::Type::kTextureDepthCube, source, "texture_depth_cube"};
+  if (str == "texture_depth_cube_array") {
+    return {Token::Type::kTextureDepthCubeArray, source,
+            "texture_depth_cube_array"};
+  }
   if (str == "true")
     return {Token::Type::kTrue, source, "true"};
   if (str == "type")
diff --git a/src/reader/wgsl/lexer_test.cc b/src/reader/wgsl/lexer_test.cc
index 9023b4a..a2169cf 100644
--- a/src/reader/wgsl/lexer_test.cc
+++ b/src/reader/wgsl/lexer_test.cc
@@ -465,6 +465,11 @@
         TokenData{"stride", Token::Type::kStride},
         TokenData{"struct", Token::Type::kStruct},
         TokenData{"switch", Token::Type::kSwitch},
+        TokenData{"texture_depth_2d", Token::Type::kTextureDepth2d},
+        TokenData{"texture_depth_2d_array", Token::Type::kTextureDepth2dArray},
+        TokenData{"texture_depth_cube", Token::Type::kTextureDepthCube},
+        TokenData{"texture_depth_cube_array",
+                  Token::Type::kTextureDepthCubeArray},
         TokenData{"true", Token::Type::kTrue},
         TokenData{"type", Token::Type::kType},
         TokenData{"u32", Token::Type::kU32},
diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc
index 33debd9..59dc553 100644
--- a/src/reader/wgsl/parser_impl.cc
+++ b/src/reader/wgsl/parser_impl.cc
@@ -46,6 +46,7 @@
 #include "src/ast/type/alias_type.h"
 #include "src/ast/type/array_type.h"
 #include "src/ast/type/bool_type.h"
+#include "src/ast/type/depth_texture_type.h"
 #include "src/ast/type/f32_type.h"
 #include "src/ast/type/i32_type.h"
 #include "src/ast/type/matrix_type.h"
@@ -594,6 +595,36 @@
   return nullptr;
 }
 
+// depth_texture_type
+//  : TEXTURE_DEPTH_2D
+//  | TEXTURE_DEPTH_2D_ARRAY
+//  | TEXTURE_DEPTH_CUBE
+//  | TEXTURE_DEPTH_CUBE_ARRAY
+ast::type::Type* ParserImpl::depth_texture_type() {
+  auto t = peek();
+  if (t.IsTextureDepth2d()) {
+    next();  // Consume the peek
+    return ctx_.type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(
+        ast::type::TextureDimension::k2d));
+  }
+  if (t.IsTextureDepth2dArray()) {
+    next();  // Consume the peek
+    return ctx_.type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(
+        ast::type::TextureDimension::k2dArray));
+  }
+  if (t.IsTextureDepthCube()) {
+    next();  // Consume the peek
+    return ctx_.type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(
+        ast::type::TextureDimension::kCube));
+  }
+  if (t.IsTextureDepthCubeArray()) {
+    next();  // Consume the peek
+    return ctx_.type_mgr().Get(std::make_unique<ast::type::DepthTextureType>(
+        ast::type::TextureDimension::kCubeArray));
+  }
+  return nullptr;
+}
+
 // variable_ident_decl
 //   : IDENT COLON type_decl
 std::pair<std::string, ast::type::Type*> ParserImpl::variable_ident_decl() {
diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h
index 7bcf639..b13f264 100644
--- a/src/reader/wgsl/parser_impl.h
+++ b/src/reader/wgsl/parser_impl.h
@@ -183,6 +183,9 @@
   /// Parses a `sampler_type` grammar element
   /// @returns the parsed Type or nullptr if none matched.
   ast::type::Type* sampler_type();
+  /// Parses a `depth_texture_type` grammar element
+  /// @returns the parsed Type or nullptr if none matched.
+  ast::type::Type* depth_texture_type();
   /// Parses a `function_type_decl` grammar element
   /// @returns the parsed type or nullptr otherwise
   ast::type::Type* function_type_decl();
diff --git a/src/reader/wgsl/parser_impl_depth_texture_type_test.cc b/src/reader/wgsl/parser_impl_depth_texture_type_test.cc
new file mode 100644
index 0000000..d86c03c
--- /dev/null
+++ b/src/reader/wgsl/parser_impl_depth_texture_type_test.cc
@@ -0,0 +1,75 @@
+// 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 "gtest/gtest.h"
+#include "src/ast/type/depth_texture_type.h"
+#include "src/reader/wgsl/parser_impl.h"
+#include "src/reader/wgsl/parser_impl_test_helper.h"
+
+namespace tint {
+namespace reader {
+namespace wgsl {
+namespace {
+
+TEST_F(ParserImplTest, DepthTextureType_Invalid) {
+  auto* p = parser("1234");
+  auto* t = p->depth_texture_type();
+  EXPECT_EQ(t, nullptr);
+  EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, DepthTextureType_2d) {
+  auto* p = parser("texture_depth_2d");
+  auto* t = p->depth_texture_type();
+  ASSERT_NE(t, nullptr);
+  ASSERT_TRUE(t->IsTexture());
+  ASSERT_TRUE(t->AsTexture()->IsDepth());
+  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2d);
+  EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, DepthTextureType_2dArray) {
+  auto* p = parser("texture_depth_2d_array");
+  auto* t = p->depth_texture_type();
+  ASSERT_NE(t, nullptr);
+  ASSERT_TRUE(t->IsTexture());
+  ASSERT_TRUE(t->AsTexture()->IsDepth());
+  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::k2dArray);
+  EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, DepthTextureType_Cube) {
+  auto* p = parser("texture_depth_cube");
+  auto* t = p->depth_texture_type();
+  ASSERT_NE(t, nullptr);
+  ASSERT_TRUE(t->IsTexture());
+  ASSERT_TRUE(t->AsTexture()->IsDepth());
+  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::kCube);
+  EXPECT_FALSE(p->has_error());
+}
+
+TEST_F(ParserImplTest, DepthTextureType_CubeArray) {
+  auto* p = parser("texture_depth_cube_array");
+  auto* t = p->depth_texture_type();
+  ASSERT_NE(t, nullptr);
+  ASSERT_TRUE(t->IsTexture());
+  ASSERT_TRUE(t->AsTexture()->IsDepth());
+  EXPECT_EQ(t->AsTexture()->dim(), ast::type::TextureDimension::kCubeArray);
+  EXPECT_FALSE(p->has_error());
+}
+
+}  // namespace
+}  // namespace wgsl
+}  // namespace reader
+}  // namespace tint
diff --git a/src/reader/wgsl/token.cc b/src/reader/wgsl/token.cc
index f878ade..9ca01c9 100644
--- a/src/reader/wgsl/token.cc
+++ b/src/reader/wgsl/token.cc
@@ -211,6 +211,14 @@
       return "struct";
     case Token::Type::kSwitch:
       return "switch";
+    case Token::Type::kTextureDepth2d:
+      return "texture_depth_2d";
+    case Token::Type::kTextureDepth2dArray:
+      return "texture_depth_2d_array";
+    case Token::Type::kTextureDepthCube:
+      return "texture_depth_cube";
+    case Token::Type::kTextureDepthCubeArray:
+      return "texture_depth_cube_array";
     case Token::Type::kTrue:
       return "true";
     case Token::Type::kType:
diff --git a/src/reader/wgsl/token.h b/src/reader/wgsl/token.h
index 18df905..3740b79 100644
--- a/src/reader/wgsl/token.h
+++ b/src/reader/wgsl/token.h
@@ -222,6 +222,14 @@
     kStruct,
     /// A 'switch'
     kSwitch,
+    /// A 'texture_depth_2d'
+    kTextureDepth2d,
+    /// A 'texture_depth_2d_array'
+    kTextureDepth2dArray,
+    /// A 'texture_depth_cube'
+    kTextureDepthCube,
+    /// A 'texture_depth_cube_array'
+    kTextureDepthCubeArray,
     /// A 'true'
     kTrue,
     /// A 'type'
@@ -483,6 +491,18 @@
   bool IsStruct() const { return type_ == Type::kStruct; }
   /// @returns true if token is a 'switch'
   bool IsSwitch() const { return type_ == Type::kSwitch; }
+  /// @returns true if token is a 'texture_depth_2d'
+  bool IsTextureDepth2d() const { return type_ == Type::kTextureDepth2d; }
+  /// @returns true if token is a 'texture_depth_2d_array'
+  bool IsTextureDepth2dArray() const {
+    return type_ == Type::kTextureDepth2dArray;
+  }
+  /// @returns true if token is a 'texture_depth_cube'
+  bool IsTextureDepthCube() const { return type_ == Type::kTextureDepthCube; }
+  /// @returns true if token is a 'texture_depth_cube_array'
+  bool IsTextureDepthCubeArray() const {
+    return type_ == Type::kTextureDepthCubeArray;
+  }
   /// @returns true if token is a 'true'
   bool IsTrue() const { return type_ == Type::kTrue; }
   /// @returns true if token is a 'type'