diff options
author | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 08:50:35 +0300 |
---|---|---|
committer | mikhnenko <mikhnenko@yandex-team.com> | 2024-06-25 09:00:27 +0300 |
commit | 509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194 (patch) | |
tree | 4b8a6a44009906ac852e59efa0bc78bb12043a5b /contrib/libs/protoc/src/google/protobuf/compiler/objectivec | |
parent | 7688f2313619a39a60ef3c2734d8efbc49a0a6db (diff) | |
download | ydb-509c9fc9e7b9c3b8be7307d72a4c966e5f9aa194.tar.gz |
Update protobuf to 3.20.2 and pyprotobuf to 3.20.3
Если это pull-request что-то сломал, то:
- если это тест с канонизацией и еще нет pr с переканонизацией, то переканонизируйте пожалуйста сами
- проверьте, что тест не флапает
- приходите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/createTicket?queue=DEVTOOLSSUPPORT) - там вам обязательно помогут
987be5ed151f827f7f292f32420470b04b71a91d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/objectivec')
17 files changed, 424 insertions, 244 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index 474b70a8ad..9f87d2c71e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -65,9 +65,8 @@ void SetEnumVariables(const FieldDescriptor* descriptor, } } // namespace -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); } @@ -116,12 +115,16 @@ void EnumFieldGenerator::GenerateCFunctionImplementations( } void EnumFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // If it is an enum defined in a different file, then we'll need a forward - // declaration for it. When it is in our file, all the enums are output - // before the message, so it will be declared before it is needed. - if (descriptor_->file() != descriptor_->enum_type()->file()) { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + SingleFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // If it is an enum defined in a different file (and not a WKT), then we'll + // need a forward declaration for it. When it is in our file, all the enums + // are output before the message, so it will be declared before it is needed. + if (include_external_types && + descriptor_->file() != descriptor_->enum_type()->file() && + !IsProtobufLibraryBundledProtoFile(descriptor_->enum_type()->file())) { // Enum name is already in "storage_type". const TProtoStringType& name = variable("storage_type"); fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); @@ -129,8 +132,8 @@ void EnumFieldGenerator::DetermineForwardDeclarations( } RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); variables_["array_storage_type"] = "GPBEnumArray"; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 89d3e6907c..8c27a3702f 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); EnumFieldGenerator(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; @@ -53,23 +52,22 @@ class EnumFieldGenerator : public SingleFieldGenerator { virtual void GenerateCFunctionImplementations( io::Printer* printer) const override; virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + EnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~EnumFieldGenerator(); }; class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization() override; protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedEnumFieldGenerator(); }; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc index 0e1bb33070..cd0ad8a016 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -118,40 +118,39 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } // namespace -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* result = NULL; if (field->is_repeated()) { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { if (field->is_map()) { - result = new MapFieldGenerator(field, options); + result = new MapFieldGenerator(field); } else { - result = new RepeatedMessageFieldGenerator(field, options); + result = new RepeatedMessageFieldGenerator(field); } break; } case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); + result = new RepeatedEnumFieldGenerator(field); break; default: - result = new RepeatedPrimitiveFieldGenerator(field, options); + result = new RepeatedPrimitiveFieldGenerator(field); break; } } else { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); + result = new MessageFieldGenerator(field); break; } case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); + result = new EnumFieldGenerator(field); break; default: if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); + result = new PrimitiveObjFieldGenerator(field); } else { - result = new PrimitiveFieldGenerator(field, options); + result = new PrimitiveFieldGenerator(field); } break; } @@ -160,8 +159,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, return result; } -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetCommonFieldVariables(descriptor, &variables_); } @@ -185,7 +183,8 @@ void FieldGenerator::GenerateCFunctionImplementations( } void FieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { // Nothing } @@ -266,9 +265,8 @@ void FieldGenerator::FinishInitialization(void) { } } -SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { // Nothing } @@ -310,9 +308,8 @@ bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { return true; } -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { variables_["property_storage_attribute"] = "strong"; if (IsRetainedName(variables_["name"])) { variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -353,8 +350,8 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( } RepeatedFieldGenerator::RepeatedFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { // Default to no comment and let the cases needing it fill it in. variables_["array_comment"] = ""; } @@ -407,19 +404,18 @@ bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { return false; // The array (or map/dict) having anything is what is used. } -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_(descriptor->field_count()), extension_generators_(descriptor->extension_count()) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { field_generators_[i].reset( - FieldGenerator::Make(descriptor->field(i), options)); + FieldGenerator::Make(descriptor->field(i))); } for (int i = 0; i < descriptor->extension_count(); i++) { extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); + FieldGenerator::Make(descriptor->extension(i))); } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h index b2d2e676b1..bc1fb11b8a 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -33,7 +33,6 @@ #include <map> #include <string> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -44,8 +43,7 @@ namespace objectivec { class FieldGenerator { public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); + static FieldGenerator* Make(const FieldDescriptor* field); virtual ~FieldGenerator(); @@ -66,7 +64,8 @@ class FieldGenerator { // Exposed for subclasses, should always call it on the parent class also. virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const; @@ -96,7 +95,7 @@ class FieldGenerator { TProtoStringType raw_field_name() const { return variable("raw_field_name"); } protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + FieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void); bool WantsHasProperty(void) const; @@ -120,8 +119,7 @@ class SingleFieldGenerator : public FieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + SingleFieldGenerator(const FieldDescriptor* descriptor); }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -136,8 +134,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator { virtual void GeneratePropertyDeclaration(io::Printer* printer) const override; protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + ObjCObjFieldGenerator(const FieldDescriptor* descriptor); }; class RepeatedFieldGenerator : public ObjCObjFieldGenerator { @@ -155,15 +152,14 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedFieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void) override; }; // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + FieldGeneratorMap(const Descriptor* descriptor); ~FieldGeneratorMap(); FieldGeneratorMap(const FieldGeneratorMap&) = delete; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc index abb8bb7811..0f4828c3ac 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -31,6 +31,7 @@ #include <google/protobuf/compiler/objectivec/objectivec_file.h> #include <google/protobuf/compiler/objectivec/objectivec_enum.h> #include <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/compiler/objectivec/objectivec_message.h> #include <google/protobuf/compiler/code_generator.h> #include <google/protobuf/io/printer.h> @@ -56,6 +57,10 @@ const arc_i32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004; const char* kHeaderExtension = ".pbobjc.h"; +TProtoStringType BundledFileName(const FileDescriptor* file) { + return "GPB" + FilePathBasename(file) + kHeaderExtension; +} + // Checks if a message contains any enums definitions (on the message or // a nested message under it). bool MessageContainsEnums(const Descriptor* message) { @@ -185,18 +190,19 @@ bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { } // namespace -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) +FileGenerator::FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options) : file_(file), + generation_options_(generation_options), root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { for (int i = 0; i < file_->enum_type_count(); i++) { EnumGenerator* generator = new EnumGenerator(file_->enum_type(i)); enum_generators_.emplace_back(generator); } for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator* generator = - new MessageGenerator(root_class_name_, file_->message_type(i), options_); + new MessageGenerator(root_class_name_, file_->message_type(i)); message_generators_.emplace_back(generator); } for (int i = 0; i < file_->extension_count(); i++) { @@ -216,6 +222,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { headers.push_back("GPBDescriptor.h"); headers.push_back("GPBMessage.h"); headers.push_back("GPBRootObject.h"); + for (int i = 0; i < file_->dependency_count(); i++) { + const TProtoStringType header_name = BundledFileName(file_->dependency(i)); + headers.push_back(header_name); + } } else { headers.push_back("GPBProtocolBuffers.h"); } @@ -237,16 +247,26 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { "\n", "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); - // #import any headers for "public imports" in the proto file. + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const TProtoStringType header_extension(kHeaderExtension); - for (int i = 0; i < file_->public_dependency_count(); i++) { - import_writer.AddFile(file_->public_dependency(i), header_extension); + if (headers_use_forward_declarations) { + // #import any headers for "public imports" in the proto file. + for (int i = 0; i < file_->public_dependency_count(); i++) { + import_writer.AddFile(file_->public_dependency(i), header_extension); + } + } else { + for (int i = 0; i < file_->dependency_count(); i++) { + import_writer.AddFile(file_->dependency(i), header_extension); + } } import_writer.Print(printer); } @@ -266,7 +286,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { std::set<TProtoStringType> fwd_decls; for (const auto& generator : message_generators_) { - generator->DetermineForwardDeclarations(&fwd_decls); + generator->DetermineForwardDeclarations( + &fwd_decls, + /* include_external_types = */ headers_use_forward_declarations); } for (std::set<TProtoStringType>::const_iterator i(fwd_decls.begin()); i != fwd_decls.end(); ++i) { @@ -340,6 +362,9 @@ void FileGenerator::GenerateSource(io::Printer* printer) { // #import the runtime support. std::vector<TProtoStringType> headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_) { + headers.push_back(BundledFileName(file_)); + } PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -352,28 +377,34 @@ void FileGenerator::GenerateSource(io::Printer* printer) { std::vector<const FileDescriptor*> deps_with_extensions; CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); + // The bundled protos (WKTs) don't use of forward declarations. + bool headers_use_forward_declarations = + generation_options_.headers_use_forward_declarations && !is_bundled_proto_; + { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const TProtoStringType header_extension(kHeaderExtension); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); - // #import the headers for anything that a plain dependency of this proto - // file (that means they were just an include, not a "public" include). - std::set<TProtoStringType> public_import_names; - for (int i = 0; i < file_->public_dependency_count(); i++) { - public_import_names.insert(file_->public_dependency(i)->name()); - } - for (int i = 0; i < file_->dependency_count(); i++) { - const FileDescriptor *dep = file_->dependency(i); - bool public_import = (public_import_names.count(dep->name()) != 0); - if (!public_import) { - import_writer.AddFile(dep, header_extension); + if (headers_use_forward_declarations) { + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + std::set<TProtoStringType> public_import_names; + for (int i = 0; i < file_->public_dependency_count(); i++) { + public_import_names.insert(file_->public_dependency(i)->name()); + } + for (int i = 0; i < file_->dependency_count(); i++) { + const FileDescriptor *dep = file_->dependency(i); + bool public_import = (public_import_names.count(dep->name()) != 0); + if (!public_import) { + import_writer.AddFile(dep, header_extension); + } } } @@ -599,8 +630,26 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); + + if (is_bundled_proto_) { + // This is basically a clone of ImportWriter::PrintRuntimeImports() but + // without the CPP symbol gate, since within the bundled files, that isn't + // needed. + TProtoStringType import_prefix = generation_options_.runtime_import_prefix; + if (!import_prefix.empty()) { + import_prefix += "/"; + } + for (const auto& header : headers_to_import) { + printer->Print( + "#import \"$import_prefix$$header$\"\n", + "import_prefix", import_prefix, + "header", header); + } + } else { + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, generation_options_.runtime_import_prefix, true); + } + printer->Print("\n"); } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h index 6bd747ac5e..6d2c970f81 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -34,7 +34,6 @@ #include <string> #include <set> #include <vector> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -49,7 +48,19 @@ class MessageGenerator; class FileGenerator { public: - FileGenerator(const FileDescriptor* file, const Options& options); + struct GenerationOptions { + GenerationOptions() + // TODO(thomasvl): Eventually flip this default to false for better + // interop with Swift if proto usages span modules made from ObjC sources. + : headers_use_forward_declarations(true) {} + TProtoStringType generate_for_named_framework; + TProtoStringType named_framework_to_proto_path_mappings_path; + TProtoStringType runtime_import_prefix; + bool headers_use_forward_declarations; + }; + + FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options); ~FileGenerator(); FileGenerator(const FileGenerator&) = delete; @@ -60,6 +71,7 @@ class FileGenerator { private: const FileDescriptor* file_; + const GenerationOptions& generation_options_; TProtoStringType root_class_name_; bool is_bundled_proto_; @@ -67,8 +79,6 @@ class FileGenerator { std::vector<std::unique_ptr<MessageGenerator>> message_generators_; std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_; - const Options options_; - void PrintFileRuntimePreamble( io::Printer* printer, const std::vector<TProtoStringType>& headers_to_import) const; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index 160af71080..552d7e7273 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -94,7 +94,8 @@ bool ObjectiveCGenerator::GenerateAll( // // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - Options generation_options; + Options validation_options; + FileGenerator::GenerationOptions generation_options; std::vector<std::pair<TProtoStringType, TProtoStringType> > options; ParseGeneratorParameter(parameter, &options); @@ -110,17 +111,20 @@ bool ObjectiveCGenerator::GenerateAll( // - Comments start with "#". // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. // // There is no validation that the prefixes are good prefixes, it is // assumed that they are when you create the file. - generation_options.expected_prefixes_path = options[i].second; + validation_options.expected_prefixes_path = options[i].second; } else if (options[i].first == "expected_prefixes_suppressions") { // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. for (StringPiece split_piece : Split( options[i].second, ";", true)) { - generation_options.expected_prefixes_suppressions.push_back( + validation_options.expected_prefixes_suppressions.push_back( TProtoStringType(split_piece)); } } else if (options[i].first == "prefixes_must_be_registered") { @@ -132,7 +136,7 @@ bool ObjectiveCGenerator::GenerateAll( // tried to use a prefix that isn't registered. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.prefixes_must_be_registered)) { + &validation_options.prefixes_must_be_registered)) { *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second; return false; } @@ -144,7 +148,7 @@ bool ObjectiveCGenerator::GenerateAll( // raised if a files doesn't have one. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.require_prefixes)) { + &validation_options.require_prefixes)) { *error = "error: Unknown value for require_prefixes: " + options[i].second; return false; } @@ -185,8 +189,22 @@ bool ObjectiveCGenerator::GenerateAll( // generated files. When integrating ObjC protos into a build system, // this can be used to avoid having to add the runtime directory to the // header search path since the generate #import will be more complete. - generation_options.runtime_import_prefix = - StripSuffixString(options[i].second, "/"); + generation_options.runtime_import_prefix = StripSuffixString(options[i].second, "/"); + } else if (options[i].first == "package_to_prefix_mappings_path") { + // Path to use for when loading the objc class prefix mappings to use. + // The `objc_class_prefix` file option is always honored first if one is present. + // This option also has precedent over the use_package_as_prefix option. + // + // The format of the file is: + // - An entry is a line of "package=prefix". + // - Comments start with "#". + // - A comment can go on a line after a expected package/prefix pair. + // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. + // + SetPackageToPrefixMappingsPath(options[i].second); } else if (options[i].first == "use_package_as_prefix") { // Controls how the symbols should be prefixed to avoid symbols // collisions. The objc_class_prefix file option is always honored, this @@ -212,6 +230,12 @@ bool ObjectiveCGenerator::GenerateAll( // - A comment can go on a line after a expected package/prefix pair. // (i.e. - "some.proto.package # comment") SetProtoPackagePrefixExceptionList(options[i].second); + } else if (options[i].first == "headers_use_forward_declarations") { + if (!StringToBool(options[i].second, + &generation_options.headers_use_forward_declarations)) { + *error = "error: Unknown value for headers_use_forward_declarations: " + options[i].second; + return false; + } } else { *error = "error: Unknown generator option: " + options[i].first; return false; @@ -240,7 +264,7 @@ bool ObjectiveCGenerator::GenerateAll( // ----------------------------------------------------------------- // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + if (!ValidateObjCClassPrefixes(files, validation_options, error)) { // *error will have been filled in. return false; } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index cbe70bac36..5122fa46c0 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -74,6 +74,14 @@ using ::open; namespace { +bool BoolFromEnvVar(const char* env_var, bool default_value) { + const char* value = getenv(env_var); + if (value) { + return TProtoStringType("YES") == ToUpper(value); + } + return default_value; +} + class SimpleLineCollector : public LineConsumer { public: SimpleLineCollector(std::unordered_set<TProtoStringType>* inout_set) @@ -88,10 +96,31 @@ class SimpleLineCollector : public LineConsumer { std::unordered_set<TProtoStringType>* set_; }; +class PackageToPrefixesCollector : public LineConsumer { + public: + PackageToPrefixesCollector(const TProtoStringType &usage, + std::map<TProtoStringType, TProtoStringType>* inout_package_to_prefix_map) + : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} + + virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override; + + private: + const TProtoStringType usage_; + std::map<TProtoStringType, TProtoStringType>* prefix_map_; +}; + class PrefixModeStorage { public: PrefixModeStorage(); + const TProtoStringType package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } + void set_package_to_prefix_mappings_path(const TProtoStringType& path) { + package_to_prefix_mappings_path_ = path; + package_to_prefix_map_.clear(); + } + + TProtoStringType prefix_from_proto_package_mappings(const FileDescriptor* file); + bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } @@ -103,9 +132,16 @@ class PrefixModeStorage { bool is_package_exempted(const TProtoStringType& package); + // When using a proto package as the prefix, this should be added as the + // prefix in front of it. + const TProtoStringType& forced_package_prefix() const { return forced_prefix_; } + private: bool use_package_name_; + std::map<TProtoStringType, TProtoStringType> package_to_prefix_map_; + TProtoStringType package_to_prefix_mappings_path_; TProtoStringType exception_path_; + TProtoStringType forced_prefix_; std::unordered_set<TProtoStringType> exceptions_; }; @@ -113,14 +149,57 @@ PrefixModeStorage::PrefixModeStorage() { // Even thought there are generation options, have an env back door since some // of these helpers could be used in other plugins. - const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX"); - use_package_name_ = - (use_package_cstr && (TProtoStringType("YES") == ToUpper(use_package_cstr))); + use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false); const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH"); if (exception_path) { exception_path_ = exception_path; } + + // This one is a not expected to be common, so it doesn't get a generation + // option, just the env var. + const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX"); + if (prefix) { + forced_prefix_ = prefix; + } +} + +TProtoStringType PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) { + if (!file) { + return ""; + } + + if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) { + TProtoStringType error_str; + // Re use the same collector as we use for expected_prefixes_path since the file + // format is the same. + PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_); + if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { + if (error_str.empty()) { + error_str = TProtoStringType("protoc:0: warning: Failed to parse") + + TProtoStringType(" prefix to proto package mappings file: ") + + package_to_prefix_mappings_path_; + } + std::cerr << error_str << std::endl; + std::cerr.flush(); + package_to_prefix_map_.clear(); + } + } + + const TProtoStringType package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const TProtoStringType no_package_prefix("no_package:"); + const TProtoStringType lookup_key = package.empty() ? no_package_prefix + file->name() : package; + + std::map<TProtoStringType, TProtoStringType>::const_iterator prefix_lookup = + package_to_prefix_map_.find(lookup_key); + + if (prefix_lookup != package_to_prefix_map_.end()) { + return prefix_lookup->second; + } + + return ""; } bool PrefixModeStorage::is_package_exempted(const TProtoStringType& package) { @@ -152,6 +231,14 @@ PrefixModeStorage g_prefix_mode; } // namespace +TProtoStringType GetPackageToPrefixMappingsPath() { + return g_prefix_mode.package_to_prefix_mappings_path(); +} + +void SetPackageToPrefixMappingsPath(const TProtoStringType& file_path) { + g_prefix_mode.set_package_to_prefix_mappings_path(file_path); +} + bool UseProtoPackageAsDefaultPrefix() { return g_prefix_mode.use_package_name(); } @@ -169,7 +256,9 @@ void SetProtoPackagePrefixExceptionList(const TProtoStringType& file_path) { } Options::Options() { - // Default is the value of the env for the package prefixes. + // While there are generator options, also support env variables to help with + // build systems where it isn't as easy to hook in for add the generation + // options when invoking protoc. const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); if (file_path) { expected_prefixes_path = file_path; @@ -179,8 +268,9 @@ Options::Options() { expected_prefixes_suppressions = Split(suppressions, ";", true); } - prefixes_must_be_registered = false; - require_prefixes = false; + prefixes_must_be_registered = + BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false); + require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false); } namespace { @@ -353,9 +443,9 @@ bool IsReservedCIdentifier(const TProtoStringType& input) { } TProtoStringType SanitizeNameForObjC(const TProtoStringType& prefix, - const TProtoStringType& input, - const TProtoStringType& extension, - TProtoStringType* out_suffix_added) { + const TProtoStringType& input, + const TProtoStringType& extension, + TProtoStringType* out_suffix_added) { static const std::unordered_set<TProtoStringType> kReservedWords = MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList)); static const std::unordered_set<TProtoStringType> kNSObjectMethods = @@ -511,8 +601,14 @@ TProtoStringType FileClassPrefix(const FileDescriptor* file) { return file->options().objc_class_prefix(); } - // If package prefix isn't enabled or no package, done. - if (!g_prefix_mode.use_package_name() || file->package().empty()) { + // If package prefix is specified in an prefix to proto mappings file then use that. + TProtoStringType objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); + if (!objc_class_prefix.empty()) { + return objc_class_prefix; + } + + // If package prefix isn't enabled, done. + if (!g_prefix_mode.use_package_name()) { return ""; } @@ -539,7 +635,7 @@ TProtoStringType FileClassPrefix(const FileDescriptor* file) { if (!result.empty()) { result.append("_"); } - return result; + return g_prefix_mode.forced_package_prefix() + result; } TProtoStringType FilePath(const FileDescriptor* file) { @@ -1185,23 +1281,11 @@ void RemoveComment(StringPiece* input) { namespace { -class ExpectedPrefixesCollector : public LineConsumer { - public: - ExpectedPrefixesCollector(std::map<TProtoStringType, TProtoStringType>* inout_package_to_prefix_map) - : prefix_map_(inout_package_to_prefix_map) {} - - virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override; - - private: - std::map<TProtoStringType, TProtoStringType>* prefix_map_; -}; - -bool ExpectedPrefixesCollector::ConsumeLine( +bool PackageToPrefixesCollector::ConsumeLine( const StringPiece& line, TProtoStringType* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = TProtoStringType("Expected prefixes file line without equal sign: '") + - TProtoStringType(line) + "'."; + *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1215,16 +1299,16 @@ bool ExpectedPrefixesCollector::ConsumeLine( return true; } -bool LoadExpectedPackagePrefixes(const Options& generation_options, +bool LoadExpectedPackagePrefixes(const TProtoStringType& expected_prefixes_path, std::map<TProtoStringType, TProtoStringType>* prefix_map, TProtoStringType* out_error) { - if (generation_options.expected_prefixes_path.empty()) { + if (expected_prefixes_path.empty()) { return true; } - ExpectedPrefixesCollector collector(prefix_map); + PackageToPrefixesCollector collector("Expected prefixes", prefix_map); return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); + expected_prefixes_path, &collector, out_error); } bool ValidateObjCClassPrefix( @@ -1241,6 +1325,11 @@ bool ValidateObjCClassPrefix( const TProtoStringType prefix = file->options().objc_class_prefix(); const TProtoStringType package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const TProtoStringType no_package_prefix("no_package:"); + const TProtoStringType lookup_key = + package.empty() ? no_package_prefix + file->name() : package; // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // error cases, so it seems to be ok to use as a back door for warnings. @@ -1248,7 +1337,7 @@ bool ValidateObjCClassPrefix( // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). std::map<TProtoStringType, TProtoStringType>::const_iterator package_match = - expected_package_prefixes.find(package); + expected_package_prefixes.find(lookup_key); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... if (has_prefix && package_match->second == prefix) { @@ -1257,8 +1346,11 @@ bool ValidateObjCClassPrefix( } else { // ...it didn't match! *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";' for package '" + package + - "' in '" + file->name() + "'"; + package_match->second + "\";'"; + if (!package.empty()) { + *out_error += " for package '" + package + "'"; + } + *out_error += " in '" + file->name() + "'"; if (has_prefix) { *out_error += "; but found '" + prefix + "' instead"; } @@ -1287,35 +1379,12 @@ bool ValidateObjCClassPrefix( i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; - break; - } - } - - // Check: Warning - If the file does not have a package, check whether the - // prefix was declared is being used by another package or not. This is - // a special case for empty packages. - if (package.empty()) { - // The file does not have a package and ... - if (other_package_for_prefix.empty()) { - // ... no other package has declared that prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no " - << "package. Consider adding a new package to the proto and adding '" - << "new.package = " << prefix << "' to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); - } else { - // ... another package has declared the same prefix. - std::cerr - << "protoc:0: warning: File '" << file->name() << "' has no package " - << "and package '" << other_package_for_prefix << "' already uses '" - << prefix << "' as its prefix. Consider either adding a new package " - << "to the proto, or reusing one of the packages already using this " - << "prefix in the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; - std::cerr.flush(); + // Stop on the first real package listing, if it was a no_package file + // specific entry, keep looking to try and find a package one. + if (!HasPrefixString(other_package_for_prefix, no_package_prefix)) { + break; + } } - return true; } // Check: Error - Make sure the prefix wasn't expected for a different @@ -1324,14 +1393,20 @@ bool ValidateObjCClassPrefix( if (!other_package_for_prefix.empty()) { *out_error = "error: Found 'option objc_class_prefix = \"" + prefix + - "\";' in '" + file->name() + - "'; that prefix is already used for 'package " + - other_package_for_prefix + ";'. It can only be reused by listing " + - "it in the expected file (" + - expected_prefixes_path + ")."; + "\";' in '" + file->name() + "'; that prefix is already used for "; + if (HasPrefixString(other_package_for_prefix, no_package_prefix)) { + *out_error += "file '" + + StripPrefixString(other_package_for_prefix, no_package_prefix) + + "'."; + } else { + *out_error += "'package " + other_package_for_prefix + ";'."; + } + *out_error += + " It can only be reused by adding '" + lookup_key + " = " + prefix + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; // Only report first usage of the prefix. } - } // !prefix.empty() + } // !prefix.empty() && have_expected_prefix_file // Check: Warning - Make sure the prefix is is a reasonable value according // to Apple's rules (the checks above implicitly whitelist anything that @@ -1360,17 +1435,18 @@ bool ValidateObjCClassPrefix( if (prefixes_must_be_registered) { *out_error = "error: '" + file->name() + "' has 'option objc_class_prefix = \"" + - prefix + "\";', but it is not registered; add it to the expected " + - "prefixes file (" + expected_prefixes_path + ") for the package '" + - package + "'."; + prefix + "\";', but it is not registered. Add '" + lookup_key + " = " + + (prefix.empty() ? "\"\"" : prefix) + + "' to the expected prefixes file (" + expected_prefixes_path + ")."; return false; } std::cerr << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " consider adding it to the expected prefixes file (" - << expected_prefixes_path << ")." << std::endl; + << prefix << "\";' in '" << file->name() << "'; consider adding '" + << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix) + << "' to the expected prefixes file (" << expected_prefixes_path + << ")." << std::endl; std::cerr.flush(); } @@ -1380,6 +1456,13 @@ bool ValidateObjCClassPrefix( } // namespace bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, + TProtoStringType* out_error) { + // Options's ctor load from the environment. + Options options; + return ValidateObjCClassPrefixes(files, options, out_error); +} + +bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, const Options& generation_options, TProtoStringType* out_error) { // Allow a '-' as the path for the expected prefixes to completely disable @@ -1390,7 +1473,7 @@ bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, // Load the expected package prefixes, if available, to validate against. std::map<TProtoStringType, TProtoStringType> expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, + if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 28acf4affd..afbf34b7ad 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -47,6 +47,10 @@ namespace protobuf { namespace compiler { namespace objectivec { +// Get/Set the path to a file to load for objc class prefix lookups. +TProtoStringType PROTOC_EXPORT GetPackageToPrefixMappingsPath(); +void PROTOC_EXPORT SetPackageToPrefixMappingsPath( + const TProtoStringType& file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -54,20 +58,18 @@ namespace objectivec { bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix(); void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off); // Get/Set the path to a file to load as exceptions when -// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`. -// And empty string means there should be no exceptions loaded. +// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there +// should be no exceptions. TProtoStringType PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); void PROTOC_EXPORT SetProtoPackagePrefixExceptionList( const TProtoStringType& file_path); -// Generator options (see objectivec_generator.cc for a description of each): +// Generator Prefix Validation Options (see objectivec_generator.cc for a +// description of each): struct Options { Options(); TProtoStringType expected_prefixes_path; std::vector<TProtoStringType> expected_prefixes_suppressions; - TProtoStringType generate_for_named_framework; - TProtoStringType named_framework_to_proto_path_mappings_path; - TProtoStringType runtime_import_prefix; bool prefixes_must_be_registered; bool require_prefixes; }; @@ -251,7 +253,11 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // and the result is false. bool PROTOC_EXPORT ValidateObjCClassPrefixes( const std::vector<const FileDescriptor*>& files, - const Options& generation_options, TProtoStringType* out_error); + const Options& validation_options, TProtoStringType* out_error); +// Same was the other ValidateObjCClassPrefixes() calls, but the options all +// come from the environment variables. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector<const FileDescriptor*>& files, TProtoStringType* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index ed21b6526c..933f0ce73d 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -81,14 +81,13 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { } // namespace -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { const FieldDescriptor* key_descriptor = descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = descriptor->message_type()->map_value(); - value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); // Pull over some variables_ from the value. variables_["field_type"] = value_field_generator_->variable("field_type"); @@ -153,7 +152,7 @@ void MapFieldGenerator::FinishInitialization(void) { // Use the array_comment support in RepeatedFieldGenerator to output what the // values in the map are. const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { variables_["array_comment"] = "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; @@ -161,11 +160,19 @@ void MapFieldGenerator::FinishInitialization(void) { } void MapFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + descriptor_->message_type()->map_value(); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE && + ((include_external_types && + !IsProtobufLibraryBundledProtoFile(value_descriptor->file())) || + descriptor_->file() == value_descriptor->file())) { const TProtoStringType& value_storage_type = value_field_generator_->variable("storage_type"); fwd_decls->insert("@class " + value_storage_type); @@ -176,7 +183,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const { // Class name is already in "storage_type". const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); + descriptor_->message_type()->map_value(); if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { fwd_decls->insert(ObjCClassDeclaration( value_field_generator_->variable("storage_type"))); diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index fd2b466dcc..2ec2e43435 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization(void) override; @@ -51,13 +50,14 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + MapFieldGenerator(const FieldDescriptor* descriptor); virtual ~MapFieldGenerator(); virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; private: std::unique_ptr<FieldGenerator> value_field_generator_; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 39f8fd50fb..ab5b29628f 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -171,11 +171,10 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } // namespace MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, - const Options& options) + const Descriptor* descriptor) : root_classname_(root_classname), descriptor_(descriptor), - field_generators_(descriptor, options), + field_generators_(descriptor), class_name_(ClassName(descriptor_)), deprecated_attribute_(GetOptionalDeprecatedAttribute( descriptor, descriptor->file(), false, true)) { @@ -197,8 +196,7 @@ MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, for (int i = 0; i < descriptor_->nested_type_count(); i++) { MessageGenerator* generator = new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); + descriptor_->nested_type(i)); nested_message_generators_.emplace_back(generator); } } @@ -217,17 +215,18 @@ void MessageGenerator::GenerateStaticVariablesInitialization( } void MessageGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) { + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) { if (!IsMapEntryMessage(descriptor_)) { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* fieldDescriptor = descriptor_->field(i); field_generators_.get(fieldDescriptor) - .DetermineForwardDeclarations(fwd_decls); + .DetermineForwardDeclarations(fwd_decls, include_external_types); } } for (const auto& generator : nested_message_generators_) { - generator->DetermineForwardDeclarations(fwd_decls); + generator->DetermineForwardDeclarations(fwd_decls, include_external_types); } } diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h index a55351b1a2..71eec0d0c7 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -35,7 +35,6 @@ #include <set> #include <vector> #include <google/protobuf/compiler/objectivec/objectivec_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> #include <google/protobuf/compiler/objectivec/objectivec_oneof.h> #include <google/protobuf/descriptor.h> #include <google/protobuf/io/printer.h> @@ -51,7 +50,7 @@ class EnumGenerator; class MessageGenerator { public: MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, const Options& options); + const Descriptor* descriptor); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; @@ -63,7 +62,8 @@ class MessageGenerator { void GenerateSource(io::Printer* printer); void GenerateExtensionRegistrationSource(io::Printer* printer); void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); - void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls); + void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls, + bool include_external_types); // Checks if the message or a nested message includes a oneof definition. bool IncludesOneOfDefinition() const; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index f26bbc8de5..828b75c868 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -58,19 +58,27 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } // namespace -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); } MessageFieldGenerator::~MessageFieldGenerator() {} void MessageFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + ObjCObjFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( @@ -79,8 +87,8 @@ void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( } RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = @@ -90,10 +98,19 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {} void RepeatedMessageFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); - // Class name is already in "storage_type". - fwd_decls->insert("@class " + variable("storage_type")); + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + RepeatedFieldGenerator::DetermineForwardDeclarations( + fwd_decls, include_external_types); + // Within a file there is no requirement on the order of the messages, so + // local references need a forward declaration. External files (not WKTs), + // need one when requested. + if ((include_external_types && + !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) || + descriptor_->file() == descriptor_->message_type()->file()) { + // Class name is already in "storage_type". + fwd_decls->insert("@class " + variable("storage_type")); + } } void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 8897c9b7b6..44b5aabcfd 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + MessageFieldGenerator(const FieldDescriptor* descriptor); MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; @@ -55,18 +53,17 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedMessageFieldGenerator(); RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; @@ -74,7 +71,8 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { public: virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const override; + std::set<TProtoStringType>* fwd_decls, + bool include_external_types) const override; virtual void DetermineObjectiveCClassDefinitions( std::set<TProtoStringType>* fwd_decls) const override; }; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index 767068107a..c8233b1441 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -125,8 +125,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } // namespace PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); } @@ -159,8 +159,8 @@ void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { } PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); variables_["property_storage_attribute"] = "copy"; } @@ -168,8 +168,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); TProtoStringType base_name = PrimitiveArrayTypeName(descriptor); diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h index a9f30f6419..291d11a2e3 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveFieldGenerator(); PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; @@ -59,12 +57,10 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator { }; class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveObjFieldGenerator(); PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; @@ -73,12 +69,10 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedPrimitiveFieldGenerator(); RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = |