Added Abseil as a third-party dependency

Using the version in the Chromium repo in order to make use of the .gn
files it contains.

Doing so also appears to require us to switch where we pull googletest
from so that the directory structure matches what the Abseil build
config expects. Fortunately this doesn't seem to cause issues in our
tests.

Bug: dawn:563
Change-Id: I55831ad33f282b3d8b03b67826fd2776e5602d89
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/63780
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Brandon Jones <bajones@chromium.org>
diff --git a/.gitignore b/.gitignore
index 526938f..a232e2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@
 build
 buildtools
 testing
+third_party/abseil-cpp/
 third_party/angle/
 third_party/clang-format/
 third_party/glfw/
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4fefeb4..0d949b5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,6 +94,7 @@
 
 set(DAWN_THIRD_PARTY_DIR "${Dawn_SOURCE_DIR}/third_party" CACHE STRING "Directory in which to find third-party dependencies.")
 
+set(DAWN_ABSEIL_DIR "${DAWN_THIRD_PARTY_DIR}/abseil-cpp" CACHE STRING "Directory in which to find Abseil")
 set(DAWN_GLFW_DIR "${DAWN_THIRD_PARTY_DIR}/glfw" CACHE STRING "Directory in which to find GLFW")
 set(DAWN_GLM_DIR "${DAWN_THIRD_PARTY_DIR}/glm" CACHE STRING "Directory in which to find GLM")
 set(DAWN_JINJA2_DIR "${DAWN_THIRD_PARTY_DIR}/jinja2" CACHE STRING "Directory in which to find Jinja2")
diff --git a/DEPS b/DEPS
index b519131..089c2f0 100644
--- a/DEPS
+++ b/DEPS
@@ -9,6 +9,21 @@
   'swiftshader_git': 'https://swiftshader.googlesource.com',
 
   'dawn_standalone': True,
+
+  # Current revision of googletest.
+  # Note: this dep cannot be auto-rolled b/c of nesting.
+  'googletest_revision': '2d924d7a971e9667d76ad09727fb2402b4f8a1e3',
+
+  # Current revision of Chrome's third_party googletest directory. This
+  # repository is mirrored as a separate repository, with separate git hashes
+  # that don't match the external googletest repository or Chrome. Mirrored
+  # patches will have a different git hash associated with them.
+  # To roll, first get the new hash for chromium_googletest_revision from the
+  # mirror of third_party/googletest located here:
+  # https://chromium.googlesource.com/chromium/src/third_party/googletest/
+  # Then get the new hash for googletest_revision from the root Chrome DEPS
+  # file: https://source.chromium.org/chromium/chromium/src/+/main:DEPS
+  'chromium_googletest_revision': '17bbed2084d3127bd7bcd27283f18d7a5861bea8',
 }
 
 deps = {
@@ -80,7 +95,7 @@
     'condition': 'dawn_standalone',
   },
   'third_party/googletest': {
-    'url': '{chromium_git}/external/github.com/google/googletest@2828773179fa425ee406df61890a150577178ea2',
+    'url': '{chromium_git}/chromium/src/third_party/googletest@{chromium_googletest_revision}',
     'condition': 'dawn_standalone',
   },
 
@@ -135,6 +150,11 @@
     'url': '{chromium_git}/chromium/src/third_party/zlib@c29ee8c9c3824ca013479bf8115035527967fe02',
     'condition': 'dawn_standalone',
   },
+
+  'third_party/abseil-cpp': {
+    'url': '{chromium_git}/chromium/src/third_party/abseil-cpp@789af048b388657987c59d4da406859034fe310f',
+    'condition': 'dawn_standalone',
+  },
 }
 
 hooks = [
@@ -232,5 +252,6 @@
 ]
 
 recursedeps = [
+  'third_party/googletest',
   'third_party/vulkan-deps',
 ]
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
index e883854..1dad137 100644
--- a/build_overrides/build.gni
+++ b/build_overrides/build.gni
@@ -23,6 +23,10 @@
   # Android 32-bit non-component, non-clang builds cannot have symbol_level=2
   # due to 4GiB file size limit, see https://crbug.com/648948.
   ignore_elf32_limitations = false
+
+  # If true, it assumes that //third_party/abseil-cpp is an available
+  # dependency for googletest.
+  gtest_enable_absl_printers = false
 }
 
 # Detect whether we can use the hermetic XCode like in Chromium and do so if
diff --git a/build_overrides/dawn.gni b/build_overrides/dawn.gni
index d0190b10..4e9d490 100644
--- a/build_overrides/dawn.gni
+++ b/build_overrides/dawn.gni
@@ -27,6 +27,7 @@
 # users of Dawn don't have to set dirs if they happen to use the same as Dawn.
 
 # The paths to Dawn's dependencies
