[DEPS] Update protobuf, add protoc_wrapper

Protobuf update moves from github version to chromium version, which has
GN build rules which can be used in standalone builds.

Change-Id: I9d3bcaa896d0b50a615c3e610dad94442b68acd4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/161000
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/.gitmodules b/.gitmodules
index 7a78129..63ff46b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -112,7 +112,11 @@
 	gclient-condition = dawn_node
 [submodule "third_party/protobuf"]
 	path = third_party/protobuf
-	url = https://chromium.googlesource.com/external/github.com/protocolbuffers/protobuf.git
+	url = https://chromium.googlesource.com/chromium/src/third_party/protobuf
+	gclient-condition = dawn_standalone
+[submodule "tools/protoc_wrapper"]
+	path = tools/protoc_wrapper
+	url = https://chromium.googlesource.com/chromium/src/tools/protoc_wrapper
 	gclient-condition = dawn_standalone
 [submodule "third_party/partition_alloc"]
 	path = third_party/partition_alloc
diff --git a/DEPS b/DEPS
index 8d90389..106aa36 100644
--- a/DEPS
+++ b/DEPS
@@ -275,7 +275,12 @@
 
   # Misc dependencies inherited from Tint
   'third_party/protobuf': {
-    'url': '{chromium_git}/external/github.com/protocolbuffers/protobuf.git@2b673bbb57e34fe1bd4570f726fc86b769a3a3d2',
+    'url': '{chromium_git}/chromium/src/third_party/protobuf@41759e11ec427e29e1a72b9401d2af3f6e02d839',
+    'condition': 'dawn_standalone',
+  },
+
+  'tools/protoc_wrapper': {
+    'url': '{chromium_git}/chromium/src/tools/protoc_wrapper@b5ea227bd88235ab3ccda964d5f3819c4e2d8032',
     'condition': 'dawn_standalone',
   },
 
diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt
index a77d376..ef51797 100644
--- a/third_party/CMakeLists.txt
+++ b/third_party/CMakeLists.txt
@@ -25,6 +25,9 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+# Needs to come before SPIR-V Tools
+include("protobuf.cmake")
+
 # Don't build testing in third_party dependencies
 set(BUILD_TESTING OFF)
 
@@ -57,14 +60,6 @@
     add_subdirectory(${DAWN_SPIRV_HEADERS_DIR} "${CMAKE_CURRENT_BINARY_DIR}/spirv-headers")
 endif()
 
-# Needs to come before SPIR-V Tools
-if ((${TINT_BUILD_SPIRV_TOOLS_FUZZER} OR ${TINT_BUILD_AST_FUZZER}) AND
-        (NOT TARGET protobuf::libprotobuf OR NOT TARGET protobuf::protoc))
-    set(protobuf_BUILD_TESTS OFF CACHE BOOL "Controls whether protobuf tests are built" FORCE)
-    set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Controls whether a protobuf static runtime is built" FORCE)
-    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/protobuf)
-endif()
-
 if (NOT TARGET SPIRV-Tools)
     set(SPIRV_SKIP_TESTS ON CACHE BOOL "" FORCE)
     set(SPIRV_SKIP_EXECUTABLES ON CACHE BOOL "" FORCE)
