Repository: kythe/kythe
Pull request #5857 (2023-09-20 16:11:14)

feat(proto_indexer): link proto field types in MarkedSource


Patch:
diff --git a/kythe/cxx/indexer/proto/BUILD b/kythe/cxx/indexer/proto/BUILD
index 13912bd70..e5640652b 100644
--- a/kythe/cxx/indexer/proto/BUILD
+++ b/kythe/cxx/indexer/proto/BUILD
@@ -62,7 +62,6 @@ cc_library(
         "//kythe/proto:xref_cc_proto",
         "@com_google_absl//absl/container:flat_hash_map",
         "@com_google_absl//absl/container:node_hash_set",
-        "@com_google_absl//absl/functional:bind_front",
         "@com_google_absl//absl/log",
         "@com_google_absl//absl/log:check",
         "@com_google_absl//absl/status:statusor",
diff --git a/kythe/cxx/indexer/proto/file_descriptor_walker.cc b/kythe/cxx/indexer/proto/file_descriptor_walker.cc
index bf58f09d1..0567c68df 100644
--- a/kythe/cxx/indexer/proto/file_descriptor_walker.cc
+++ b/kythe/cxx/indexer/proto/file_descriptor_walker.cc
@@ -18,7 +18,6 @@
 
 #include <optional>
 
-#include "absl/functional/bind_front.h"
 #include "absl/log/check.h"
 #include "absl/log/log.h"
 #include "absl/status/statusor.h"
@@ -439,12 +438,8 @@ void FileDescriptorWalker::VisitField(const std::string* parent_name,
                                 v_name, location);
   }
 
-  AttachMarkedSource(
-      v_name,
-      GenerateMarkedSourceForDescriptor(
-          field, absl::bind_front(&ProtoGraphBuilder::VNameForDescriptor<
-                                      google::protobuf::FieldDescriptor>,
-                                  builder_)));
+  AttachMarkedSource(v_name,
+                     GenerateMarkedSourceForDescriptor(field, builder_));
 
   // Check for [deprecated=true] annotations and emit deprecation tags.
   if (field->options().deprecated()) {
diff --git a/kythe/cxx/indexer/proto/marked_source.cc b/kythe/cxx/indexer/proto/marked_source.cc
index baccbc6f0..1866782ec 100644
--- a/kythe/cxx/indexer/proto/marked_source.cc
+++ b/kythe/cxx/indexer/proto/marked_source.cc
@@ -16,13 +16,13 @@
 
 #include "kythe/cxx/indexer/proto/marked_source.h"
 
-#include <functional>
 #include <optional>
 
 #include "absl/strings/str_split.h"
 #include "google/protobuf/descriptor.h"
 #include "kythe/cxx/common/indexing/KytheOutputStream.h"
 #include "kythe/cxx/common/kythe_uri.h"
+#include "kythe/cxx/indexer/proto/proto_graph_builder.h"
 #include "kythe/proto/common.pb.h"
 
 namespace kythe {
@@ -98,7 +98,8 @@ std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
 }
 
 std::optional<MarkedSource> GenerateMarkedSourceForType(
-    const google::protobuf::FieldDescriptor* descriptor) {
+    const google::protobuf::FieldDescriptor* descriptor,
+    ProtoGraphBuilder* builder) {
   MarkedSource type;
   type.set_kind(MarkedSource::TYPE);
   switch (descriptor->type()) {
@@ -108,10 +109,10 @@ std::optional<MarkedSource> GenerateMarkedSourceForType(
         type.set_post_child_text(", ");
         type.set_post_text(">");
 
-        auto key =
-            GenerateMarkedSourceForType(descriptor->message_type()->map_key());
+        auto key = GenerateMarkedSourceForType(
+            descriptor->message_type()->map_key(), builder);
         auto val = GenerateMarkedSourceForType(
-            descriptor->message_type()->map_value());
+            descriptor->message_type()->map_value(), builder);
         if (!key || !val) {
           return std::nullopt;
         }
@@ -119,14 +120,15 @@ std::optional<MarkedSource> GenerateMarkedSourceForType(
         *type.add_child() = *key;
         *type.add_child() = *val;
       } else if (!GenerateMarkedSourceForDottedName(
-                     descriptor->message_type()->full_name(),
-                     type.add_child())) {
+                     descriptor->message_type()->full_name(), type.add_child(),
+                     builder->VNameForDescriptor(descriptor->message_type()))) {
         return std::nullopt;
       }
       break;
     case google::protobuf::FieldDescriptor::TYPE_ENUM:
       if (!GenerateMarkedSourceForDottedName(
-              descriptor->enum_type()->full_name(), type.add_child())) {
+              descriptor->enum_type()->full_name(), type.add_child(),
+              builder->VNameForDescriptor(descriptor->enum_type()))) {
         return std::nullopt;
       }
       break;
@@ -139,8 +141,7 @@ std::optional<MarkedSource> GenerateMarkedSourceForType(
 
 std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     const google::protobuf::FieldDescriptor* descriptor,
-    const std::function<proto::VName(const google::protobuf::FieldDescriptor*)>&
-        vname_for_desc) {
+    ProtoGraphBuilder* builder) {
   std::string full_name;
   if (const google::protobuf::OneofDescriptor* oneof =
           descriptor->real_containing_oneof()) {
@@ -167,11 +168,11 @@ std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     }
   }
   if (const std::optional<MarkedSource> t =
-          GenerateMarkedSourceForType(descriptor)) {
+          GenerateMarkedSourceForType(descriptor, builder)) {
     *ms.add_child() = *t;
   }
-  if (GenerateMarkedSourceForDottedName(full_name, ms.add_child(),
-                                        vname_for_desc(descriptor))) {
+  if (GenerateMarkedSourceForDottedName(
+          full_name, ms.add_child(), builder->VNameForDescriptor(descriptor))) {
     return ms;
   }
   return std::nullopt;
@@ -187,4 +188,13 @@ std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
   return GenerateMarkedSourceForDescriptor("rpc", descriptor);
 }
 
+std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
+    const google::protobuf::OneofDescriptor* descriptor) {
+  MarkedSource ms;
+  if (GenerateMarkedSourceForDottedName(descriptor->full_name(), &ms)) {
+    return ms;
+  }
+  return std::nullopt;
+}
+
 }  // namespace kythe