+dawn_abseil_dir = "//third_party/abseil-cpp"
 dawn_angle_dir = "//third_party/angle"
 dawn_jinja2_dir = "//third_party/jinja2"
 dawn_glfw_dir = "//third_party/glfw"
diff --git a/scripts/dawn_overrides_with_defaults.gni b/scripts/dawn_overrides_with_defaults.gni
index acb5a70..4b30ec2 100644
--- a/scripts/dawn_overrides_with_defaults.gni
+++ b/scripts/dawn_overrides_with_defaults.gni
@@ -76,3 +76,7 @@
   # Default to Tint being Dawn's DEPS
   dawn_tint_dir = "${dawn_root}/third_party/tint"
 }
+
+if (!defined(dawn_abseil_dir)) {
+  dawn_abseil_dir = "//third_party/abseil-cpp"
+}
diff --git a/src/dawn_native/BUILD.gn b/src/dawn_native/BUILD.gn
index ad46ffc..edbc594 100644
--- a/src/dawn_native/BUILD.gn
+++ b/src/dawn_native/BUILD.gn
@@ -53,6 +53,32 @@
       dawn_enable_vulkan_loader && dawn_vulkan_loader_dir != ""
 }
 
+config("dawn_abseil_config") {
+  if (dawn_standalone && is_clang) {
+    cflags = [
+      # Allow the use of enable_if()
+      "-Wno-gcc-compat",
+    ]
+  }
+
+  configs = [
+    "$dawn_abseil_dir:absl_define_config",
+    "$dawn_abseil_dir:absl_include_config",
+  ]
+}
+
+group("dawn_abseil") {
+  # When build_with_chromium=true we need to include "//third_party/abseil-cpp:absl" while
+  # we can be more specific when building standalone Dawn.
+  if (build_with_chromium) {
+    public_deps = [ "$dawn_abseil_dir:absl" ]
+  } else {
+    public_deps = [ "$dawn_abseil_dir/absl/strings:str_format" ]
+  }
+
+  public_configs = [ ":dawn_abseil_config" ]
+}
+
 config("dawn_native_internal") {
   configs = [ "${dawn_root}/src/common:dawn_internal" ]
 
@@ -142,6 +168,7 @@
 # except those that define exported symbols.
 source_set("dawn_native_sources") {
   deps = [
+    ":dawn_abseil",
     ":dawn_native_headers",
     ":dawn_native_utils_gen",
     "${dawn_root}/src/common",
diff --git a/src/dawn_native/ShaderModule.cpp b/src/dawn_native/ShaderModule.cpp
index f821606..f108c33 100644
--- a/src/dawn_native/ShaderModule.cpp
+++ b/src/dawn_native/ShaderModule.cpp
@@ -14,6 +14,7 @@
 
 #include "dawn_native/ShaderModule.h"
 
+#include "absl/strings/str_format.h"
 #include "common/Constants.h"
 #include "common/HashUtils.h"
 #include "dawn_native/BindGroupLayout.h"
@@ -35,10 +36,8 @@
     namespace {
 
         std::string GetShaderDeclarationString(BindGroupIndex group, BindingNumber binding) {
-            std::ostringstream ostream;
-            ostream << "the shader module declaration at set " << static_cast<uint32_t>(group)
-                    << " binding " << static_cast<uint32_t>(binding);
-            return ostream.str();
+            return absl::StrFormat("the shader module declaration at set %u, binding %u",
+                                   static_cast<uint32_t>(group), static_cast<uint32_t>(binding));
         }
 
         tint::transform::VertexFormat ToTintVertexFormat(wgpu::VertexFormat format) {
diff --git a/src/tests/BUILD.gn b/src/tests/BUILD.gn
index 6fbe81b..6b8c850 100644
--- a/src/tests/BUILD.gn
+++ b/src/tests/BUILD.gn
@@ -39,7 +39,7 @@
 if (!build_with_chromium) {
   # When we aren't in Chromium we define out own targets based on the location
   # of the googletest repo.
-  googletest_dir = dawn_googletest_dir
+  googletest_dir = "${dawn_googletest_dir}/src"
 
   config("gtest_config") {
     include_dirs = [
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index 94e5d83..f7eb8c2 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -59,6 +59,11 @@
     add_subdirectory(${DAWN_TINT_DIR})
 endif()
 
+if (NOT TARGET libabsl)
+    message(STATUS "Dawn: using Abseil at ${DAWN_ABSEIL_DIR}")
+    add_subdirectory(${DAWN_ABSEIL_DIR})
+endif()
+
 # Header-only library for khrplatform.h
 add_library(dawn_khronos_platform INTERFACE)
 target_sources(dawn_khronos_platform INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/khronos/KHR/khrplatform.h")