• 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: robinson@google.com (Will Robinson)
9 //
10 // Generates Python code for a given .proto file.
11 
12 #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
13 #define GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
14 
15 #include <cstdint>
16 #include <string>
17 #include <vector>
18 
19 #include "absl/strings/string_view.h"
20 #include "absl/synchronization/mutex.h"
21 #include "google/protobuf/compiler/code_generator.h"
22 #include "google/protobuf/descriptor.pb.h"
23 
24 // Must be included last.
25 #include "google/protobuf/port_def.inc"
26 
27 namespace google {
28 namespace protobuf {
29 
30 class Descriptor;
31 class EnumDescriptor;
32 class EnumValueDescriptor;
33 class FieldDescriptor;
34 class OneofDescriptor;
35 class ServiceDescriptor;
36 
37 namespace io {
38 class Printer;
39 }
40 
41 namespace compiler {
42 namespace python {
43 
44 // CodeGenerator implementation for generated Python protocol buffer classes.
45 // If you create your own protocol compiler binary and you want it to support
46 // Python output, you can do so by registering an instance of this
47 // CodeGenerator with the CommandLineInterface in your main() function.
48 
49 struct GeneratorOptions {
50   bool generate_pyi = false;
51   bool annotate_pyi = false;
52   bool bootstrap = false;
53   bool strip_nonfunctional_codegen = false;
54 };
55 
56 class PROTOC_EXPORT Generator : public CodeGenerator {
57  public:
58   Generator();
59   Generator(const Generator&) = delete;
60   Generator& operator=(const Generator&) = delete;
61   ~Generator() override;
62 
63   // CodeGenerator methods.
64   bool Generate(const FileDescriptor* file, const std::string& parameter,
65                 GeneratorContext* generator_context,
66                 std::string* error) const override;
67 
GetSupportedFeatures()68   uint64_t GetSupportedFeatures() const override {
69     return Feature::FEATURE_PROTO3_OPTIONAL |
70            Feature::FEATURE_SUPPORTS_EDITIONS;
71   }
GetMinimumEdition()72   Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; }
GetMaximumEdition()73   Edition GetMaximumEdition() const override { return Edition::EDITION_2023; }
GetFeatureExtensions()74   std::vector<const FieldDescriptor*> GetFeatureExtensions() const override {
75     return {};
76   }
77 
set_opensource_runtime(bool opensource)78   void set_opensource_runtime(bool opensource) {
79     opensource_runtime_ = opensource;
80   }
81 
82  private:
83   GeneratorOptions ParseParameter(absl::string_view parameter,
84                                   std::string* error) const;
85   void PrintImports() const;
86   template <typename DescriptorT>
87   std::string GetResolvedFeatures(const DescriptorT& descriptor) const;
88   void PrintResolvedFeatures() const;
89   void PrintFileDescriptor() const;
90   void PrintAllEnumsInFile() const;
91   void PrintNestedEnums(const Descriptor& descriptor,
92                         const DescriptorProto& proto) const;
93   void PrintEnum(const EnumDescriptor& enum_descriptor,
94                  const EnumDescriptorProto& proto) const;
95 
96   void PrintFieldDescriptor(const FieldDescriptor& field,
97                             const FieldDescriptorProto& proto) const;
98   void PrintFieldDescriptorsInDescriptor(
99       const Descriptor& message_descriptor, const DescriptorProto& proto,
100       bool is_extension, absl::string_view list_variable_name) const;
101   void PrintFieldsInDescriptor(const Descriptor& message_descriptor,
102                                const DescriptorProto& proto) const;
103   void PrintExtensionsInDescriptor(const Descriptor& message_descriptor,
104                                    const DescriptorProto& proto) const;
105   void PrintMessageDescriptors() const;
106   void PrintDescriptor(const Descriptor& message_descriptor,
107                        const DescriptorProto& proto) const;
108   void PrintNestedDescriptors(const Descriptor& containing_descriptor,
109                               const DescriptorProto& proto) const;
110 
111   void PrintMessages() const;
112   void PrintMessage(const Descriptor& message_descriptor,
113                     absl::string_view prefix,
114                     std::vector<std::string>* to_register,
115                     bool is_nested) const;
116   void PrintNestedMessages(const Descriptor& containing_descriptor,
117                            absl::string_view prefix,
118                            std::vector<std::string>* to_register) const;
119 
120   void FixForeignFieldsInDescriptors() const;
121   void FixForeignFieldsInDescriptor(
122       const Descriptor& descriptor,
123       const Descriptor* containing_descriptor) const;
124   void FixForeignFieldsInField(const Descriptor* containing_type,
125                                const FieldDescriptor& field,
126                                absl::string_view python_dict_name) const;
127   void AddMessageToFileDescriptor(const Descriptor& descriptor) const;
128   void AddEnumToFileDescriptor(const EnumDescriptor& descriptor) const;
129   void AddExtensionToFileDescriptor(const FieldDescriptor& descriptor) const;
130   void AddServiceToFileDescriptor(const ServiceDescriptor& descriptor) const;
131   std::string FieldReferencingExpression(
132       const Descriptor* containing_type, const FieldDescriptor& field,
133       absl::string_view python_dict_name) const;
134   template <typename DescriptorT>
135   void FixContainingTypeInDescriptor(
136       const DescriptorT& descriptor,
137       const Descriptor* containing_descriptor) const;
138 
139   void PrintTopBoilerplate() const;
140   void PrintServices() const;
141   void PrintServiceDescriptors() const;
142   void PrintServiceDescriptor(const ServiceDescriptor& descriptor) const;
143   void PrintServiceClass(const ServiceDescriptor& descriptor) const;
144   void PrintServiceStub(const ServiceDescriptor& descriptor) const;
145   void PrintDescriptorKeyAndModuleName(
146       const ServiceDescriptor& descriptor) const;
147 
148   void PrintEnumValueDescriptor(const EnumValueDescriptor& descriptor,
149                                 const EnumValueDescriptorProto& proto) const;
150   bool GeneratingDescriptorProto() const;
151 
152   template <typename DescriptorT>
153   std::string ModuleLevelDescriptorName(const DescriptorT& descriptor) const;
154   std::string ModuleLevelMessageName(const Descriptor& descriptor) const;
155   std::string ModuleLevelServiceDescriptorName(
156       const ServiceDescriptor& descriptor) const;
157 
158   template <typename DescriptorProtoT>
159   void PrintSerializedPbInterval(const DescriptorProtoT& descriptor_proto,
160                                  absl::string_view name) const;
161 
162   template <typename DescriptorT>
163   bool PrintDescriptorOptionsFixingCode(
164       const DescriptorT& descriptor, const typename DescriptorT::Proto& proto,
165       absl::string_view descriptor_str) const;
166 
167   void FixAllDescriptorOptions() const;
168   void FixOptionsForField(const FieldDescriptor& field,
169                           const FieldDescriptorProto& proto) const;
170   void FixOptionsForOneof(const OneofDescriptor& oneof,
171                           const OneofDescriptorProto& proto) const;
172   void FixOptionsForEnum(const EnumDescriptor& descriptor,
173                          const EnumDescriptorProto& proto) const;
174   void FixOptionsForService(const ServiceDescriptor& descriptor,
175                             const ServiceDescriptorProto& proto) const;
176   void FixOptionsForMessage(const Descriptor& descriptor,
177                             const DescriptorProto& proto) const;
178 
179   void SetSerializedPbInterval(const FileDescriptorProto& file) const;
180   void SetMessagePbInterval(const DescriptorProto& message_proto,
181                             const Descriptor& descriptor) const;
182 
183   void CopyPublicDependenciesAliases(absl::string_view copy_from,
184                                      const FileDescriptor* file) const;
185 
186   // Very coarse-grained lock to ensure that Generate() is reentrant.
187   // Guards file_, printer_ and file_descriptor_serialized_.
188   mutable absl::Mutex mutex_;
189   mutable const FileDescriptor* file_;  // Set in Generate().  Under mutex_.
190   mutable FileDescriptorProto proto_;   // Set in Generate().  Under mutex_.
191   mutable std::string file_descriptor_serialized_;
192   mutable io::Printer* printer_;  // Set in Generate().  Under mutex_.
193 
194   bool opensource_runtime_ = true;
195 };
196 
197 }  // namespace python
198 }  // namespace compiler
199 }  // namespace protobuf
200 }  // namespace google
201 
202 #include "google/protobuf/port_undef.inc"
203 
204 #endif  // GOOGLE_PROTOBUF_COMPILER_PYTHON_GENERATOR_H__
205