kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/cxx/indexer/proto/source_tree.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 #ifndef KYTHE_CXX_INDEXER_PROTO_SOURCE_TREE_H_ 18 #define KYTHE_CXX_INDEXER_PROTO_SOURCE_TREE_H_ 19 20 #include <string> 21 #include <vector> 22 23 #include "absl/container/flat_hash_map.h" 24 #include "google/protobuf/compiler/importer.h" 25 #include "google/protobuf/io/zero_copy_stream.h" 26 27 namespace kythe { 28 29 // An implementation of SourceTree that 30 // - provides only pre-loaded files and 31 // - understands the path substitutions (generalizing search paths) used by 32 // the Proto compiler (e.g., for import statements). 33 // Needed because Proto files will import "foo/bar.proto" and not want to care 34 // whether the path is actually "bazel-out/long/path/foo/genprotos/bar.proto". 35 // A ProtoFileParser passes exactly the argument of import statements, leaving 36 // details like this to some other party (in this case the FileReader). 37 // 38 // Takes a sequence of substitutions (s, t) such that paths beginning with s 39 // (and where the end of s is the end of a path component) can be treated as 40 // though they instead began with t for purposes of file lookup. This is the 41 // same as what protoc gets from "-I" and "--proto_path arguments". 42 // (Often either s is empty, in which case t is essentially a search path, or 43 // s and t completely specify virtual and actual filenames.) 44 // 45 // Substitutions are attempted one at a time (not composed) in the order they 46 // appear, which should match the order they were specified on the protoc 47 // command line. If no applicable substitution finds a valid file, the 48 // filename is considered one more time with no substitution before failing. 49 class PreloadedProtoFileTree : public google::protobuf::compiler::SourceTree { 50 public: 51 PreloadedProtoFileTree( 52 const std::vector<std::pair<std::string, std::string>>* substitutions, 53 absl::flat_hash_map<std::string, std::string>* file_mapping_cache) 54 : substitutions_(substitutions), 55 file_mapping_cache_(file_mapping_cache) {} 56 57 // disallow copy and assign 58 PreloadedProtoFileTree(const PreloadedProtoFileTree&) = delete; 59 void operator=(const PreloadedProtoFileTree&) = delete; 60 61 // Add a file's full name (i.e., what any substitutions will map the name(s) 62 // by which it is included onto) to the FileReader. 63 // Returns false if `filename` was already added. 64 bool AddFile(const std::string& filename, const std::string& contents); 65 66 // Load the full contents of `filename` into `contents`, if possible, and 67 // return whether this was successful. 68 // Note that ProtoFileParser passes the literal argument to import statements 69 // as `filename`, leaving FileReaders to do any elaboration (e.g., in this 70 // case, applying path substitutions). 71 google::protobuf::io::ZeroCopyInputStream* Open( 72 absl::string_view filename) override; 73 74 // If Open() returns nullptr, calling this method immediately will return a 75 // description of the error. 76 std::string GetLastErrorMessage() override { return last_error_; } 77 78 // A wrapper around Open(), that reads the proto file contents into a buffer. 79 bool Read(absl::string_view file_path, std::string* out); 80 81 private: 82 // All path prefix substitutions to consider. 83 const std::vector<std::pair<std::string, std::string>>* const substitutions_; 84 85 // A map of pre-substitution to post-substitution names for all files that 86 // have been successfully read via this reader. 87 absl::flat_hash_map<std::string, std::string>* file_mapping_cache_; 88 89 // Path (post-substitution) -> file contents. 90 absl::flat_hash_map<std::string, std::string> file_map_; 91 92 // A description of the error from the last call to Open() (if any). 93 std::string last_error_; 94 }; 95 96 } // namespace kythe 97 98 #endif // KYTHE_CXX_INDEXER_PROTO_SOURCE_TREE_H_