kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/common/protobuf_metadata_file.cc (about) 1 /* 2 * Copyright 2016 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 #include "kythe/cxx/common/protobuf_metadata_file.h" 18 19 #include <memory> 20 #include <string> 21 #include <vector> 22 23 #include "absl/log/log.h" 24 #include "absl/strings/match.h" 25 #include "absl/strings/string_view.h" 26 #include "google/protobuf/descriptor.pb.h" 27 #include "kythe/cxx/common/kythe_metadata_file.h" 28 #include "kythe/cxx/common/schema/edges.h" 29 #include "kythe/proto/storage.pb.h" 30 31 namespace kythe { 32 proto::VName ProtobufMetadataSupport::VNameForAnnotation( 33 const proto::VName& context_vname, 34 const google::protobuf::GeneratedCodeInfo::Annotation& annotation) { 35 proto::VName out; 36 if (!vname_lookup_(annotation.source_file(), &out)) { 37 out.set_corpus(context_vname.corpus()); 38 if (absl::EndsWith(annotation.source_file(), ".gen.proto")) { 39 out.set_root(context_vname.root()); 40 } 41 } 42 out.set_path(annotation.source_file()); 43 return VNameForProtoPath(out, annotation.path()); 44 } 45 46 std::unique_ptr<kythe::MetadataFile> ProtobufMetadataSupport::ParseFile( 47 const std::string& raw_filename, const std::string& filename, 48 absl::string_view buffer, absl::string_view target_buffer) { 49 absl::string_view file_ref(filename); 50 if (!(absl::EndsWith(filename, ".pb.h.meta") || 51 absl::EndsWith(filename, ".pb.h") || 52 absl::EndsWith(filename, ".proto.h.meta") || 53 absl::EndsWith(filename, ".proto.h") || 54 absl::EndsWith(filename, ".stubby.h"))) { 55 return nullptr; 56 } 57 proto::VName context_vname; 58 if (!vname_lookup_(raw_filename, &context_vname)) { 59 LOG(WARNING) << "Failed getting VName for metadata: " << raw_filename; 60 } 61 google::protobuf::GeneratedCodeInfo info; 62 if (!info.ParseFromArray(buffer.data(), buffer.size())) { 63 LOG(WARNING) << "Failed ParseFromArray: " << raw_filename; 64 return nullptr; 65 } 66 67 std::vector<MetadataFile::Rule> rules; 68 int file_rule = -1; 69 for (const auto& annotation : info.annotation()) { 70 MetadataFile::Rule rule{}; 71 rule.whole_file = false; 72 rule.begin = annotation.begin(); 73 rule.end = annotation.end(); 74 rule.vname = VNameForAnnotation(context_vname, annotation); 75 rule.edge_in = kythe::common::schema::kDefinesBinding; 76 rule.edge_out = kythe::common::schema::kGenerates; 77 rule.reverse_edge = true; 78 rule.generate_anchor = false; 79 rule.anchor_begin = 0; 80 rule.anchor_end = 0; 81 if (!rule.vname.path().empty()) { 82 if (file_rule < 0 || rule.begin > rules[file_rule].begin) { 83 file_rule = rules.size() - 1; 84 } 85 } 86 switch (annotation.semantic()) { 87 case google::protobuf::GeneratedCodeInfo_Annotation_Semantic_SET: 88 rule.semantic = kythe::MetadataFile::Semantic::kWrite; 89 break; 90 case google::protobuf::GeneratedCodeInfo_Annotation_Semantic_ALIAS: 91 rule.semantic = set_aliases_as_writes_ 92 ? kythe::MetadataFile::Semantic::kWrite 93 : kythe::MetadataFile::Semantic::kTakeAlias; 94 break; 95 default: 96 rule.semantic = kythe::MetadataFile::Semantic::kNone; 97 } 98 rules.push_back(rule); 99 } 100 101 // Add a file-scoped rule for the last encountered vname; this 102 // will always be from an annotation generated by the corresponding 103 // source file. (Other VNames end up due to the inclusion of 104 // forward-declarations early in the .h). 105 if (file_rule >= 0) { 106 MetadataFile::Rule rule{}; 107 rule.whole_file = true; 108 rule.vname = rules[file_rule].vname; 109 rule.vname.set_signature(""); 110 rule.vname.set_language(""); 111 rule.edge_out = kythe::common::schema::kGenerates; 112 rule.reverse_edge = true; 113 rule.generate_anchor = false; 114 rules.push_back(rule); 115 } 116 117 return MetadataFile::LoadFromRules(raw_filename, rules.begin(), rules.end()); 118 } 119 } // namespace kythe