diff options
author | nechda <[email protected]> | 2024-08-29 23:50:27 +0300 |
---|---|---|
committer | nechda <[email protected]> | 2024-08-30 00:05:25 +0300 |
commit | e10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch) | |
tree | 571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc | |
parent | e79b38f2bbbf78d295d1901d2a79f898022d5224 (diff) |
Update cpp-protobuf to 22.5
Привет!\
Этот PR переключат cpp & python библиотеки protobuf на версию 22.5
Если у вас возникли проблемы после влития этого PR:
1. Если начали падать канон тесты, то проведите их переканонизацию
2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями
3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT)
7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc')
-rw-r--r-- | contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc | 522 |
1 files changed, 522 insertions, 0 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc new file mode 100644 index 00000000000..e72185e7949 --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc @@ -0,0 +1,522 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "google/protobuf/compiler/objectivec/field.h" + +#include <iostream> +#include <ostream> +#include <string> +#include <vector> + +#include "y_absl/container/flat_hash_map.h" +#include "y_absl/log/absl_check.h" +#include "y_absl/log/absl_log.h" +#include "y_absl/strings/str_cat.h" +#include "google/protobuf/compiler/objectivec/enum_field.h" +#include "google/protobuf/compiler/objectivec/helpers.h" +#include "google/protobuf/compiler/objectivec/map_field.h" +#include "google/protobuf/compiler/objectivec/message_field.h" +#include "google/protobuf/compiler/objectivec/names.h" +#include "google/protobuf/compiler/objectivec/primitive_field.h" +#include "google/protobuf/io/printer.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +void SetCommonFieldVariables( + const FieldDescriptor* descriptor, + y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables) { + TProtoStringType camel_case_name = FieldName(descriptor); + TProtoStringType raw_field_name; + if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { + raw_field_name = descriptor->message_type()->name(); + } else { + raw_field_name = descriptor->name(); + } + // The logic here has to match -[GGPBFieldDescriptor textFormatName]. + const TProtoStringType un_camel_case_name( + UnCamelCaseFieldName(camel_case_name, descriptor)); + const bool needs_custom_name = (raw_field_name != un_camel_case_name); + + SourceLocation location; + if (descriptor->GetSourceLocation(&location)) { + (*variables)["comments"] = BuildCommentsString(location, true); + } else { + (*variables)["comments"] = "\n"; + } + const TProtoStringType& classname = ClassName(descriptor->containing_type()); + (*variables)["classname"] = classname; + (*variables)["name"] = camel_case_name; + const TProtoStringType& capitalized_name = FieldNameCapitalized(descriptor); + (*variables)["capitalized_name"] = capitalized_name; + (*variables)["raw_field_name"] = raw_field_name; + (*variables)["field_number_name"] = + y_absl::StrCat(classname, "_FieldNumber_", capitalized_name); + (*variables)["field_number"] = y_absl::StrCat(descriptor->number()); + (*variables)["field_type"] = GetCapitalizedType(descriptor); + (*variables)["deprecated_attribute"] = + GetOptionalDeprecatedAttribute(descriptor); + std::vector<TProtoStringType> field_flags; + if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated"); + if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired"); + if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional"); + if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked"); + + // ObjC custom flags. + if (descriptor->has_default_value()) + field_flags.push_back("GPBFieldHasDefaultValue"); + if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom"); + if (descriptor->type() == FieldDescriptor::TYPE_ENUM) { + field_flags.push_back("GPBFieldHasEnumDescriptor"); + if (descriptor->enum_type()->is_closed()) { + field_flags.push_back("GPBFieldClosedEnum"); + } + } + // It will clear on a zero value if... + // - not repeated/map + // - doesn't have presence + bool clear_on_zero = + (!descriptor->is_repeated() && !descriptor->has_presence()); + if (clear_on_zero) { + field_flags.push_back("GPBFieldClearHasIvarOnZero"); + } + + (*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags); + + (*variables)["default"] = DefaultValue(descriptor); + (*variables)["default_name"] = GPBGenericValueFieldName(descriptor); + + (*variables)["dataTypeSpecific_name"] = "clazz"; + (*variables)["dataTypeSpecific_value"] = "Nil"; + + (*variables)["storage_offset_value"] = y_absl::StrCat( + "(arc_ui32)offsetof(", classname, "__storage_, ", camel_case_name, ")"); + (*variables)["storage_offset_comment"] = ""; + + // Clear some common things so they can be set just when needed. + (*variables)["storage_attribute"] = ""; +} + +bool HasNonZeroDefaultValue(const FieldDescriptor* field) { + // Repeated fields don't have defaults. + if (field->is_repeated()) { + return false; + } + + // As much as checking field->has_default_value() seems useful, it isn't + // because of enums. proto2 syntax allows the first item in an enum (the + // default) to be non zero. So checking field->has_default_value() would + // result in missing this non zero default. See MessageWithOneBasedEnum in + // objectivec/Tests/unittest_objc.proto for a test Message to confirm this. + + // Some proto file set the default to the zero value, so make sure the value + // isn't the zero case. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return field->default_value_int32() != 0; + case FieldDescriptor::CPPTYPE_UINT32: + return field->default_value_uint32() != 0U; + case FieldDescriptor::CPPTYPE_INT64: + return field->default_value_int64() != 0LL; + case FieldDescriptor::CPPTYPE_UINT64: + return field->default_value_uint64() != 0ULL; + case FieldDescriptor::CPPTYPE_DOUBLE: + return field->default_value_double() != 0.0; + case FieldDescriptor::CPPTYPE_FLOAT: + return field->default_value_float() != 0.0f; + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool(); + case FieldDescriptor::CPPTYPE_STRING: { + const TProtoStringType& default_string = field->default_value_string(); + return default_string.length() != 0; + } + case FieldDescriptor::CPPTYPE_ENUM: + return field->default_value_enum()->number() != 0; + case FieldDescriptor::CPPTYPE_MESSAGE: + return false; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + Y_ABSL_LOG(FATAL) << "Can't get here."; + return false; +} + +} // namespace + +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { + FieldGenerator* result = nullptr; + if (field->is_repeated()) { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + if (field->is_map()) { + result = new MapFieldGenerator(field); + } else { + result = new RepeatedMessageFieldGenerator(field); + } + break; + } + case OBJECTIVECTYPE_ENUM: + result = new RepeatedEnumFieldGenerator(field); + break; + default: + result = new RepeatedPrimitiveFieldGenerator(field); + break; + } + } else { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + result = new MessageFieldGenerator(field); + break; + } + case OBJECTIVECTYPE_ENUM: + result = new EnumFieldGenerator(field); + break; + default: + if (IsReferenceType(field)) { + result = new PrimitiveObjFieldGenerator(field); + } else { + result = new PrimitiveFieldGenerator(field); + } + break; + } + } + result->FinishInitialization(); + return result; +} + +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) + : descriptor_(descriptor) { + SetCommonFieldVariables(descriptor, &variables_); +} + +void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const { + printer->Print(variables_, "$field_number_name$ = $field_number$,\n"); +} + +void FieldGenerator::GenerateCFunctionDeclarations(io::Printer* printer) const { + // Nothing +} + +void FieldGenerator::GenerateCFunctionImplementations( + io::Printer* printer) const { + // Nothing +} + +void FieldGenerator::DetermineForwardDeclarations( + y_absl::btree_set<TProtoStringType>* fwd_decls, + bool include_external_types) const { + // Nothing +} + +void FieldGenerator::DetermineObjectiveCClassDefinitions( + y_absl::btree_set<TProtoStringType>* fwd_decls) const { + // Nothing +} + +void FieldGenerator::GenerateFieldDescription(io::Printer* printer, + bool include_default) const { + // Printed in the same order as the structure decl. + if (include_default) { + // clang-format off + printer->Print( + variables_, + "{\n" + " .defaultValue.$default_name$ = $default$,\n" + " .core.name = \"$name$\",\n" + " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n" + " .core.number = $field_number_name$,\n" + " .core.hasIndex = $has_index$,\n" + " .core.offset = $storage_offset_value$,$storage_offset_comment$\n" + " .core.flags = $fieldflags$,\n" + " .core.dataType = GPBDataType$field_type$,\n" + "},\n"); + // clang-format on + } else { + // clang-format off + printer->Print( + variables_, + "{\n" + " .name = \"$name$\",\n" + " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n" + " .number = $field_number_name$,\n" + " .hasIndex = $has_index$,\n" + " .offset = $storage_offset_value$,$storage_offset_comment$\n" + " .flags = $fieldflags$,\n" + " .dataType = GPBDataType$field_type$,\n" + "},\n"); + // clang-format on + } +} + +void FieldGenerator::SetRuntimeHasBit(int has_index) { + variables_["has_index"] = y_absl::StrCat(has_index); +} + +void FieldGenerator::SetNoHasBit() { variables_["has_index"] = "GPBNoHasBit"; } + +int FieldGenerator::ExtraRuntimeHasBitsNeeded() const { return 0; } + +void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { + Y_ABSL_LOG(FATAL) + << "Error: should have overridden SetExtraRuntimeHasBitsBase()."; +} + +void FieldGenerator::SetOneofIndexBase(int index_base) { + const OneofDescriptor* oneof = descriptor_->real_containing_oneof(); + if (oneof != nullptr) { + int index = oneof->index() + index_base; + // Flip the sign to mark it as a oneof. + variables_["has_index"] = y_absl::StrCat(-index); + } +} + +bool FieldGenerator::WantsHasProperty() const { + return descriptor_->has_presence() && !descriptor_->real_containing_oneof(); +} + +void FieldGenerator::FinishInitialization() { + // If "property_type" wasn't set, make it "storage_type". + if ((variables_.find("property_type") == variables_.end()) && + (variables_.find("storage_type") != variables_.end())) { + variables_["property_type"] = variable("storage_type"); + } +} + +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { + // Nothing +} + +void SingleFieldGenerator::GenerateFieldStorageDeclaration( + io::Printer* printer) const { + printer->Print(variables_, "$storage_type$ $name$;\n"); +} + +void SingleFieldGenerator::GeneratePropertyDeclaration( + io::Printer* printer) const { + printer->Print(variables_, "$comments$"); + // clang-format off + printer->Print( + variables_, + "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"); + // clang-format on + if (WantsHasProperty()) { + // clang-format off + printer->Print( + variables_, + "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); + // clang-format on + } + printer->Print("\n"); +} + +void SingleFieldGenerator::GeneratePropertyImplementation( + io::Printer* printer) const { + if (WantsHasProperty()) { + printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n"); + } else { + printer->Print(variables_, "@dynamic $name$;\n"); + } +} + +bool SingleFieldGenerator::RuntimeUsesHasBit() const { + if (descriptor_->real_containing_oneof()) { + // The oneof tracks what is set instead. + return false; + } + return true; +} + +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { + variables_["property_storage_attribute"] = "strong"; + if (IsRetainedName(variables_["name"])) { + variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; + } +} + +void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration( + io::Printer* printer) const { + printer->Print(variables_, "$storage_type$ *$name$;\n"); +} + +void ObjCObjFieldGenerator::GeneratePropertyDeclaration( + io::Printer* printer) const { + // Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that + // it uses pointers and deals with Objective-C's rules around storage name + // conventions (init*, new*, etc.) + + printer->Print(variables_, "$comments$"); + // clang-format off + printer->Print( + variables_, + "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"); + // clang-format on + if (WantsHasProperty()) { + // clang-format off + printer->Print( + variables_, + "/** Test to see if @c $name$ has been set. */\n" + "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); + // clang-format on + } + if (IsInitName(variables_.find("name")->second)) { + // If property name starts with init we need to annotate it to get past ARC. + // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 + printer->Print(variables_, + "- ($property_type$ *)$name$ " + "GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); + } + printer->Print("\n"); +} + +RepeatedFieldGenerator::RepeatedFieldGenerator( + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { + // Default to no comment and let the cases needing it fill it in. + variables_["array_comment"] = ""; +} + +void RepeatedFieldGenerator::FinishInitialization() { + FieldGenerator::FinishInitialization(); + if (variables_.find("array_property_type") == variables_.end()) { + variables_["array_property_type"] = variable("array_storage_type"); + } +} + +void RepeatedFieldGenerator::GenerateFieldStorageDeclaration( + io::Printer* printer) const { + printer->Print(variables_, "$array_storage_type$ *$name$;\n"); +} + +void RepeatedFieldGenerator::GeneratePropertyImplementation( + io::Printer* printer) const { + printer->Print(variables_, "@dynamic $name$, $name$_Count;\n"); +} + +void RepeatedFieldGenerator::GeneratePropertyDeclaration( + io::Printer* printer) const { + // Repeated fields don't need the has* properties, but they do expose a + // *Count (to check without autocreation). So for the field property we need + // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for + // dealing with needing Objective-C's rules around storage name conventions + // (init*, new*, etc.) + + // clang-format off + printer->Print( + variables_, + "$comments$" + "$array_comment$" + "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n" + "/** The number of items in @c $name$ without causing the container to be created. */\n" + "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n"); + // clang-format on + if (IsInitName(variables_.find("name")->second)) { + // If property name starts with init we need to annotate it to get past ARC. + // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227 + // clang-format off + printer->Print(variables_, + "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); + // clang-format on + } + printer->Print("\n"); +} + +bool RepeatedFieldGenerator::RuntimeUsesHasBit() const { + return false; // The array (or map/dict) having anything is what is used. +} + +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))); + } + for (int i = 0; i < descriptor->extension_count(); i++) { + extension_generators_[i].reset( + FieldGenerator::Make(descriptor->extension(i))); + } +} + +const FieldGenerator& FieldGeneratorMap::get( + const FieldDescriptor* field) const { + Y_ABSL_CHECK_EQ(field->containing_type(), descriptor_); + return *field_generators_[field->index()]; +} + +const FieldGenerator& FieldGeneratorMap::get_extension(int index) const { + return *extension_generators_[index]; +} + +int FieldGeneratorMap::CalculateHasBits() { + int total_bits = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + if (field_generators_[i]->RuntimeUsesHasBit()) { + field_generators_[i]->SetRuntimeHasBit(total_bits); + ++total_bits; + } else { + field_generators_[i]->SetNoHasBit(); + } + int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded(); + if (extra_bits) { + field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits); + total_bits += extra_bits; + } + } + return total_bits; +} + +void FieldGeneratorMap::SetOneofIndexBase(int index_base) { + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_[i]->SetOneofIndexBase(index_base); + } +} + +bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault() const { + for (int i = 0; i < descriptor_->field_count(); i++) { + if (HasNonZeroDefaultValue(descriptor_->field(i))) { + return true; + } + } + + return false; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google |