Fix includes of reflection.fbs with static flatbuffer API

Because the base reflection_generated.h needs to be available to flatc
at compile-time, it gets checked into the repository. On top of this,
flatc special-cases `reflection/reflection.fbs` for inclusion, so we
need to treat it special in our #include paths as well.

This makes it so that we codegen the reflection_static.h from
reflection.fbs, and introduces a requirements that any flatbuffer files
which use the reflection.fbs must depend on
@aos//aos/flatbuffers/reflection:reflection_fbs

Change-Id: I22a11e86052b7bd90efadb209a7529ff58b6e0ca
Signed-off-by: James Kuszmaul <james.kuszmaul@bluerivertech.com>
diff --git a/aos/BUILD b/aos/BUILD
index 4d041ca..7c0ad3d 100644
--- a/aos/BUILD
+++ b/aos/BUILD
@@ -239,6 +239,7 @@
     srcs = ["configuration.fbs"],
     target_compatible_with = ["@platforms//os:linux"],
     visibility = ["//visibility:public"],
+    deps = ["//aos/flatbuffers/reflection:reflection_fbs"],
 )
 
 cc_static_flatbuffer(
diff --git a/aos/flatbuffers/BUILD b/aos/flatbuffers/BUILD
index 08d548f..32f1d39 100644
--- a/aos/flatbuffers/BUILD
+++ b/aos/flatbuffers/BUILD
@@ -102,6 +102,7 @@
         ":test_schema",
         "//aos:flatbuffers",
         "//aos:json_to_flatbuffer",
+        "//aos/flatbuffers/test_dir:include_reflection_fbs",
         "//aos/flatbuffers/test_dir:type_coverage_fbs",
         "//aos/testing:googletest",
         "//aos/testing:path",
diff --git a/aos/flatbuffers/reflection/BUILD.bazel b/aos/flatbuffers/reflection/BUILD.bazel
new file mode 100644
index 0000000..475f2a2
--- /dev/null
+++ b/aos/flatbuffers/reflection/BUILD.bazel
@@ -0,0 +1,18 @@
+load("@aspect_bazel_lib//lib:copy_file.bzl", "copy_file")
+load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
+
+copy_file(
+    name = "reflection_fbs_copy",
+    src = "@com_github_google_flatbuffers//reflection:reflection_fbs_schema",
+    out = "reflection.fbs",
+)
+
+# This autogenerates both a reflection_static.h and a reflection_generated.h.
+# However, in order to avoid having two conflicting headers floating around,
+# we forcibly override the #include to use flatbuffers/reflection_generated.h
+# in static_flatbuffers.cc
+static_flatbuffer(
+    name = "reflection_fbs",
+    srcs = ["reflection.fbs"],
+    visibility = ["//visibility:public"],
+)
diff --git a/aos/flatbuffers/static_flatbuffers.cc b/aos/flatbuffers/static_flatbuffers.cc
index 760d92c..c1b617f 100644
--- a/aos/flatbuffers/static_flatbuffers.cc
+++ b/aos/flatbuffers/static_flatbuffers.cc
@@ -120,6 +120,22 @@
 
 const std::string IncludePathForFbs(
     std::string_view fbs_file, std::string_view include_suffix = "static") {
+  // Special case for the reflection_generated.h, which is checked into the
+  // repo.
+  // Note that we *do* autogenerated the reflection_static.h but that because
+  // it uses a special import path, we end up overriding the include anyways
+  // (note that we could muck around with the paths on the bazel side to instead
+  // get a cc_library with the correct include paths specified, although it is
+  // not clear that that would be any simpler than the extra else-if).
+  if (fbs_file == "reflection/reflection.fbs") {
+    if (include_suffix == "generated") {
+      return "flatbuffers/reflection_generated.h";
+    } else if (include_suffix == "static") {
+      return "aos/flatbuffers/reflection/reflection_static.h";
+    } else {
+      LOG(FATAL) << "This should be unreachable.";
+    }
+  }
   fbs_file.remove_suffix(4);
   return absl::StrCat(fbs_file, "_", include_suffix, ".h");
 }
diff --git a/aos/flatbuffers/static_flatbuffers_test.cc b/aos/flatbuffers/static_flatbuffers_test.cc
index ca1cf42..52fa01e 100644
--- a/aos/flatbuffers/static_flatbuffers_test.cc
+++ b/aos/flatbuffers/static_flatbuffers_test.cc
@@ -10,6 +10,7 @@
 #include "aos/flatbuffers.h"
 #include "aos/flatbuffers/builder.h"
 #include "aos/flatbuffers/interesting_schemas.h"
+#include "aos/flatbuffers/test_dir/include_reflection_static.h"
 #include "aos/flatbuffers/test_dir/type_coverage_static.h"
 #include "aos/flatbuffers/test_schema.h"
 #include "aos/flatbuffers/test_static.h"
@@ -1088,4 +1089,9 @@
             aos::FlatbufferToJson(from_object_static, {.multi_line = true}));
 }
 
+// Tests that we can build code that uses the reflection types.
+TEST_F(StaticFlatbuffersTest, IncludeReflectionTypes) {
+  VerifyJson<::aos::testing::UseSchemaStatic>("{\n\n}");
+}
+
 }  // namespace aos::fbs::testing
diff --git a/aos/flatbuffers/test_dir/BUILD b/aos/flatbuffers/test_dir/BUILD
index 76f5fb4..a6275a5 100644
--- a/aos/flatbuffers/test_dir/BUILD
+++ b/aos/flatbuffers/test_dir/BUILD
@@ -1,6 +1,13 @@
 load("//aos/flatbuffers:generate.bzl", "static_flatbuffer")
 
 static_flatbuffer(
+    name = "include_reflection_fbs",
+    srcs = ["include_reflection.fbs"],
+    visibility = ["//visibility:public"],
+    deps = ["//aos/flatbuffers/reflection:reflection_fbs"],
+)
+
+static_flatbuffer(
     name = "include_fbs",
     srcs = ["include.fbs"],
     visibility = ["//visibility:public"],
diff --git a/aos/flatbuffers/test_dir/include_reflection.fbs b/aos/flatbuffers/test_dir/include_reflection.fbs
new file mode 100644
index 0000000..7eda4f5
--- /dev/null
+++ b/aos/flatbuffers/test_dir/include_reflection.fbs
@@ -0,0 +1,9 @@
+include "reflection/reflection.fbs";
+
+namespace aos.testing;
+
+table UseSchema {
+  schema:reflection.Schema (id: 0);
+}
+
+root_type UseSchema;