Add ExternalTexture Type

Adds ExternalTexture type and basic unit tests in accordance with the
currently proposed WGSL specification.

Bug: dawn:728
Change-Id: I7a16a351ff098ba6df5b1e6305c390e3ca1c9d46
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/47180
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 76dcd28..8a54ecc 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -470,6 +470,8 @@
     "type/bool_type.h",
     "type/depth_texture_type.cc",
     "type/depth_texture_type.h",
+    "type/external_texture_type.cc",
+    "type/external_texture_type.h",
     "type/f32_type.cc",
     "type/f32_type.h",
     "type/i32_type.cc",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6dd5985..1c5b27f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -248,6 +248,8 @@
   type/bool_type.h
   type/depth_texture_type.cc
   type/depth_texture_type.h
+  type/external_texture_type.cc
+  type/external_texture_type.h
   type/f32_type.cc
   type/f32_type.h
   type/i32_type.cc
@@ -506,6 +508,7 @@
     type/array_type_test.cc
     type/bool_type_test.cc
     type/depth_texture_type_test.cc
+    type/external_texture_type_test.cc
     type/f32_type_test.cc
     type/i32_type_test.cc
     type/matrix_type_test.cc
diff --git a/src/type/depth_texture_type_test.cc b/src/type/depth_texture_type_test.cc
index 62cb05b..8406feb 100644
--- a/src/type/depth_texture_type_test.cc
+++ b/src/type/depth_texture_type_test.cc
@@ -17,6 +17,7 @@
 #include "src/type/test_helper.h"
 
 #include "src/type/access_control_type.h"
+#include "src/type/external_texture_type.h"
 #include "src/type/sampled_texture_type.h"
 #include "src/type/storage_texture_type.h"
 
@@ -48,6 +49,7 @@
   DepthTexture d(TextureDimension::kCube);
   Texture* ty = &d;
   EXPECT_TRUE(ty->Is<DepthTexture>());
+  EXPECT_FALSE(ty->Is<ExternalTexture>());
   EXPECT_FALSE(ty->Is<SampledTexture>());
   EXPECT_FALSE(ty->Is<StorageTexture>());
 }
diff --git a/src/type/external_texture_type.cc b/src/type/external_texture_type.cc
new file mode 100644
index 0000000..c7d475a
--- /dev/null
+++ b/src/type/external_texture_type.cc
@@ -0,0 +1,47 @@
+// Copyright 2021 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/type/external_texture_type.h"
+
+#include "src/program_builder.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::type::ExternalTexture);
+
+namespace tint {
+namespace type {
+
+ExternalTexture::ExternalTexture() : Base(TextureDimension::k2d) {}
+
+ExternalTexture::ExternalTexture(ExternalTexture&&) = default;
+
+ExternalTexture::~ExternalTexture() = default;
+
+std::string ExternalTexture::type_name() const {
+  std::ostringstream out;
+  out << "__external_texture";
+  return out.str();
+}
+
+std::string ExternalTexture::FriendlyName(const SymbolTable&) const {
+  std::ostringstream out;
+  out << "texture_external";
+  return out.str();
+}
+
+ExternalTexture* ExternalTexture::Clone(CloneContext* ctx) const {
+  return ctx->dst->create<ExternalTexture>();
+}
+
+}  // namespace type
+}  // namespace tint
diff --git a/src/type/external_texture_type.h b/src/type/external_texture_type.h
new file mode 100644
index 0000000..b6ffbc3
--- /dev/null
+++ b/src/type/external_texture_type.h
@@ -0,0 +1,47 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef SRC_TYPE_EXTERNAL_TEXTURE_TYPE_H_
+#define SRC_TYPE_EXTERNAL_TEXTURE_TYPE_H_
+
+#include "src/type/texture_type.h"
+
+namespace tint {
+namespace type {
+class ExternalTexture : public Castable<ExternalTexture, Texture> {
+ public:
+  /// Constructor
+  ExternalTexture();
+
+  /// Move constructor
+  ExternalTexture(ExternalTexture&&);
+  ~ExternalTexture() override;
+
+  /// @returns the name for this type
+  std::string type_name() const override;
+
+  /// @param symbols the program's symbol table
+  /// @returns the name for this type that closely resembles how it would be
+  /// declared in WGSL.
+  std::string FriendlyName(const SymbolTable& symbols) const override;
+
+  /// Clones this type and all transitive types using the `CloneContext` `ctx`.
+  /// @param ctx the clone context
+  /// @return the newly cloned type
+  ExternalTexture* Clone(CloneContext* ctx) const override;
+};
+
+}  // namespace type
+}  // namespace tint
+#endif  // SRC_TYPE_EXTERNAL_TEXTURE_TYPE_H_
diff --git a/src/type/external_texture_type_test.cc b/src/type/external_texture_type_test.cc
new file mode 100644
index 0000000..c181159
--- /dev/null
+++ b/src/type/external_texture_type_test.cc
@@ -0,0 +1,79 @@
+// Copyright 2021 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/type/external_texture_type.h"
+
+#include "src/type/access_control_type.h"
+#include "src/type/depth_texture_type.h"
+#include "src/type/multisampled_texture_type.h"
+#include "src/type/sampled_texture_type.h"
+#include "src/type/storage_texture_type.h"
+#include "src/type/test_helper.h"
+
+namespace tint {
+namespace type {
+namespace {
+
+using ExternalTextureTest = TestHelper;
+
+TEST_F(ExternalTextureTest, Is) {
+  F32 f32;
+  ExternalTexture s;
+  Type* ty = &s;
+  EXPECT_FALSE(ty->Is<AccessControl>());
+  EXPECT_FALSE(ty->Is<Alias>());
+  EXPECT_FALSE(ty->Is<Array>());
+  EXPECT_FALSE(ty->Is<Bool>());
+  EXPECT_FALSE(ty->Is<F32>());
+  EXPECT_FALSE(ty->Is<I32>());
+  EXPECT_FALSE(ty->Is<Matrix>());
+  EXPECT_FALSE(ty->Is<Pointer>());
+  EXPECT_FALSE(ty->Is<Sampler>());
+  EXPECT_FALSE(ty->Is<Struct>());
+  EXPECT_TRUE(ty->Is<Texture>());
+  EXPECT_FALSE(ty->Is<U32>());
+  EXPECT_FALSE(ty->Is<Vector>());
+}
+
+TEST_F(ExternalTextureTest, IsTexture) {
+  F32 f32;
+  ExternalTexture s;
+  Texture* ty = &s;
+  EXPECT_FALSE(ty->Is<DepthTexture>());
+  EXPECT_TRUE(ty->Is<ExternalTexture>());
+  EXPECT_FALSE(ty->Is<MultisampledTexture>());
+  EXPECT_FALSE(ty->Is<SampledTexture>());
+  EXPECT_FALSE(ty->Is<StorageTexture>());
+}
+
+TEST_F(ExternalTextureTest, Dim) {
+  F32 f32;
+  ExternalTexture s;
+  EXPECT_EQ(s.dim(), TextureDimension::k2d);
+}
+
+TEST_F(ExternalTextureTest, TypeName) {
+  F32 f32;
+  ExternalTexture s;
+  EXPECT_EQ(s.type_name(), "__external_texture");
+}
+
+TEST_F(ExternalTextureTest, FriendlyName) {
+  ExternalTexture s;
+  EXPECT_EQ(s.FriendlyName(Symbols()), "texture_external");
+}
+
+}  // namespace
+}  // namespace type
+}  // namespace tint
diff --git a/src/type/multisampled_texture_type_test.cc b/src/type/multisampled_texture_type_test.cc
index d0f025e..2e15846 100644
--- a/src/type/multisampled_texture_type_test.cc
+++ b/src/type/multisampled_texture_type_test.cc
@@ -16,6 +16,7 @@
 
 #include "src/type/access_control_type.h"
 #include "src/type/depth_texture_type.h"
