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