chore: use external aquery-based compilation db (#5333)

diff --git a/.gitignore b/.gitignore
index a9167d0..2a27e16 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,11 @@
 # Ignore Rust build artifacts
 kythe/rust/**/target
 rust-project.json
+
+### Added by Hedron's Bazel Compile Commands Extractor: https://github.com/hedronvision/bazel-compile-commands-extractor
+# The external link: Differs on Windows vs macOS/Linux, so we can't check it in. The pattern needs to not have a trailing / because it's a symlink on macOS/Linux.
+/external
+# Compiled output -> don't check in
+/compile_commands.json
+# Directory where clangd puts its indexing work
+/.cache/
diff --git a/BUILD b/BUILD
index 5206066..e5cfc52 100644
--- a/BUILD
+++ b/BUILD
@@ -2,6 +2,7 @@
 load("//:version.bzl", "MAX_VERSION", "MIN_VERSION")
 load("@bazel_gazelle//:def.bzl", "gazelle")
 load("@rules_rust//proto:toolchain.bzl", "rust_proto_toolchain")
+load("@hedron_compile_commands//:refresh_compile_commands.bzl", "refresh_compile_commands")
 
 package(default_visibility = ["//visibility:private"])
 
@@ -64,3 +65,13 @@
     toolchain = ":rust_proto_toolchain_impl",
     toolchain_type = "@rules_rust//proto:toolchain",
 )
+
+refresh_compile_commands(
+    name = "refresh_compile_commands",
+    # Gathering header compile commands fails due to mismatched clang versions with RBE.
+    exclude_headers = "all",
+    # If clangd is complaining about missing headers (and all that goes along with it),
+    # and you're using remote builds, rebuild with --remote_download_outputs=all
+    # With layering_check enabled, clangd warns about missing dependencies on standard library headers.
+    targets = {"//kythe/cxx/...": "--features=-layering_check"},
+)
diff --git a/external.bzl b/external.bzl
index ed9a2ce..e07ac6d 100644
--- a/external.bzl
+++ b/external.bzl
@@ -28,6 +28,7 @@
 load("@llvm-project-raw//utils/bazel:configure.bzl", "llvm_configure")
 load("@llvm-project-raw//utils/bazel:terminfo.bzl", "llvm_terminfo_disable")
 load("@llvm-project-raw//utils/bazel:zlib.bzl", "llvm_zlib_external")
+load("@hedron_compile_commands//:workspace_setup.bzl", "hedron_compile_commands_setup")
 
 def _rule_dependencies():
     go_rules_dependencies()
@@ -1284,6 +1285,7 @@
 
     _bindings()
     _rule_dependencies()
+    hedron_compile_commands_setup()
 
     if sample_ui:
         _sample_ui_dependencies()
diff --git a/setup.bzl b/setup.bzl
index e45f085..bfd9ae7 100644
--- a/setup.bzl
+++ b/setup.bzl
@@ -147,3 +147,10 @@
         patch_args = ["-p1"],
         patches = ["@io_kythe//third_party:llvm-bazel-glob.patch"],
     )
+
+    maybe(
+        github_archive,
+        repo_name = "hedronvision/bazel-compile-commands-extractor",
+        name = "hedron_compile_commands",
+        commit = "d6734f1d7848800edc92de48fb9d9b82f2677958",
+    )
diff --git a/tools/clang_tidy/clang_tidy.sh b/tools/clang_tidy/clang_tidy.sh
index d4aa392..d42db95 100755
--- a/tools/clang_tidy/clang_tidy.sh
+++ b/tools/clang_tidy/clang_tidy.sh
@@ -6,6 +6,7 @@
   exit 1
 fi
 
-"$(dirname "${BASH_SOURCE[0]}")/../cpp/generate_compilation_database.sh"
+(cd "$(dirname "${BASH_SOURCE[0]}")"; bazel run //:refresh_compile_commands)
 
-"$CLANG_TIDY" -p "$(bazel info execution_root)" "$@"
+
+"$CLANG_TIDY" "$@"
diff --git a/tools/cpp/generate_compilation_database.sh b/tools/cpp/generate_compilation_database.sh
deleted file mode 100755
index d5cfba4..0000000
--- a/tools/cpp/generate_compilation_database.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-# Generates a compile_commands.json file at $(bazel info execution_root) for
-# your Clang tooling needs.
-
-set -e
-
-mapfile -t TARGETS < <(bazel query 'kind(cc_.*, //...) - attr(tags, manual, //...)')
-bazel build \
-  --experimental_action_listener=//kythe/cxx/tools/generate_compile_commands:extract_json \
-  --noshow_progress \
-  --noshow_loading_progress \
-  --output_groups=compilation_outputs \
-  "${TARGETS[@]}" > /dev/null
-
-BAZEL_ROOT="$(bazel info execution_root)"
-pushd "$BAZEL_ROOT" > /dev/null
-find . -name '*.compile_command.json' -print0 | while read -r -d '' fname; do
-  sed -e "s|@BAZEL_ROOT@|$BAZEL_ROOT|g" < "$fname" >> compile_commands.json
-  echo "" >> compile_commands.json
-done
-# Decompose, insert and keep the most recent entry for a given file, then
-# recombine.
-sed 's/\(^[[]\)\|\([],]$\)//;/^$/d;' < compile_commands.json \
-  | tac | sort -u -t, -k1,1 \
-  | sed '1s/^./[\0/;s/}$/},/;$s/,$/]/' > compile_commands.json.tmp
-mv compile_commands.json{.tmp,}
-popd > /dev/null