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: jieluo@google.com (Jie Luo) 9 // 10 // Generates Python stub (.pyi) for a given .proto file. 11 12 #ifndef GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ 13 #define GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ 14 15 #include <string> 16 #include <vector> 17 18 #include "absl/container/flat_hash_map.h" 19 #include "absl/container/flat_hash_set.h" 20 #include "absl/synchronization/mutex.h" 21 #include "google/protobuf/compiler/code_generator.h" 22 23 // Must be included last. 24 #include "google/protobuf/port_def.inc" 25 26 namespace google { 27 namespace protobuf { 28 class Descriptor; 29 class EnumDescriptor; 30 class FieldDescriptor; 31 class MethodDescriptor; 32 class ServiceDescriptor; 33 34 namespace io { 35 class Printer; 36 } 37 38 namespace compiler { 39 namespace python { 40 41 class PROTOC_EXPORT PyiGenerator : public google::protobuf::compiler::CodeGenerator { 42 public: 43 PyiGenerator(); 44 PyiGenerator(const PyiGenerator&) = delete; 45 PyiGenerator& operator=(const PyiGenerator&) = delete; 46 ~PyiGenerator() override; 47 48 // CodeGenerator methods. GetSupportedFeatures()49 uint64_t GetSupportedFeatures() const override { 50 // Code generators must explicitly support proto3 optional. 51 return Feature::FEATURE_PROTO3_OPTIONAL | 52 Feature::FEATURE_SUPPORTS_EDITIONS; 53 } 54 bool Generate(const FileDescriptor* file, const std::string& parameter, 55 GeneratorContext* generator_context, 56 std::string* error) const override; 57 GetMinimumEdition()58 Edition GetMinimumEdition() const override { return Edition::EDITION_PROTO2; } GetMaximumEdition()59 Edition GetMaximumEdition() const override { return Edition::EDITION_2023; } GetFeatureExtensions()60 std::vector<const FieldDescriptor*> GetFeatureExtensions() const override { 61 return {}; 62 } 63 64 private: 65 void PrintImportForDescriptor(const FileDescriptor& desc, 66 absl::flat_hash_set<std::string>* seen_aliases, 67 bool* has_importlib) const; 68 template <typename DescriptorT> 69 void Annotate(const std::string& label, const DescriptorT* descriptor) const; 70 void PrintImports() const; 71 void PrintTopLevelEnums() const; 72 void PrintEnum(const EnumDescriptor& enum_descriptor) const; 73 void PrintEnumValues(const EnumDescriptor& enum_descriptor, 74 bool is_classvar = false) const; 75 template <typename DescriptorT> 76 void PrintExtensions(const DescriptorT& descriptor) const; 77 void PrintMessages() const; 78 void PrintMessage(const Descriptor& message_descriptor, bool is_nested) const; 79 void PrintServices() const; 80 std::string GetFieldType( 81 const FieldDescriptor& field_des, const Descriptor& containing_des) const; 82 template <typename DescriptorT> 83 std::string ModuleLevelName(const DescriptorT& descriptor) const; 84 std::string PublicPackage() const; 85 std::string InternalPackage() const; 86 87 bool opensource_runtime_ = true; 88 89 // Very coarse-grained lock to ensure that Generate() is reentrant. 90 // Guards file_, printer_, and import_map_. 91 mutable absl::Mutex mutex_; 92 mutable const FileDescriptor* file_; // Set in Generate(). Under mutex_. 93 mutable io::Printer* printer_; // Set in Generate(). Under mutex_. 94 mutable bool strip_nonfunctional_codegen_ = false; // Set in Generate(). 95 // import_map will be a mapping from filename to module alias, e.g. 96 // "google3/foo/bar.py" -> "_bar" 97 mutable absl::flat_hash_map<std::string, std::string> import_map_; 98 }; 99 100 } // namespace python 101 } // namespace compiler 102 } // namespace protobuf 103 } // namespace google 104 105 #include "google/protobuf/port_undef.inc" 106 107 #endif // GOOGLE_PROTOBUF_COMPILER_PYTHON_PYI_GENERATOR_H__ 108