+#include "src/type/external_texture_type.h"
 #include "src/type/sampled_texture_type.h"
 #include "src/type/storage_texture_type.h"
 #include "src/type/test_helper.h"
@@ -50,6 +51,7 @@
   MultisampledTexture s(TextureDimension::kCube, &f32);
   Texture* ty = &s;
   EXPECT_FALSE(ty->Is<DepthTexture>());
+  EXPECT_FALSE(ty->Is<ExternalTexture>());
   EXPECT_TRUE(ty->Is<MultisampledTexture>());
   EXPECT_FALSE(ty->Is<SampledTexture>());
   EXPECT_FALSE(ty->Is<StorageTexture>());
diff --git a/src/type/sampled_texture_type_test.cc b/src/type/sampled_texture_type_test.cc
index 2587c2e..3dc6c38 100644
--- a/src/type/sampled_texture_type_test.cc
+++ b/src/type/sampled_texture_type_test.cc
@@ -16,6 +16,7 @@
 
 #include "src/type/access_control_type.h"
 #include "src/type/depth_texture_type.h"
+#include "src/type/external_texture_type.h"
 #include "src/type/storage_texture_type.h"
 #include "src/type/test_helper.h"
 
@@ -49,6 +50,7 @@
   SampledTexture s(TextureDimension::kCube, &f32);
   Texture* ty = &s;
   EXPECT_FALSE(ty->Is<DepthTexture>());
+  EXPECT_FALSE(ty->Is<ExternalTexture>());
   EXPECT_TRUE(ty->Is<SampledTexture>());
   EXPECT_FALSE(ty->Is<StorageTexture>());
 }
diff --git a/src/type/storage_texture_type_test.cc b/src/type/storage_texture_type_test.cc
index 976ea72..ff8efc7 100644
--- a/src/type/storage_texture_type_test.cc
+++ b/src/type/storage_texture_type_test.cc
@@ -16,6 +16,7 @@
 
 #include "src/type/access_control_type.h"
 #include "src/type/depth_texture_type.h"
+#include "src/type/external_texture_type.h"
 #include "src/type/sampled_texture_type.h"
 #include "src/type/test_helper.h"
 
@@ -53,6 +54,7 @@
                                    ImageFormat::kRgba32Float, subtype);
   Texture* ty = s;
   EXPECT_FALSE(ty->Is<DepthTexture>());
+  EXPECT_FALSE(ty->Is<ExternalTexture>());
   EXPECT_FALSE(ty->Is<SampledTexture>());
   EXPECT_TRUE(ty->Is<StorageTexture>());
 }
diff --git a/test/BUILD.gn b/test/BUILD.gn
index 6845d77..a64d410 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -237,6 +237,7 @@
     "../src/type/array_type_test.cc",
     "../src/type/bool_type_test.cc",
     "../src/type/depth_texture_type_test.cc",
+    "../src/type/external_texture_type_test.cc",
     "../src/type/f32_type_test.cc",
     "../src/type/i32_type_test.cc",
     "../src/type/matrix_type_test.cc",