diff --git a/kythe/cxx/indexer/proto/marked_source.h b/kythe/cxx/indexer/proto/marked_source.h
index 1e0fc83b0..2cb07d794 100644
--- a/kythe/cxx/indexer/proto/marked_source.h
+++ b/kythe/cxx/indexer/proto/marked_source.h
@@ -21,6 +21,7 @@
 
 #include "google/protobuf/descriptor.h"
 #include "kythe/cxx/common/indexing/KytheOutputStream.h"
+#include "kythe/cxx/indexer/proto/proto_graph_builder.h"
 
 namespace kythe {
 
@@ -33,18 +34,6 @@ bool GenerateMarkedSourceForDottedName(
     absl::string_view name, MarkedSource* root,
     std::optional<proto::VName> vname = std::nullopt);
 
-// Given a proto descriptor, generates an appropriate code fact. Returns
-// `None` if a code fact couldn't be generated.
-template <typename T>
-std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
-    const T* descriptor) {
-  MarkedSource ms;
-  if (GenerateMarkedSourceForDottedName(descriptor->full_name(), &ms)) {
-    return ms;
-  }
-  return std::nullopt;
-}
-
 std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     const google::protobuf::Descriptor* descriptor);
 
@@ -56,8 +45,7 @@ std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
 
 std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     const google::protobuf::FieldDescriptor* descriptor,
-    const std::function<proto::VName(const google::protobuf::FieldDescriptor*)>&
-        vname_for_desc);
+    ProtoGraphBuilder* builder);
 
 std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     const google::protobuf::ServiceDescriptor* descriptor);
@@ -65,6 +53,9 @@ std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
 std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
     const google::protobuf::MethodDescriptor* descriptor);
 
+std::optional<MarkedSource> GenerateMarkedSourceForDescriptor(
+    const google::protobuf::OneofDescriptor* descriptor);
+
 }  // namespace kythe
 
 #endif  // KYTHE_CXX_INDEXER_PROTO_MARKED_SOURCE_H_


Test patch:
diff --git a/kythe/cxx/indexer/proto/testdata/basic/message-fields.proto b/kythe/cxx/indexer/proto/testdata/basic/message-fields.proto
index 7a5816ade..276b87018 100644
--- a/kythe/cxx/indexer/proto/testdata/basic/message-fields.proto
+++ b/kythe/cxx/indexer/proto/testdata/basic/message-fields.proto
@@ -19,6 +19,12 @@ message MessageFields {
   //- FNRoot child.0 FNLabel
   //- FNLabel.kind "MODIFIER"
   //- FNLabel.pre_text "optional"
+  //- FNRoot child.1 FNType
+  //- FNType.kind "TYPE"
+  //- FNType child.0 FNTypeName
+  //- FNTypeName child.1 FNTypeIdent
+  //- FNTypeIdent.pre_text "Type1"
+  //- FNTypeIdent link Type1Node
   //- FNRoot child.2 FNName
   //- FNName child.0 FNQualName
   //- FNName child.1 FNIdent