diff --git a/third_party/closure_compiler/compile_js.gni b/third_party/closure_compiler/compile_js.gni
new file mode 100644
index 0000000..6dd61ce
--- /dev/null
+++ b/third_party/closure_compiler/compile_js.gni
@@ -0,0 +1,6 @@
+# An stub file so that third_party/protobuf/proto_library.gni can build without
+# setting enable_js_protobuf to false in args.gn
+template("js_library") {
+  not_needed(invoker, "*")
+  not_needed([ "target_name" ])
+}
diff --git a/third_party/protobuf b/third_party/protobuf
index 2b673bb..41759e1 160000
--- a/third_party/protobuf
+++ b/third_party/protobuf
@@ -1 +1 @@
-Subproject commit 2b673bbb57e34fe1bd4570f726fc86b769a3a3d2
+Subproject commit 41759e11ec427e29e1a72b9401d2af3f6e02d839
diff --git a/third_party/protobuf.cmake b/third_party/protobuf.cmake
new file mode 100644
index 0000000..48850d3
--- /dev/null
+++ b/third_party/protobuf.cmake
@@ -0,0 +1,174 @@
+# Copyright 2023 The Dawn & Tint Authors
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice, this
+#    list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+#    this list of conditions and the following disclaimer in the documentation
+#    and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+#    contributors may be used to endorse or promote products derived from
+#    this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set(protobuf_INSTALL OFF CACHE BOOL "Install protobuf binaries and files" FORCE)
+set(protobuf_BUILD_CONFORMANCE OFF CACHE BOOL "Build conformance tests" FORCE)
+set(protobuf_BUILD_EXAMPLES OFF CACHE BOOL "Build examples" FORCE)
+set(protobuf_BUILD_LIBPROTOC OFF CACHE BOOL "Build libprotoc" FORCE)
+set(protobuf_BUILD_TESTS OFF CACHE BOOL "Controls whether protobuf tests are built" FORCE)
+set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Controls whether a protobuf static runtime is built" FORCE)
+
+set(protobuf_BUILD_PROTOC_BINARIES ON CACHE BOOL "Build libprotoc and protoc compiler" FORCE)
+set(protobuf_DISABLE_RTTI ON CACHE BOOL "Remove runtime type information in the binaries" FORCE)
+
+add_subdirectory("protobuf/cmake")
+
+target_compile_definitions(libprotobuf PUBLIC "-DGOOGLE_PROTOBUF_INTERNAL_DONATE_STEAL_INLINE=0")
+
+# A simplified version of protobuf_generate()
+function(generate_protos)
+  set(OPTIONS APPEND_PATH)
+  set(SINGLE_ARGS TARGET LANGUAGE EXPORT_MACRO PROTOC_OUT_DIR PLUGIN PLUGIN_OPTIONS)
+  set(MULTI_ARGS IMPORT_DIRS GENERATE_EXTENSIONS PROTOC_OPTIONS)
+  cmake_parse_arguments(ARGS "${OPTIONS}" "${SINGLE_ARGS}" "${MULTI_ARGS}" "${ARGN}")
+
+  if(NOT ARGS_TARGET)
+    message(FATAL_ERROR "generate_protos called without a target")
+  endif()
+
+  if(NOT ARGS_LANGUAGE)
+    set(ARGS_LANGUAGE cpp)
+  endif()
+  string(TOLOWER ${ARGS_LANGUAGE} ARGS_LANGUAGE)
+
+  if(NOT ARGS_PROTOC_OUT_DIR)
+    set(ARGS_PROTOC_OUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
+  endif()
+
+  foreach(OPTION ${ARGS_PLUGIN_OPTIONS})
+    # append comma - not using CMake lists and string replacement as users
+    # might have semicolons in options
+    if(PLUGIN_OPTIONS)
+      set( PLUGIN_OPTIONS "${PLUGIN_OPTIONS},")
+    endif()
+    set(PLUGIN_OPTIONS "${PLUGIN_OPTIONS}${OPTION}")
+  endforeach()
+
+  if(ARGS_PLUGIN)
+      set(_plugin "--plugin=${ARGS_PLUGIN}")
+  endif()
+
+  if(NOT ARGS_GENERATE_EXTENSIONS)
+    if(ARGS_LANGUAGE STREQUAL cpp)
+      set(ARGS_GENERATE_EXTENSIONS .pb.h .pb.cc)
+    elseif(ARGS_LANGUAGE STREQUAL python)
+      set(ARGS_GENERATE_EXTENSIONS _pb2.py)
+    else()
+      message(FATAL_ERROR "generate_protos given unknown Language ${LANGUAGE}, please provide a value for GENERATE_EXTENSIONS")
+    endif()
+  endif()
+
+  if(ARGS_TARGET)
+    get_target_property(SOURCE_LIST ${ARGS_TARGET} SOURCES)
+    foreach(FILE ${SOURCE_LIST})
+      if(FILE MATCHES ".proto$")
+        list(APPEND PROTO_FILES ${FILE})
+      endif()
+    endforeach()
+  endif()
+
+  if(NOT PROTO_FILES)
+    message(FATAL_ERROR "generate_protos could not find any .proto files")
+  endif()
+
+  if(ARGS_APPEND_PATH)
+    # Create an include path for each file specified
+    foreach(FILE ${PROTO_FILES})
+      get_filename_component(ABS_FILE ${FILE} ABSOLUTE)
+      get_filename_component(ABS_PATH ${ABS_FILE} PATH)
+      list(FIND PROTOBUF_INCLUDE_PATH ${ABS_PATH} FOUND)
+      if(${FOUND} EQUAL -1)
+          list(APPEND PROTOBUF_INCLUDE_PATH -I ${ABS_PATH})
+      endif()
+    endforeach()
+  endif()
+
+  foreach(DIR ${ARGS_IMPORT_DIRS})
+    get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
+    list(FIND PROTOBUF_INCLUDE_PATH ${ABS_PATH} FOUND)
+    if(${FOUND} EQUAL -1)
+        list(APPEND PROTOBUF_INCLUDE_PATH -I ${ABS_PATH})
+    endif()
+  endforeach()
+
+  if(NOT PROTOBUF_INCLUDE_PATH)
+    set(PROTOBUF_INCLUDE_PATH -I ${CMAKE_CURRENT_SOURCE_DIR})
+  endif()
+
+  set(ALL_GENERATED_SRCS)
+  foreach(PROTO_FILE ${PROTO_FILES})
+    get_filename_component(ABS_FILE ${PROTO_FILE} ABSOLUTE)
+    get_filename_component(ABS_DIR ${ABS_FILE} DIRECTORY)
+
+    get_filename_component(FILE_FULL_NAME ${PROTO_FILE} NAME)
+    string(FIND "${FILE_FULL_NAME}" "." FILE_LAST_EXT_POS REVERSE)
+    string(SUBSTRING "${FILE_FULL_NAME}" 0 ${FILE_LAST_EXT_POS} BASENAME)
+
+    set(SUITABLE_INCLUDE_FOUND FALSE)
+    foreach(DIR ${PROTOBUF_INCLUDE_PATH})
+      if(NOT DIR STREQUAL "-I")
+        file(RELATIVE_PATH REL_DIR ${DIR} ${ABS_DIR})
+        string(FIND "${REL_DIR}" "../" IS_IN_PARENT_FOLDER)
+        if (NOT ${IS_IN_PARENT_FOLDER} EQUAL 0)
+          set(SUITABLE_INCLUDE_FOUND TRUE)
+          break()
+        endif()
+      endif()
+    endforeach()
+
+    if(NOT SUITABLE_INCLUDE_FOUND)
+      message(FATAL_ERROR "generate_protos could not find any correct proto include directory.")
+    endif()
+
+    set(GENERATED_SRCS)
+    foreach(EXT ${ARGS_GENERATE_EXTENSIONS})
+      list(APPEND GENERATED_SRCS "${ARGS_PROTOC_OUT_DIR}/${REL_DIR}/${BASENAME}${EXT}")
+    endforeach()
+    list(APPEND ALL_GENERATED_SRCS ${GENERATED_SRCS})
+
+    set(COMMENT "Running ${ARGS_LANGUAGE} protocol buffer compiler on ${PROTO_FILE}")
+    if(ARGS_PROTOC_OPTIONS)
+      set(COMMENT "${COMMENT}, protoc-options: ${ARGS_PROTOC_OPTIONS}")
+    endif()
+    if(PLUGIN_OPTIONS)
+      set(COMMENT "${COMMENT}, plugin-options: ${PLUGIN_OPTIONS}")
+    endif()
+
+    add_custom_command(
+      OUTPUT ${GENERATED_SRCS}
+      COMMAND protobuf::protoc
+      ARGS ${ARGS_PROTOC_OPTIONS} --${ARGS_LANGUAGE}_out ${_plugin_options}:${ARGS_PROTOC_OUT_DIR} ${_plugin} ${PROTOBUF_INCLUDE_PATH} ${ABS_FILE}
+      DEPENDS ${ABS_FILE} protobuf::protoc
+      COMMENT ${COMMENT}
+      VERBATIM)
+  endforeach()
+
+  set_source_files_properties(${ALL_GENERATED_SRCS} PROPERTIES GENERATED TRUE)
+  if(ARGS_TARGET)
+    target_sources(${ARGS_TARGET} PRIVATE ${ALL_GENERATED_SRCS})
+  endif()
+endfunction()
diff --git a/tools/protoc_wrapper b/tools/protoc_wrapper
new file mode 160000
index 0000000..b5ea227
--- /dev/null
+++ b/tools/protoc_wrapper
@@ -0,0 +1 @@
+Subproject commit b5ea227bd88235ab3ccda964d5f3819c4e2d8032