diff options
author | nechda <nechda@yandex-team.com> | 2024-08-29 23:50:27 +0300 |
---|---|---|
committer | nechda <nechda@yandex-team.com> | 2024-08-30 00:05:25 +0300 |
commit | e10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch) | |
tree | 571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc | |
parent | e79b38f2bbbf78d295d1901d2a79f898022d5224 (diff) | |
download | ydb-e10d6638f07a82edae3ea8197b9f5c0affcc07ea.tar.gz |
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/enum.cc')
-rw-r--r-- | contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc new file mode 100644 index 0000000000..5b23792af4 --- /dev/null +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc @@ -0,0 +1,294 @@ +// 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/enum.h" + +#include <algorithm> +#include <limits> +#include <string> + +#include "y_absl/container/flat_hash_set.h" +#include "y_absl/strings/escaping.h" +#include "y_absl/strings/str_cat.h" +#include "google/protobuf/compiler/objectivec/helpers.h" +#include "google/protobuf/compiler/objectivec/names.h" +#include "google/protobuf/compiler/objectivec/text_format_decode_data.h" +#include "google/protobuf/io/printer.h" + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { +namespace { +TProtoStringType SafelyPrintIntToCode(int v) { + if (v == std::numeric_limits<int>::min()) { + // Some compilers try to parse -2147483648 as two tokens and then get spicy + // about the fact that +2147483648 cannot be represented as an int. + return y_absl::StrCat(v + 1, " - 1"); + } else { + return y_absl::StrCat(v); + } +} +} // namespace + +EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) + : descriptor_(descriptor), name_(EnumName(descriptor_)) { + // Track the names for the enum values, and if an alias overlaps a base + // value, skip making a name for it. Likewise if two alias overlap, the + // first one wins. + // The one gap in this logic is if two base values overlap, but for that + // to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar", + // and if an enum has that, it is already going to be confusing and a + // compile error is just fine. + // The values are still tracked to support the reflection apis and + // TextFormat handing since they are different there. + y_absl::flat_hash_set<TProtoStringType> value_names; + + for (int i = 0; i < descriptor_->value_count(); i++) { + const EnumValueDescriptor* value = descriptor_->value(i); + const EnumValueDescriptor* canonical_value = + descriptor_->FindValueByNumber(value->number()); + + if (value == canonical_value) { + base_values_.push_back(value); + value_names.insert(EnumValueName(value)); + } else { + if (!value_names.insert(EnumValueName(value)).second) { + alias_values_to_skip_.insert(value); + } + } + all_values_.push_back(value); + } +} + +void EnumGenerator::GenerateHeader(io::Printer* printer) const { + TProtoStringType enum_comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + enum_comments = BuildCommentsString(location, true); + } else { + enum_comments = ""; + } + + printer->Print( + "#pragma mark - Enum $name$\n" + "\n", + "name", name_); + + // Swift 5 included SE0192 "Handling Future Enum Cases" + // https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md + // Since a .proto file can get new values added to an enum at any time, they + // are effectively "non-frozen". Even in a proto3 syntax file where there is + // support for the unknown value, an edit to the file can always add a new + // value moving something from unknown to known. Since Swift is now ABI + // stable, it also means a binary could contain Swift compiled against one + // version of the .pbobjc.h file, but finally linked against an enum with + // more cases. So the Swift code will always have to treat ObjC Proto Enums + // as "non-frozen". The default behavior in SE0192 is for all objc enums to + // be "non-frozen" unless marked as otherwise, so this means this generation + // doesn't have to bother with the `enum_extensibility` attribute, as the + // default will be what is needed. + + printer->Print( + "$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n", + "comments", enum_comments, "deprecated_attribute", + GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()), "name", + name_); + printer->Indent(); + + if (!descriptor_->is_closed()) { + // Include the unknown value. + printer->Print( + // clang-format off + "/**\n" + " * Value used if any message's field encounters a value that is not defined\n" + " * by this enum. The message will also have C functions to get/set the rawValue\n" + " * of the field.\n" + " **/\n" + "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n", + // clang-format on + "name", name_); + } + for (int i = 0; i < all_values_.size(); i++) { + if (alias_values_to_skip_.find(all_values_[i]) != + alias_values_to_skip_.end()) { + continue; + } + if (all_values_[i]->GetSourceLocation(&location)) { + TProtoStringType comments = BuildCommentsString(location, true); + if (comments.length() > 0) { + if (i > 0) { + printer->Print("\n"); + } + printer->Print(comments); + } + } + + printer->Print("$name$$deprecated_attribute$ = $value$,\n", "name", + EnumValueName(all_values_[i]), "deprecated_attribute", + GetOptionalDeprecatedAttribute(all_values_[i]), "value", + SafelyPrintIntToCode(all_values_[i]->number())); + } + printer->Outdent(); + printer->Print( + // clang-format off + "};\n" + "\n" + "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n" + "\n" + "/**\n" + " * Checks to see if the given value is defined by the enum or was not known at\n" + " * the time this source was generated.\n" + " **/\n" + "BOOL $name$_IsValidValue(arc_i32 value);\n" + // clang-format on + "\n", + "name", name_); +} + +void EnumGenerator::GenerateSource(io::Printer* printer) const { + printer->Print( + "#pragma mark - Enum $name$\n" + "\n", + "name", name_); + + // Note: For the TextFormat decode info, we can't use the enum value as + // the key because protocol buffer enums have 'allow_alias', which lets + // a value be used more than once. Instead, the index into the list of + // enum value descriptions is used. Note: start with -1 so the first one + // will be zero. + TextFormatDecodeData text_format_decode_data; + int enum_value_description_key = -1; + TProtoStringType text_blob; + + for (int i = 0; i < all_values_.size(); i++) { + ++enum_value_description_key; + TProtoStringType short_name(EnumValueShortName(all_values_[i])); + text_blob += short_name + '\0'; + if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) { + text_format_decode_data.AddString(enum_value_description_key, short_name, + all_values_[i]->name()); + } + } + + printer->Print( + // clang-format off + "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" + " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n" + " if (!descriptor) {\n" + " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n", + // clang-format on + "name", name_); + + static const int kBytesPerLine = 40; // allow for escaping + printer->Print(" static const char *valueNames ="); + for (int i = 0; i < text_blob.size(); i += kBytesPerLine) { + printer->Print( + "\n \"$data$\"", "data", + EscapeTrigraphs(y_absl::CEscape(text_blob.substr(i, kBytesPerLine)))); + } + printer->Print( + ";\n" + " static const arc_i32 values[] = {\n"); + for (int i = 0; i < all_values_.size(); i++) { + printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i])); + } + printer->Print(" };\n"); + + if (text_format_decode_data.num_entries() == 0) { + printer->Print( + // clang-format off + " GPBEnumDescriptor *worker =\n" + " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " valueNames:valueNames\n" + " values:values\n" + " count:(arc_ui32)(sizeof(values) / sizeof(arc_i32))\n" + " enumVerifier:$name$_IsValidValue\n" + " flags:$flags$];\n", + // clang-format on + "name", name_, "flags", + (descriptor_->is_closed() + ? "GPBEnumDescriptorInitializationFlag_IsClosed" + : "GPBEnumDescriptorInitializationFlag_None")); + } else { + printer->Print( + // clang-format off + " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n" + " GPBEnumDescriptor *worker =\n" + " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " valueNames:valueNames\n" + " values:values\n" + " count:(arc_ui32)(sizeof(values) / sizeof(arc_i32))\n" + " enumVerifier:$name$_IsValidValue\n" + " flags:$flags$\n" + " extraTextFormatInfo:extraTextFormatInfo];\n", + // clang-format on + "name", name_, "flags", + (descriptor_->is_closed() + ? "GPBEnumDescriptorInitializationFlag_IsClosed" + : "GPBEnumDescriptorInitializationFlag_None"), + "extraTextFormatInfo", y_absl::CEscape(text_format_decode_data.Data())); + } + // clang-format off + printer->Print( + " GPBEnumDescriptor *expected = nil;\n" + " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n" + " [worker release];\n" + " }\n" + " }\n" + " return descriptor;\n" + "}\n\n"); + // clang-format on + + printer->Print( + // clang-format off + "BOOL $name$_IsValidValue(arc_i32 value__) {\n" + " switch (value__) {\n", + // clang-format on + "name", name_); + + for (int i = 0; i < base_values_.size(); i++) { + printer->Print(" case $name$:\n", "name", + EnumValueName(base_values_[i])); + } + + // clang-format off + printer->Print( + " return YES;\n" + " default:\n" + " return NO;\n" + " }\n" + "}\n\n"); + // clang-format on +} +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google |