• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Author: kenton@google.com (Kenton Varda)
9 
10 #ifndef GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
11 #define GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
12 
13 #include <cstdint>
14 #include <string>
15 #include <vector>
16 
17 #include "absl/strings/string_view.h"
18 #include "google/protobuf/compiler/code_generator.h"
19 #include "google/protobuf/descriptor.h"
20 #include "google/protobuf/unittest_features.pb.h"
21 
22 // Must be included last.
23 #include "google/protobuf/port_def.inc"
24 
25 namespace google {
26 namespace protobuf {
27 class FileDescriptor;
28 }  // namespace protobuf
29 }  // namespace google
30 
31 namespace google {
32 namespace protobuf {
33 namespace compiler {
34 
35 // A mock CodeGenerator, used by command_line_interface_unittest.  This is in
36 // its own file so that it can be used both directly and as a plugin.
37 //
38 // Generate() produces some output which can be checked by ExpectCalled().  The
39 // generator can run in a different process (e.g. a plugin).
40 //
41 // If the parameter is "insert=NAMES", the MockCodeGenerator will insert lines
42 // into the files generated by other MockCodeGenerators instead of creating
43 // its own file.  NAMES is a comma-separated list of the names of those other
44 // MockCodeGenerators.  If the parameter is "insert_endlines=NAMES", the
45 // MockCodeGenerator will insert data guaranteed to contain more than one
46 // endline into the files generated by NAMES.
47 //
48 // MockCodeGenerator will also modify its behavior slightly if the input file
49 // contains a message type with one of the following names:
50 //   MockCodeGenerator_Error:  Causes Generate() to return false and set the
51 //     error message to "Saw message type MockCodeGenerator_Error."
52 //   MockCodeGenerator_Exit:  Generate() prints "Saw message type
53 //     MockCodeGenerator_Exit." to stderr and then calls exit(123).
54 //   MockCodeGenerator_Abort:  Generate() prints "Saw message type
55 //     MockCodeGenerator_Abort." to stderr and then calls abort().
56 //   MockCodeGenerator_HasSourceCodeInfo:  Causes Generate() to abort after
57 //     printing "Saw message type MockCodeGenerator_HasSourceCodeInfo: FOO." to
58 //     stderr, where FOO is "1" if the supplied FileDescriptorProto has source
59 //     code info, and "0" otherwise.
60 //   MockCodeGenerator_Annotate:  Generate() will add annotations to its output
61 //     that can later be verified with CheckGeneratedAnnotations.
62 class MockCodeGenerator : public CodeGenerator {
63  public:
64   explicit MockCodeGenerator(absl::string_view name);
65   ~MockCodeGenerator() override;
66 
67   // Expect (via gTest) that a MockCodeGenerator with the given name was called
68   // with the given parameters by inspecting the output location.
69   //
70   // |insertions| is a comma-separated list of names of MockCodeGenerators which
71   // should have inserted lines into this file.
72   // |parsed_file_list| is a comma-separated list of names of the files
73   // that are being compiled together in this run.
74   static void ExpectGenerated(absl::string_view name,
75                               absl::string_view parameter,
76                               absl::string_view insertions,
77                               absl::string_view file,
78                               absl::string_view first_message_name,
79                               absl::string_view first_parsed_file_name,
80                               absl::string_view output_directory);
81 
82   // Checks that the correct text ranges were annotated by the
83   // MockCodeGenerator_Annotate directive.
84   static void CheckGeneratedAnnotations(absl::string_view name,
85                                         absl::string_view file,
86                                         absl::string_view output_directory);
87 
88   // Get the name of the file which would be written by the given generator.
89   static std::string GetOutputFileName(absl::string_view generator_name,
90                                        const FileDescriptor* file);
91   static std::string GetOutputFileName(absl::string_view generator_name,
92                                        absl::string_view file);
93 
94   // implements CodeGenerator ----------------------------------------
95 
96   bool Generate(const FileDescriptor* file, const std::string& parameter,
97                 GeneratorContext* context, std::string* error) const override;
98 
99   uint64_t GetSupportedFeatures() const override;
100   void SuppressFeatures(uint64_t features);
101 
GetFeatureExtensions()102   std::vector<const FieldDescriptor*> GetFeatureExtensions() const override {
103     return feature_extensions_;
104   }
set_feature_extensions(std::vector<const FieldDescriptor * > extensions)105   void set_feature_extensions(std::vector<const FieldDescriptor*> extensions) {
106     feature_extensions_ = extensions;
107   }
108 
GetMinimumEdition()109   Edition GetMinimumEdition() const override { return minimum_edition_; }
set_minimum_edition(Edition minimum_edition)110   void set_minimum_edition(Edition minimum_edition) {
111     minimum_edition_ = minimum_edition;
112   }
113 
GetMaximumEdition()114   Edition GetMaximumEdition() const override { return maximum_edition_; }
set_maximum_edition(Edition maximum_edition)115   void set_maximum_edition(Edition maximum_edition) {
116     maximum_edition_ = maximum_edition;
117   }
118 
119  private:
120   std::string name_;
121   uint64_t suppressed_features_ = 0;
122   mutable Edition minimum_edition_ = MinimumAllowedEdition();
123   mutable Edition maximum_edition_ = MaximumAllowedEdition();
124   std::vector<const FieldDescriptor*> feature_extensions_ = {
125       GetExtensionReflection(pb::test)};
126 
127   static std::string GetOutputFileContent(absl::string_view generator_name,
128                                           absl::string_view parameter,
129                                           const FileDescriptor* file,
130                                           GeneratorContext* context);
131   static std::string GetOutputFileContent(absl::string_view generator_name,
132                                           absl::string_view parameter,
133                                           absl::string_view file,
134                                           absl::string_view parsed_file_list,
135                                           absl::string_view first_message_name);
136 };
137 
138 }  // namespace compiler
139 }  // namespace protobuf
140 }  // namespace google
141 
142 #include "google/protobuf/port_undef.inc"
143 
144 #endif  // GOOGLE_PROTOBUF_COMPILER_MOCK_CODE_GENERATOR_H__
145