1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ 9 #define GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ 10 11 #include "google/protobuf/descriptor.pb.h" 12 #include "google/protobuf/testing/googletest.h" 13 #include <gtest/gtest.h> 14 #include "absl/strings/string_view.h" 15 #include "absl/types/optional.h" 16 17 // Utilities that assist in writing tests for generator annotations. 18 // See java/internal/annotation_unittest.cc for an example. 19 namespace google { 20 namespace protobuf { 21 namespace compiler { 22 namespace annotation_test_util { 23 24 // Struct that contains the file generated from a .proto file and its 25 // GeneratedCodeInfo. For example, the Java generator will fill this struct 26 // (for some 'foo.proto') with: 27 // file_path = "Foo.java" 28 // file_content = content of Foo.java 29 // file_info = parsed content of Foo.java.pb.meta 30 struct ExpectedOutput { 31 std::string file_path; 32 std::string file_content; 33 GeneratedCodeInfo file_info; ExpectedOutputExpectedOutput34 explicit ExpectedOutput(const std::string& file_path) 35 : file_path(file_path) {} 36 }; 37 38 // Creates a file with name `filename` and content `data` in temp test 39 // directory. 40 void AddFile(absl::string_view filename, absl::string_view data); 41 42 // Runs proto compiler. Captures proto file structure in FileDescriptorProto. 43 // Files will be generated in TestTempDir() folder. Callers of this 44 // function must read generated files themselves. 45 // 46 // filename: source .proto file used to generate code. 47 // plugin_specific_args: command line arguments specific to current generator. 48 // For Java, this value might be "--java_out=annotate_code:test_temp_dir" 49 // cli: instance of command line interface to run generator. See Java's 50 // annotation_unittest.cc for an example of how to initialize it. 51 // file: output parameter, will be set to the descriptor of the proto file 52 // specified in filename. 53 bool RunProtoCompiler(const std::string& filename, 54 const std::string& plugin_specific_args, 55 CommandLineInterface* cli, FileDescriptorProto* file); 56 57 bool DecodeMetadata(const std::string& path, GeneratedCodeInfo* info); 58 59 // Finds all of the Annotations for a given source file and path. 60 // See Location.path in https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto for 61 // explanation of what path vector is. 62 void FindAnnotationsOnPath( 63 const GeneratedCodeInfo& info, const std::string& source_file, 64 const std::vector<int>& path, 65 std::vector<const GeneratedCodeInfo::Annotation*>* annotations); 66 67 // Finds the Annotation for a given source file and path (or returns null if it 68 // couldn't). If there are several annotations for given path, returns the first 69 // one. See Location.path in 70 // https://github.com/protocolbuffers/protobuf/blob/main/src/google/protobuf/descriptor.proto for explanation of what path 71 // vector is. 72 const GeneratedCodeInfo::Annotation* FindAnnotationOnPath( 73 const GeneratedCodeInfo& info, const std::string& source_file, 74 const std::vector<int>& path); 75 76 // Returns true if at least one of the provided annotations covers a given 77 // substring with the given semantic in file_content. 78 bool AtLeastOneAnnotationMatchesSubstring( 79 const std::string& file_content, 80 const std::vector<const GeneratedCodeInfo::Annotation*>& annotations, 81 const std::string& expected_text, 82 absl::optional<GeneratedCodeInfo::Annotation::Semantic> expected_semantic = 83 absl::nullopt); 84 85 // Returns true if the provided annotation covers a given substring in 86 // file_content. 87 bool AnnotationMatchesSubstring(const std::string& file_content, 88 const GeneratedCodeInfo::Annotation* annotation, 89 const std::string& expected_text); 90 91 // Returns the text spanned by the annotation if the span is valid; otherwise 92 // returns nullopt. 93 absl::optional<absl::string_view> GetAnnotationSubstring( 94 absl::string_view file_content, 95 const GeneratedCodeInfo::Annotation& annotation); 96 97 } // namespace annotation_test_util 98 } // namespace compiler 99 } // namespace protobuf 100 } // namespace google 101 102 #endif // GOOGLE_PROTOBUF_COMPILER_ANNOTATION_TEST_UTIL_H__ 103