kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/indexer/proto/proto_graph_builder.h (about) 1 /* 2 * Copyright 2018 The Kythe Authors. All rights reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 // Wrappers for adding nodes/edges to the Kythe graph. 18 19 #ifndef KYTHE_CXX_INDEXER_PROTO_PROTO_GRAPH_BUILDER_H_ 20 #define KYTHE_CXX_INDEXER_PROTO_PROTO_GRAPH_BUILDER_H_ 21 22 #include <functional> 23 #include <string> 24 #include <utility> 25 #include <vector> 26 27 #include "absl/log/log.h" 28 #include "google/protobuf/io/printer.h" 29 #include "google/protobuf/io/zero_copy_stream_impl_lite.h" 30 #include "kythe/cxx/common/indexing/KytheGraphRecorder.h" 31 #include "kythe/cxx/common/indexing/KytheOutputStream.h" 32 #include "kythe/cxx/common/kythe_metadata_file.h" 33 #include "kythe/cxx/common/kythe_uri.h" 34 #include "kythe/cxx/indexer/proto/vname_util.h" 35 #include "kythe/proto/common.pb.h" 36 #include "kythe/proto/storage.pb.h" 37 #include "kythe/proto/xref.pb.h" 38 39 namespace kythe { 40 41 // The canonical name for the protobuf language in Kythe 42 static const char kLanguageName[] = "protobuf"; 43 44 // A simple structure for the offsets we need to make anchor nodes, because 45 // Descriptors omit these and kythe::proto::Location is seriously overkill. 46 struct Location { 47 proto::VName file; 48 size_t begin; 49 size_t end; 50 }; 51 52 // Contains the hooks for emitting the correct Kythe artifacts based at 53 // relevant points in a proto file's source tree. 54 class ProtoGraphBuilder { 55 public: 56 // Constructs a graph builder using the given graph recorder. Ownership 57 // of the graph recorder is not transferred, and it must outlive this 58 // object. `vname_for_rel_path` should return a VName for the given 59 // relative (to the file under analysis) path. 60 ProtoGraphBuilder( 61 KytheGraphRecorder* recorder, 62 std::function<proto::VName(const std::string&)> vname_for_rel_path); 63 64 // disallow copy and assign 65 ProtoGraphBuilder(const ProtoGraphBuilder&) = delete; 66 void operator=(const ProtoGraphBuilder&) = delete; 67 68 // Returns a VName for the given protobuf descriptor. Descriptors share 69 // various member names but do not participate in any sort of inheritance 70 // hierarchy, so we're stuck with a template. 71 template <typename SomeDescriptor> 72 proto::VName VNameForDescriptor(const SomeDescriptor* descriptor) { 73 return ::kythe::lang_proto::VNameForDescriptor(descriptor, 74 vname_for_rel_path_); 75 } 76 77 // Sets the metadata for this file. 78 void SetMetadata(std::unique_ptr<MetadataFile> meta) { 79 meta_ = std::move(meta); 80 } 81 82 // Sets the source text for this file. 83 void SetText(const proto::VName& node_name, const std::string& content); 84 85 // Records a node with the given VName and kind in the graph. 86 void AddNode(const proto::VName& node_name, NodeKindID node_kind); 87 88 // Maybe add a generated file edge 89 void MaybeAddMetadataFileRules(const proto::VName& file); 90 91 // Records an edge of the given kind between the named nodes in the graph. 92 void AddEdge(const proto::VName& start, const proto::VName& end, 93 EdgeKindID start_to_end_kind); 94 95 // Records an edge of the given kind between the named nodes in the graph. 96 void AddEdge(const proto::VName& start, const proto::VName& end, 97 EdgeKindID start_to_end_kind, int ordinal); 98 99 // Creates and add to the graph a proto language-specific declaration node. 100 proto::VName CreateAndAddAnchorNode(const Location& location); 101 102 // Creates and adds a documentation node for `element` to the graph. The 103 // `location` is used to derive the location of the documentation text. 104 proto::VName CreateAndAddDocNode(const Location& location, 105 const proto::VName& element); 106 107 // Adds an import for the file. 108 void AddImport(const std::string& import, const Location& location); 109 110 // Adds a namespace for the file. Generally the first call. 111 void AddNamespace(const proto::VName& package, const Location& location); 112 113 // Adds a value field to an already-added enum declaration. 114 void AddValueToEnum(const proto::VName& enum_type, const proto::VName& value, 115 const Location& location); 116 117 // Adds a field to an already-added protocol buffer message. 118 // `parent` refers to the context where the field is defined, 119 // and `message` refers to the message this field is a part of. 120 // These only differ when processing extensions. 121 void AddFieldToMessage(const proto::VName* parent, 122 const proto::VName& message, const proto::VName* oneof, 123 const proto::VName& field, const Location& location); 124 125 // Adds a oneof to an already-added protocol buffer message. 126 void AddOneofToMessage(const proto::VName& message, const proto::VName& oneof, 127 const Location& location); 128 129 // Adds a stubby method to an already-added RPC service. 130 void AddMethodToService(const proto::VName& service, 131 const proto::VName& method, const Location& location); 132 133 // Adds an enum. 134 void AddEnumType(const proto::VName* parent, const proto::VName& enum_type, 135 const Location& location); 136 137 // Adds a message. 138 void AddMessageType(const proto::VName* parent, const proto::VName& message, 139 const Location& location); 140 141 // Adds an argument with type given by type at the specified location to an 142 // already-added stubby service method. 143 void AddArgumentToMethod(const proto::VName& method, const proto::VName& type, 144 const Location& location) { 145 AddReference(type, location); 146 } 147 148 // Adds typed edges for the given RPC method. 149 void AddMethodType(const proto::VName& method, const proto::VName& input, 150 const proto::VName& output); 151 152 // Adds an anchor for location and a Ref edge to referent 153 void AddReference(const proto::VName& referent, const Location& location); 154 155 // Adds an edge indicating that `term` has type `type`. 156 void AddTyping(const proto::VName& term, const proto::VName& type); 157 158 // Adds a stubby service to the file or optionally provided namespace scope. 159 // Nested fields/declarations/etc must be added separately. 160 void AddService(const proto::VName* parent, const proto::VName& service, 161 const Location& location); 162 163 // Adds an edge associating the comment at a location with an element. 164 void AddDocComment(const proto::VName& element, const Location& location); 165 166 // Adds a code fact to the element. 167 void AddCodeFact(const proto::VName& element, const MarkedSource& code); 168 169 // Marks the given node as deprecated. 170 void SetDeprecated(const proto::VName& node_name); 171 172 private: 173 // Adds an edge from the metadata if metadata exists and a rule is found for 174 // location. 175 void MaybeAddEdgeFromMetadata(const Location& location, 176 const proto::VName& target); 177 // Where we output nodes, edges, etc.. 178 KytheGraphRecorder* recorder_; 179 180 // The metadata file for generated protos. 181 std::unique_ptr<MetadataFile> meta_; 182 183 // A function to resolve relative paths to VNames. 184 std::function<proto::VName(const std::string&)> vname_for_rel_path_; 185 186 // The text of the current file being analyzed. 187 std::string current_file_contents_; 188 189 // Whether the builtin rpc type node has been emitted. 190 bool builtin_rpc_type_emitted_ = false; 191 192 proto::VName builtin_rpc_type_constructor_; 193 }; 194 195 } // namespace kythe 196 197 #endif // KYTHE_CXX_INDEXER_PROTO_PROTO_GRAPH_BUILDER_H_