diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:08 +0300 |
commit | 4e839db24a3bbc9f1c610c43d6faaaa99824dcca (patch) | |
tree | 506dac10f5df94fab310584ee51b24fc5a081c22 /contrib/libs/protoc/src/google/protobuf/compiler/objectivec | |
parent | 2d37894b1b037cf24231090eda8589bbb44fb6fc (diff) | |
download | ydb-4e839db24a3bbc9f1c610c43d6faaaa99824dcca.tar.gz |
Restoring authorship annotation for <thegeorg@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/objectivec')
25 files changed, 6397 insertions, 6397 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc index 8149a47c83..80c6833aae 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc @@ -1,261 +1,261 @@ -// 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_enum.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> -#include <algorithm> // std::find() - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -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. - std::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 { - TProtoStringType value_name(EnumValueName(value)); - if (value_names.find(value_name) != value_names.end()) { - alias_values_to_skip_.insert(value); - } else { - value_names.insert(value_name); - } - } - all_values_.push_back(value); - } -} - -EnumGenerator::~EnumGenerator() {} - -void EnumGenerator::GenerateHeader(io::Printer* printer) { - 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 (HasPreservingUnknownEnumSemantics(descriptor_->file())) { - // Include the unknown value. - printer->Print( - "/**\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", - "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; - } - SourceLocation location; - if (all_values_[i]->GetSourceLocation(&location)) { - TProtoStringType comments = BuildCommentsString(location, true).c_str(); - if (comments.length() > 0) { - if (i > 0) { - printer->Print("\n"); - } - printer->Print(comments.c_str()); - } - } - - printer->Print( - "$name$$deprecated_attribute$ = $value$,\n", - "name", EnumValueName(all_values_[i]), - "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]), - "value", StrCat(all_values_[i]->number())); - } - printer->Outdent(); - printer->Print( - "};\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(int32_t value);\n" - "\n", - "name", name_); -} - -void EnumGenerator::GenerateSource(io::Printer* printer) { - 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( - "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" - " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n" - " if (!descriptor) {\n", - "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(CEscape(text_blob.substr(i, kBytesPerLine)))); - } - printer->Print( - ";\n" - " static const int32_t 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( - " GPBEnumDescriptor *worker =\n" - " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" - " valueNames:valueNames\n" - " values:values\n" - " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n" - " enumVerifier:$name$_IsValidValue];\n", - "name", name_); - } else { - printer->Print( - " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n" - " GPBEnumDescriptor *worker =\n" - " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" - " valueNames:valueNames\n" - " values:values\n" - " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n" - " enumVerifier:$name$_IsValidValue\n" - " extraTextFormatInfo:extraTextFormatInfo];\n", - "name", name_, - "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); - } - 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"); - - printer->Print( - "BOOL $name$_IsValidValue(int32_t value__) {\n" - " switch (value__) {\n", - "name", name_); - - for (int i = 0; i < base_values_.size(); i++) { - printer->Print( - " case $name$:\n", - "name", EnumValueName(base_values_[i])); - } - - printer->Print( - " return YES;\n" - " default:\n" - " return NO;\n" - " }\n" - "}\n\n"); -} -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_enum.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> +#include <algorithm> // std::find() + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +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. + std::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 { + TProtoStringType value_name(EnumValueName(value)); + if (value_names.find(value_name) != value_names.end()) { + alias_values_to_skip_.insert(value); + } else { + value_names.insert(value_name); + } + } + all_values_.push_back(value); + } +} + +EnumGenerator::~EnumGenerator() {} + +void EnumGenerator::GenerateHeader(io::Printer* printer) { + 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 (HasPreservingUnknownEnumSemantics(descriptor_->file())) { + // Include the unknown value. + printer->Print( + "/**\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", + "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; + } + SourceLocation location; + if (all_values_[i]->GetSourceLocation(&location)) { + TProtoStringType comments = BuildCommentsString(location, true).c_str(); + if (comments.length() > 0) { + if (i > 0) { + printer->Print("\n"); + } + printer->Print(comments.c_str()); + } + } + + printer->Print( + "$name$$deprecated_attribute$ = $value$,\n", + "name", EnumValueName(all_values_[i]), + "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]), + "value", StrCat(all_values_[i]->number())); + } + printer->Outdent(); + printer->Print( + "};\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(int32_t value);\n" + "\n", + "name", name_); +} + +void EnumGenerator::GenerateSource(io::Printer* printer) { + 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( + "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n" + " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n" + " if (!descriptor) {\n", + "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(CEscape(text_blob.substr(i, kBytesPerLine)))); + } + printer->Print( + ";\n" + " static const int32_t 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( + " GPBEnumDescriptor *worker =\n" + " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " valueNames:valueNames\n" + " values:values\n" + " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n" + " enumVerifier:$name$_IsValidValue];\n", + "name", name_); + } else { + printer->Print( + " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n" + " GPBEnumDescriptor *worker =\n" + " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n" + " valueNames:valueNames\n" + " values:values\n" + " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n" + " enumVerifier:$name$_IsValidValue\n" + " extraTextFormatInfo:extraTextFormatInfo];\n", + "name", name_, + "extraTextFormatInfo", CEscape(text_format_decode_data.Data())); + } + 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"); + + printer->Print( + "BOOL $name$_IsValidValue(int32_t value__) {\n" + " switch (value__) {\n", + "name", name_); + + for (int i = 0; i < base_values_.size(); i++) { + printer->Print( + " case $name$:\n", + "name", EnumValueName(base_values_[i])); + } + + printer->Print( + " return YES;\n" + " default:\n" + " return NO;\n" + " }\n" + "}\n\n"); +} +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h index 4d0404bcb3..0bc342ace2 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h @@ -1,71 +1,71 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ - -#include <string> -#include <set> -#include <vector> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class EnumGenerator { - public: - explicit EnumGenerator(const EnumDescriptor* descriptor); - ~EnumGenerator(); - - EnumGenerator(const EnumGenerator&) = delete; - EnumGenerator& operator=(const EnumGenerator&) = delete; - - void GenerateHeader(io::Printer* printer); - void GenerateSource(io::Printer* printer); - - const TProtoStringType& name() const { return name_; } - - private: - const EnumDescriptor* descriptor_; - std::vector<const EnumValueDescriptor*> base_values_; - std::vector<const EnumValueDescriptor*> all_values_; - std::set<const EnumValueDescriptor*> alias_values_to_skip_; - const TProtoStringType name_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumGenerator { + public: + explicit EnumGenerator(const EnumDescriptor* descriptor); + ~EnumGenerator(); + + EnumGenerator(const EnumGenerator&) = delete; + EnumGenerator& operator=(const EnumGenerator&) = delete; + + void GenerateHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + + const TProtoStringType& name() const { return name_; } + + private: + const EnumDescriptor* descriptor_; + std::vector<const EnumValueDescriptor*> base_values_; + std::vector<const EnumValueDescriptor*> all_values_; + std::set<const EnumValueDescriptor*> alias_values_to_skip_; + const TProtoStringType name_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__ 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 cd0d721066..9fb44f83ee 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 @@ -1,149 +1,149 @@ -// 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -namespace { - -void SetEnumVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables) { - TProtoStringType type = EnumName(descriptor->enum_type()); - (*variables)["storage_type"] = type; - // For non repeated fields, if it was defined in a different file, the - // property decls need to use "enum NAME" rather than just "NAME" to support - // the forward declaration of the enums. - if (!descriptor->is_repeated() && - (descriptor->file() != descriptor->enum_type()->file())) { - (*variables)["property_type"] = "enum " + type; - } - (*variables)["enum_verifier"] = type + "_IsValidValue"; - (*variables)["enum_desc_func"] = type + "_EnumDescriptor"; - - (*variables)["dataTypeSpecific_name"] = "enumDescFunc"; - (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"]; - - const Descriptor* msg_descriptor = descriptor->containing_type(); - (*variables)["owning_message_class"] = ClassName(msg_descriptor); -} -} // namespace - -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { - SetEnumVariables(descriptor, &variables_); -} - -EnumFieldGenerator::~EnumFieldGenerator() {} - -void EnumFieldGenerator::GenerateCFunctionDeclarations( - io::Printer* printer) const { - if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { - return; - } - - printer->Print( - variables_, - "/**\n" - " * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n" - " * if the value was not defined by the enum at the time the code was generated.\n" - " **/\n" - "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n" - "/**\n" - " * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n" - " * it to be set to a value that was not defined by the enum at the time the code\n" - " * was generated.\n" - " **/\n" - "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n" - "\n"); -} - -void EnumFieldGenerator::GenerateCFunctionImplementations( - io::Printer* printer) const { - if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return; - - printer->Print( - variables_, - "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n" - " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" - " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" - " return GPBGetMessageRawEnumField(message, field);\n" - "}\n" - "\n" - "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n" - " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" - " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" - " GPBSetMessageRawEnumField(message, field, value);\n" - "}\n" - "\n"); -} - -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()) { - // Enum name is already in "storage_type". - const TProtoStringType& name = variable("storage_type"); - fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); - } -} - -RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { - SetEnumVariables(descriptor, &variables_); - variables_["array_storage_type"] = "GPBEnumArray"; -} - -RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} - -void RepeatedEnumFieldGenerator::FinishInitialization(void) { - RepeatedFieldGenerator::FinishInitialization(); - variables_["array_comment"] = - "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n"; -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +void SetEnumVariables(const FieldDescriptor* descriptor, + std::map<TProtoStringType, TProtoStringType>* variables) { + TProtoStringType type = EnumName(descriptor->enum_type()); + (*variables)["storage_type"] = type; + // For non repeated fields, if it was defined in a different file, the + // property decls need to use "enum NAME" rather than just "NAME" to support + // the forward declaration of the enums. + if (!descriptor->is_repeated() && + (descriptor->file() != descriptor->enum_type()->file())) { + (*variables)["property_type"] = "enum " + type; + } + (*variables)["enum_verifier"] = type + "_IsValidValue"; + (*variables)["enum_desc_func"] = type + "_EnumDescriptor"; + + (*variables)["dataTypeSpecific_name"] = "enumDescFunc"; + (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"]; + + const Descriptor* msg_descriptor = descriptor->containing_type(); + (*variables)["owning_message_class"] = ClassName(msg_descriptor); +} +} // namespace + +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : SingleFieldGenerator(descriptor, options) { + SetEnumVariables(descriptor, &variables_); +} + +EnumFieldGenerator::~EnumFieldGenerator() {} + +void EnumFieldGenerator::GenerateCFunctionDeclarations( + io::Printer* printer) const { + if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) { + return; + } + + printer->Print( + variables_, + "/**\n" + " * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n" + " * if the value was not defined by the enum at the time the code was generated.\n" + " **/\n" + "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n" + "/**\n" + " * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n" + " * it to be set to a value that was not defined by the enum at the time the code\n" + " * was generated.\n" + " **/\n" + "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n" + "\n"); +} + +void EnumFieldGenerator::GenerateCFunctionImplementations( + io::Printer* printer) const { + if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return; + + printer->Print( + variables_, + "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n" + " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" + " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" + " return GPBGetMessageRawEnumField(message, field);\n" + "}\n" + "\n" + "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n" + " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" + " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n" + " GPBSetMessageRawEnumField(message, field, value);\n" + "}\n" + "\n"); +} + +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()) { + // Enum name is already in "storage_type". + const TProtoStringType& name = variable("storage_type"); + fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")"); + } +} + +RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : RepeatedFieldGenerator(descriptor, options) { + SetEnumVariables(descriptor, &variables_); + variables_["array_storage_type"] = "GPBEnumArray"; +} + +RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {} + +void RepeatedEnumFieldGenerator::FinishInitialization(void) { + RepeatedFieldGenerator::FinishInitialization(); + variables_["array_comment"] = + "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n"; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 7016c8022c..55c46a14fa 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 @@ -1,78 +1,78 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - EnumFieldGenerator(const EnumFieldGenerator&) = delete; - EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; - - public: - virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; - virtual void GenerateCFunctionImplementations(io::Printer* printer) const; - virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; - - protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - virtual ~EnumFieldGenerator(); -}; - -class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - public: - virtual void FinishInitialization(); - - protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual ~RepeatedEnumFieldGenerator(); -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumFieldGenerator : public SingleFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + EnumFieldGenerator(const EnumFieldGenerator&) = delete; + EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; + + public: + virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; + virtual void GenerateCFunctionImplementations(io::Printer* printer) const; + virtual void DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const; + + protected: + EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + virtual ~EnumFieldGenerator(); +}; + +class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + public: + virtual void FinishInitialization(); + + protected: + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual ~RepeatedEnumFieldGenerator(); +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__ diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc index dbbce48952..572b27a5c5 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc @@ -1,156 +1,156 @@ -// 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 <iostream> - -#include <google/protobuf/compiler/objectivec/objectivec_extension.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -ExtensionGenerator::ExtensionGenerator(const TProtoStringType& root_class_name, - const FieldDescriptor* descriptor) - : method_name_(ExtensionMethodName(descriptor)), - root_class_and_method_name_(root_class_name + "_" + method_name_), - descriptor_(descriptor) { - if (descriptor->is_map()) { - // 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 errors. - std::cerr << "error: Extension is a map<>!" - << " That used to be blocked by the compiler." << std::endl; - std::cerr.flush(); - abort(); - } -} - -ExtensionGenerator::~ExtensionGenerator() {} - -void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { - std::map<TProtoStringType, TProtoStringType> vars; - vars["method_name"] = method_name_; - if (IsRetainedName(method_name_)) { - vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; - } else { - vars["storage_attribute"] = ""; - } - SourceLocation location; - if (descriptor_->GetSourceLocation(&location)) { - vars["comments"] = BuildCommentsString(location, true); - } else { - vars["comments"] = ""; - } - // Unlike normal message fields, check if the file for the extension was - // deprecated. - vars["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()); - printer->Print(vars, - "$comments$" - "+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n"); -} - -void ExtensionGenerator::GenerateStaticVariablesInitialization( - io::Printer* printer) { - std::map<TProtoStringType, TProtoStringType> vars; - vars["root_class_and_method_name"] = root_class_and_method_name_; - const TProtoStringType containing_type = ClassName(descriptor_->containing_type()); - vars["extended_type"] = ObjCClass(containing_type); - vars["number"] = StrCat(descriptor_->number()); - - std::vector<TProtoStringType> options; - if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated"); - if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked"); - if (descriptor_->containing_type()->options().message_set_wire_format()) { - options.push_back("GPBExtensionSetWireFormat"); - } - vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options); - - ObjectiveCType objc_type = GetObjectiveCType(descriptor_); - if (objc_type == OBJECTIVECTYPE_MESSAGE) { - TProtoStringType message_type = ClassName(descriptor_->message_type()); - vars["type"] = ObjCClass(message_type); - } else { - vars["type"] = "Nil"; - } - - vars["default_name"] = GPBGenericValueFieldName(descriptor_); - if (descriptor_->is_repeated()) { - vars["default"] = "nil"; - } else { - vars["default"] = DefaultValue(descriptor_); - } - TProtoStringType type = GetCapitalizedType(descriptor_); - vars["extension_type"] = TProtoStringType("GPBDataType") + type; - - if (objc_type == OBJECTIVECTYPE_ENUM) { - vars["enum_desc_func_name"] = - EnumName(descriptor_->enum_type()) + "_EnumDescriptor"; - } else { - vars["enum_desc_func_name"] = "NULL"; - } - - printer->Print(vars, - "{\n" - " .defaultValue.$default_name$ = $default$,\n" - " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n" - " .extendedClass.clazz = $extended_type$,\n" - " .messageOrGroupClass.clazz = $type$,\n" - " .enumDescriptorFunc = $enum_desc_func_name$,\n" - " .fieldNumber = $number$,\n" - " .dataType = $extension_type$,\n" - " .options = $options$,\n" - "},\n"); -} - -void ExtensionGenerator::DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) { - TProtoStringType extended_type = ClassName(descriptor_->containing_type()); - fwd_decls->insert(ObjCClassDeclaration(extended_type)); - ObjectiveCType objc_type = GetObjectiveCType(descriptor_); - if (objc_type == OBJECTIVECTYPE_MESSAGE) { - TProtoStringType message_type = ClassName(descriptor_->message_type()); - fwd_decls->insert(ObjCClassDeclaration(message_type)); - } -} - -void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) { - printer->Print( - "[registry addExtension:$root_class_and_method_name$];\n", - "root_class_and_method_name", root_class_and_method_name_); -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <iostream> + +#include <google/protobuf/compiler/objectivec/objectivec_extension.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +ExtensionGenerator::ExtensionGenerator(const TProtoStringType& root_class_name, + const FieldDescriptor* descriptor) + : method_name_(ExtensionMethodName(descriptor)), + root_class_and_method_name_(root_class_name + "_" + method_name_), + descriptor_(descriptor) { + if (descriptor->is_map()) { + // 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 errors. + std::cerr << "error: Extension is a map<>!" + << " That used to be blocked by the compiler." << std::endl; + std::cerr.flush(); + abort(); + } +} + +ExtensionGenerator::~ExtensionGenerator() {} + +void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) { + std::map<TProtoStringType, TProtoStringType> vars; + vars["method_name"] = method_name_; + if (IsRetainedName(method_name_)) { + vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; + } else { + vars["storage_attribute"] = ""; + } + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + vars["comments"] = BuildCommentsString(location, true); + } else { + vars["comments"] = ""; + } + // Unlike normal message fields, check if the file for the extension was + // deprecated. + vars["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()); + printer->Print(vars, + "$comments$" + "+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n"); +} + +void ExtensionGenerator::GenerateStaticVariablesInitialization( + io::Printer* printer) { + std::map<TProtoStringType, TProtoStringType> vars; + vars["root_class_and_method_name"] = root_class_and_method_name_; + const TProtoStringType containing_type = ClassName(descriptor_->containing_type()); + vars["extended_type"] = ObjCClass(containing_type); + vars["number"] = StrCat(descriptor_->number()); + + std::vector<TProtoStringType> options; + if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated"); + if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked"); + if (descriptor_->containing_type()->options().message_set_wire_format()) { + options.push_back("GPBExtensionSetWireFormat"); + } + vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options); + + ObjectiveCType objc_type = GetObjectiveCType(descriptor_); + if (objc_type == OBJECTIVECTYPE_MESSAGE) { + TProtoStringType message_type = ClassName(descriptor_->message_type()); + vars["type"] = ObjCClass(message_type); + } else { + vars["type"] = "Nil"; + } + + vars["default_name"] = GPBGenericValueFieldName(descriptor_); + if (descriptor_->is_repeated()) { + vars["default"] = "nil"; + } else { + vars["default"] = DefaultValue(descriptor_); + } + TProtoStringType type = GetCapitalizedType(descriptor_); + vars["extension_type"] = TProtoStringType("GPBDataType") + type; + + if (objc_type == OBJECTIVECTYPE_ENUM) { + vars["enum_desc_func_name"] = + EnumName(descriptor_->enum_type()) + "_EnumDescriptor"; + } else { + vars["enum_desc_func_name"] = "NULL"; + } + + printer->Print(vars, + "{\n" + " .defaultValue.$default_name$ = $default$,\n" + " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n" + " .extendedClass.clazz = $extended_type$,\n" + " .messageOrGroupClass.clazz = $type$,\n" + " .enumDescriptorFunc = $enum_desc_func_name$,\n" + " .fieldNumber = $number$,\n" + " .dataType = $extension_type$,\n" + " .options = $options$,\n" + "},\n"); +} + +void ExtensionGenerator::DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) { + TProtoStringType extended_type = ClassName(descriptor_->containing_type()); + fwd_decls->insert(ObjCClassDeclaration(extended_type)); + ObjectiveCType objc_type = GetObjectiveCType(descriptor_); + if (objc_type == OBJECTIVECTYPE_MESSAGE) { + TProtoStringType message_type = ClassName(descriptor_->message_type()); + fwd_decls->insert(ObjCClassDeclaration(message_type)); + } +} + +void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) { + printer->Print( + "[registry addExtension:$root_class_and_method_name$];\n", + "root_class_and_method_name", root_class_and_method_name_); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h index 04e59f9284..4c74c82ef9 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h @@ -1,67 +1,67 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ - -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class ExtensionGenerator { - public: - ExtensionGenerator(const TProtoStringType& root_class_name, - const FieldDescriptor* descriptor); - ~ExtensionGenerator(); - - ExtensionGenerator(const ExtensionGenerator&) = delete; - ExtensionGenerator& operator=(const ExtensionGenerator&) = delete; - - void GenerateMembersHeader(io::Printer* printer); - void GenerateStaticVariablesInitialization(io::Printer* printer); - void GenerateRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); - - private: - TProtoStringType method_name_; - TProtoStringType root_class_and_method_name_; - const FieldDescriptor* descriptor_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__ + +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class ExtensionGenerator { + public: + ExtensionGenerator(const TProtoStringType& root_class_name, + const FieldDescriptor* descriptor); + ~ExtensionGenerator(); + + ExtensionGenerator(const ExtensionGenerator&) = delete; + ExtensionGenerator& operator=(const ExtensionGenerator&) = delete; + + void GenerateMembersHeader(io::Printer* printer); + void GenerateStaticVariablesInitialization(io::Printer* printer); + void GenerateRegistrationSource(io::Printer* printer); + void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); + + private: + TProtoStringType method_name_; + TProtoStringType root_class_and_method_name_; + const FieldDescriptor* descriptor_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ 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 7fcd00a24c..9b2fee37c6 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 @@ -1,475 +1,475 @@ -// 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 <iostream> - -#include <google/protobuf/compiler/objectivec/objectivec_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_map_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -namespace { - -void SetCommonFieldVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, 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"] = - classname + "_FieldNumber_" + capitalized_name; - (*variables)["field_number"] = 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"); - } - // 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"] = - "(uint32_t)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"] = ""; -} - -} // namespace - -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { - FieldGenerator* result = NULL; - if (field->is_repeated()) { - switch (GetObjectiveCType(field)) { - case OBJECTIVECTYPE_MESSAGE: { - if (field->is_map()) { - result = new MapFieldGenerator(field, options); - } else { - result = new RepeatedMessageFieldGenerator(field, options); - } - break; - } - case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); - break; - default: - result = new RepeatedPrimitiveFieldGenerator(field, options); - break; - } - } else { - switch (GetObjectiveCType(field)) { - case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); - break; - } - case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); - break; - default: - if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); - } else { - result = new PrimitiveFieldGenerator(field, options); - } - break; - } - } - result->FinishInitialization(); - return result; -} - -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : descriptor_(descriptor) { - SetCommonFieldVariables(descriptor, &variables_); -} - -FieldGenerator::~FieldGenerator() {} - -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( - std::set<TProtoStringType>* fwd_decls) const { - // Nothing -} - -void FieldGenerator::DetermineObjectiveCClassDefinitions( - std::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) { - 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"); - } else { - 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"); - } -} - -void FieldGenerator::SetRuntimeHasBit(int has_index) { - variables_["has_index"] = StrCat(has_index); -} - -void FieldGenerator::SetNoHasBit(void) { - variables_["has_index"] = "GPBNoHasBit"; -} - -int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { - return 0; -} - -void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { - // 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 errors. - std::cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << std::endl; - std::cerr.flush(); - abort(); -} - -void FieldGenerator::SetOneofIndexBase(int index_base) { - const OneofDescriptor* oneof = descriptor_->real_containing_oneof(); - if (oneof != NULL) { - int index = oneof->index() + index_base; - // Flip the sign to mark it as a oneof. - variables_["has_index"] = StrCat(-index); - } -} - -bool FieldGenerator::WantsHasProperty(void) const { - return descriptor_->has_presence() && !descriptor_->real_containing_oneof(); -} - -void FieldGenerator::FinishInitialization(void) { - // 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, - const Options& options) - : FieldGenerator(descriptor, options) { - // Nothing -} - -SingleFieldGenerator::~SingleFieldGenerator() {} - -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$"); - printer->Print( - variables_, - "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n" - "\n"); - if (WantsHasProperty()) { - printer->Print( - variables_, - "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\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(void) const { - if (descriptor_->real_containing_oneof()) { - // The oneof tracks what is set instead. - return false; - } - return true; -} - -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { - variables_["property_storage_attribute"] = "strong"; - if (IsRetainedName(variables_["name"])) { - variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; - } -} - -ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {} - -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$"); - printer->Print( - variables_, - "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"); - if (WantsHasProperty()) { - printer->Print( - variables_, - "/** Test to see if @c $name$ has been set. */\n" - "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); - } - 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, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { - // Default to no comment and let the cases needing it fill it in. - variables_["array_comment"] = ""; -} - -RepeatedFieldGenerator::~RepeatedFieldGenerator() {} - -void RepeatedFieldGenerator::FinishInitialization(void) { - 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.) - - 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 array to be created. */\n" - "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n"); - 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_, - "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); - } - printer->Print("\n"); -} - -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) - : 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)); - } - for (int i = 0; i < descriptor->extension_count(); i++) { - extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); - } -} - -FieldGeneratorMap::~FieldGeneratorMap() {} - -const FieldGenerator& FieldGeneratorMap::get( - const FieldDescriptor* field) const { - GOOGLE_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(void) { - 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(void) 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 +// 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 <iostream> + +#include <google/protobuf/compiler/objectivec/objectivec_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/compiler/objectivec/objectivec_enum_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_map_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +void SetCommonFieldVariables(const FieldDescriptor* descriptor, + std::map<TProtoStringType, 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"] = + classname + "_FieldNumber_" + capitalized_name; + (*variables)["field_number"] = 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"); + } + // 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"] = + "(uint32_t)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"] = ""; +} + +} // namespace + +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options) { + FieldGenerator* result = NULL; + if (field->is_repeated()) { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + if (field->is_map()) { + result = new MapFieldGenerator(field, options); + } else { + result = new RepeatedMessageFieldGenerator(field, options); + } + break; + } + case OBJECTIVECTYPE_ENUM: + result = new RepeatedEnumFieldGenerator(field, options); + break; + default: + result = new RepeatedPrimitiveFieldGenerator(field, options); + break; + } + } else { + switch (GetObjectiveCType(field)) { + case OBJECTIVECTYPE_MESSAGE: { + result = new MessageFieldGenerator(field, options); + break; + } + case OBJECTIVECTYPE_ENUM: + result = new EnumFieldGenerator(field, options); + break; + default: + if (IsReferenceType(field)) { + result = new PrimitiveObjFieldGenerator(field, options); + } else { + result = new PrimitiveFieldGenerator(field, options); + } + break; + } + } + result->FinishInitialization(); + return result; +} + +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : descriptor_(descriptor) { + SetCommonFieldVariables(descriptor, &variables_); +} + +FieldGenerator::~FieldGenerator() {} + +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( + std::set<TProtoStringType>* fwd_decls) const { + // Nothing +} + +void FieldGenerator::DetermineObjectiveCClassDefinitions( + std::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) { + 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"); + } else { + 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"); + } +} + +void FieldGenerator::SetRuntimeHasBit(int has_index) { + variables_["has_index"] = StrCat(has_index); +} + +void FieldGenerator::SetNoHasBit(void) { + variables_["has_index"] = "GPBNoHasBit"; +} + +int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { + return 0; +} + +void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) { + // 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 errors. + std::cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << std::endl; + std::cerr.flush(); + abort(); +} + +void FieldGenerator::SetOneofIndexBase(int index_base) { + const OneofDescriptor* oneof = descriptor_->real_containing_oneof(); + if (oneof != NULL) { + int index = oneof->index() + index_base; + // Flip the sign to mark it as a oneof. + variables_["has_index"] = StrCat(-index); + } +} + +bool FieldGenerator::WantsHasProperty(void) const { + return descriptor_->has_presence() && !descriptor_->real_containing_oneof(); +} + +void FieldGenerator::FinishInitialization(void) { + // 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, + const Options& options) + : FieldGenerator(descriptor, options) { + // Nothing +} + +SingleFieldGenerator::~SingleFieldGenerator() {} + +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$"); + printer->Print( + variables_, + "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n" + "\n"); + if (WantsHasProperty()) { + printer->Print( + variables_, + "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\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(void) const { + if (descriptor_->real_containing_oneof()) { + // The oneof tracks what is set instead. + return false; + } + return true; +} + +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : SingleFieldGenerator(descriptor, options) { + variables_["property_storage_attribute"] = "strong"; + if (IsRetainedName(variables_["name"])) { + variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; + } +} + +ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {} + +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$"); + printer->Print( + variables_, + "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"); + if (WantsHasProperty()) { + printer->Print( + variables_, + "/** Test to see if @c $name$ has been set. */\n" + "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n"); + } + 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, const Options& options) + : ObjCObjFieldGenerator(descriptor, options) { + // Default to no comment and let the cases needing it fill it in. + variables_["array_comment"] = ""; +} + +RepeatedFieldGenerator::~RepeatedFieldGenerator() {} + +void RepeatedFieldGenerator::FinishInitialization(void) { + 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.) + + 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 array to be created. */\n" + "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n"); + 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_, + "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n"); + } + printer->Print("\n"); +} + +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) + : 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)); + } + for (int i = 0; i < descriptor->extension_count(); i++) { + extension_generators_[i].reset( + FieldGenerator::Make(descriptor->extension(i), options)); + } +} + +FieldGeneratorMap::~FieldGeneratorMap() {} + +const FieldGenerator& FieldGeneratorMap::get( + const FieldDescriptor* field) const { + GOOGLE_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(void) { + 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(void) 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 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 24c64dbc05..8f11166bf0 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 @@ -1,194 +1,194 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class FieldGenerator { - public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); - - virtual ~FieldGenerator(); - - FieldGenerator(const FieldGenerator&) = delete; - FieldGenerator& operator=(const FieldGenerator&) = delete; - - // Exposed for subclasses to fill in. - virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0; - virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0; - virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0; - - // Called by GenerateFieldDescription, exposed for classes that need custom - // generation. - - // Exposed for subclasses to extend, base does nothing. - virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; - virtual void GenerateCFunctionImplementations(io::Printer* printer) const; - - // Exposed for subclasses, should always call it on the parent class also. - virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const; - - // Used during generation, not intended to be extended by subclasses. - void GenerateFieldDescription( - io::Printer* printer, bool include_default) const; - void GenerateFieldNumberConstant(io::Printer* printer) const; - - // Exposed to get and set the has bits information. - virtual bool RuntimeUsesHasBit(void) const = 0; - void SetRuntimeHasBit(int has_index); - void SetNoHasBit(void); - virtual int ExtraRuntimeHasBitsNeeded(void) const; - virtual void SetExtraRuntimeHasBitsBase(int index_base); - void SetOneofIndexBase(int index_base); - - TProtoStringType variable(const char* key) const { - return variables_.find(key)->second; - } - - bool needs_textformat_name_support() const { - const TProtoStringType& field_flags = variable("fieldflags"); - return field_flags.find("GPBFieldTextFormatNameCustom") != - TProtoStringType::npos; - } - TProtoStringType generated_objc_name() const { return variable("name"); } - TProtoStringType raw_field_name() const { return variable("raw_field_name"); } - - protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); - - virtual void FinishInitialization(void); - bool WantsHasProperty(void) const; - - const FieldDescriptor* descriptor_; - std::map<TProtoStringType, TProtoStringType> variables_; -}; - -class SingleFieldGenerator : public FieldGenerator { - public: - virtual ~SingleFieldGenerator(); - - SingleFieldGenerator(const SingleFieldGenerator&) = delete; - SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete; - - virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; - virtual void GeneratePropertyDeclaration(io::Printer* printer) const; - - virtual void GeneratePropertyImplementation(io::Printer* printer) const; - - virtual bool RuntimeUsesHasBit(void) const; - - protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); -}; - -// Subclass with common support for when the field ends up as an ObjC Object. -class ObjCObjFieldGenerator : public SingleFieldGenerator { - public: - virtual ~ObjCObjFieldGenerator(); - - ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete; - ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete; - - virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; - virtual void GeneratePropertyDeclaration(io::Printer* printer) const; - - protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); -}; - -class RepeatedFieldGenerator : public ObjCObjFieldGenerator { - public: - virtual ~RepeatedFieldGenerator(); - - RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete; - RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete; - - virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; - virtual void GeneratePropertyDeclaration(io::Printer* printer) const; - - virtual void GeneratePropertyImplementation(io::Printer* printer) const; - - virtual bool RuntimeUsesHasBit(void) const; - - protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual void FinishInitialization(void); -}; - -// Convenience class which constructs FieldGenerators for a Descriptor. -class FieldGeneratorMap { - public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); - ~FieldGeneratorMap(); - - FieldGeneratorMap(const FieldGeneratorMap&) = delete; - FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete; - - const FieldGenerator& get(const FieldDescriptor* field) const; - const FieldGenerator& get_extension(int index) const; - - // Assigns the has bits and returns the number of bits needed. - int CalculateHasBits(void); - - void SetOneofIndexBase(int index_base); - - // Check if any field of this message has a non zero default. - bool DoesAnyFieldHaveNonZeroDefault(void) const; - - private: - const Descriptor* descriptor_; - std::vector<std::unique_ptr<FieldGenerator>> field_generators_; - std::vector<std::unique_ptr<FieldGenerator>> extension_generators_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class FieldGenerator { + public: + static FieldGenerator* Make(const FieldDescriptor* field, + const Options& options); + + virtual ~FieldGenerator(); + + FieldGenerator(const FieldGenerator&) = delete; + FieldGenerator& operator=(const FieldGenerator&) = delete; + + // Exposed for subclasses to fill in. + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0; + virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0; + + // Called by GenerateFieldDescription, exposed for classes that need custom + // generation. + + // Exposed for subclasses to extend, base does nothing. + virtual void GenerateCFunctionDeclarations(io::Printer* printer) const; + virtual void GenerateCFunctionImplementations(io::Printer* printer) const; + + // Exposed for subclasses, should always call it on the parent class also. + virtual void DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const; + + // Used during generation, not intended to be extended by subclasses. + void GenerateFieldDescription( + io::Printer* printer, bool include_default) const; + void GenerateFieldNumberConstant(io::Printer* printer) const; + + // Exposed to get and set the has bits information. + virtual bool RuntimeUsesHasBit(void) const = 0; + void SetRuntimeHasBit(int has_index); + void SetNoHasBit(void); + virtual int ExtraRuntimeHasBitsNeeded(void) const; + virtual void SetExtraRuntimeHasBitsBase(int index_base); + void SetOneofIndexBase(int index_base); + + TProtoStringType variable(const char* key) const { + return variables_.find(key)->second; + } + + bool needs_textformat_name_support() const { + const TProtoStringType& field_flags = variable("fieldflags"); + return field_flags.find("GPBFieldTextFormatNameCustom") != + TProtoStringType::npos; + } + TProtoStringType generated_objc_name() const { return variable("name"); } + TProtoStringType raw_field_name() const { return variable("raw_field_name"); } + + protected: + FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + + virtual void FinishInitialization(void); + bool WantsHasProperty(void) const; + + const FieldDescriptor* descriptor_; + std::map<TProtoStringType, TProtoStringType> variables_; +}; + +class SingleFieldGenerator : public FieldGenerator { + public: + virtual ~SingleFieldGenerator(); + + SingleFieldGenerator(const SingleFieldGenerator&) = delete; + SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete; + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + virtual void GeneratePropertyImplementation(io::Printer* printer) const; + + virtual bool RuntimeUsesHasBit(void) const; + + protected: + SingleFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); +}; + +// Subclass with common support for when the field ends up as an ObjC Object. +class ObjCObjFieldGenerator : public SingleFieldGenerator { + public: + virtual ~ObjCObjFieldGenerator(); + + ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete; + ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete; + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + protected: + ObjCObjFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); +}; + +class RepeatedFieldGenerator : public ObjCObjFieldGenerator { + public: + virtual ~RepeatedFieldGenerator(); + + RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete; + RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete; + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + virtual void GeneratePropertyDeclaration(io::Printer* printer) const; + + virtual void GeneratePropertyImplementation(io::Printer* printer) const; + + virtual bool RuntimeUsesHasBit(void) const; + + protected: + RepeatedFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual void FinishInitialization(void); +}; + +// Convenience class which constructs FieldGenerators for a Descriptor. +class FieldGeneratorMap { + public: + FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + ~FieldGeneratorMap(); + + FieldGeneratorMap(const FieldGeneratorMap&) = delete; + FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete; + + const FieldGenerator& get(const FieldDescriptor* field) const; + const FieldGenerator& get_extension(int index) const; + + // Assigns the has bits and returns the number of bits needed. + int CalculateHasBits(void); + + void SetOneofIndexBase(int index_base); + + // Check if any field of this message has a non zero default. + bool DoesAnyFieldHaveNonZeroDefault(void) const; + + private: + const Descriptor* descriptor_; + std::vector<std::unique_ptr<FieldGenerator>> field_generators_; + std::vector<std::unique_ptr<FieldGenerator>> extension_generators_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__ 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 63b543bfb4..f399d6e4bc 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 @@ -1,610 +1,610 @@ -// 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/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_message.h> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/stubs/stl_util.h> -#include <google/protobuf/stubs/strutil.h> -#include <algorithm> // std::find() -#include <iostream> -#include <sstream> - -// 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 errors. - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -namespace { - -// This is also found in GPBBootstrap.h, and needs to be kept in sync. -const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004; - -const char* kHeaderExtension = ".pbobjc.h"; - -// Checks if a message contains any enums definitions (on the message or -// a nested message under it). -bool MessageContainsEnums(const Descriptor* message) { - if (message->enum_type_count() > 0) { - return true; - } - for (int i = 0; i < message->nested_type_count(); i++) { - if (MessageContainsEnums(message->nested_type(i))) { - return true; - } - } - return false; -} - -// Checks if a message contains any extension definitions (on the message or -// a nested message under it). -bool MessageContainsExtensions(const Descriptor* message) { - if (message->extension_count() > 0) { - return true; - } - for (int i = 0; i < message->nested_type_count(); i++) { - if (MessageContainsExtensions(message->nested_type(i))) { - return true; - } - } - return false; -} - -// Checks if the file contains any enum definitions (at the root or -// nested under a message). -bool FileContainsEnums(const FileDescriptor* file) { - if (file->enum_type_count() > 0) { - return true; - } - for (int i = 0; i < file->message_type_count(); i++) { - if (MessageContainsEnums(file->message_type(i))) { - return true; - } - } - return false; -} - -// Checks if the file contains any extensions definitions (at the root or -// nested under a message). -bool FileContainsExtensions(const FileDescriptor* file) { - if (file->extension_count() > 0) { - return true; - } - for (int i = 0; i < file->message_type_count(); i++) { - if (MessageContainsExtensions(file->message_type(i))) { - return true; - } - } - return false; -} - -// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all -// deps as visited and prunes them from the needed files list. -void PruneFileAndDepsMarkingAsVisited( - const FileDescriptor* file, - std::vector<const FileDescriptor*>* files, - std::set<const FileDescriptor*>* files_visited) { - std::vector<const FileDescriptor*>::iterator iter = - std::find(files->begin(), files->end(), file); - if (iter != files->end()) { - files->erase(iter); - } - files_visited->insert(file); - for (int i = 0; i < file->dependency_count(); i++) { - PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited); - } -} - -// Helper for CollectMinimalFileDepsContainingExtensions. -void CollectMinimalFileDepsContainingExtensionsWorker( - const FileDescriptor* file, - std::vector<const FileDescriptor*>* files, - std::set<const FileDescriptor*>* files_visited) { - if (files_visited->find(file) != files_visited->end()) { - return; - } - files_visited->insert(file); - - if (FileContainsExtensions(file)) { - files->push_back(file); - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - PruneFileAndDepsMarkingAsVisited(dep, files, files_visited); - } - } else { - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - CollectMinimalFileDepsContainingExtensionsWorker(dep, files, - files_visited); - } - } -} - -// Collect the deps of the given file that contain extensions. This can be used to -// create the chain of roots that need to be wired together. -// -// NOTE: If any changes are made to this and the supporting functions, you will -// need to manually validate what the generated code is for the test files: -// objectivec/Tests/unittest_extension_chain_*.proto -// There are comments about what the expected code should be line and limited -// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports -// specifically). -void CollectMinimalFileDepsContainingExtensions( - const FileDescriptor* file, - std::vector<const FileDescriptor*>* files) { - std::set<const FileDescriptor*> files_visited; - for (int i = 0; i < file->dependency_count(); i++) { - const FileDescriptor* dep = file->dependency(i); - CollectMinimalFileDepsContainingExtensionsWorker(dep, files, - &files_visited); - } -} - -bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { - for (int i = 0; i < file->dependency_count(); i++) { - if (dep == file->dependency(i)) { - return true; - } - } - return false; -} - -} // namespace - -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) - : file_(file), - root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { - 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_); - message_generators_.emplace_back(generator); - } - for (int i = 0; i < file_->extension_count(); i++) { - ExtensionGenerator* generator = - new ExtensionGenerator(root_class_name_, file_->extension(i)); - extension_generators_.emplace_back(generator); - } -} - -FileGenerator::~FileGenerator() {} - -void FileGenerator::GenerateHeader(io::Printer* printer) { - std::vector<TProtoStringType> headers; - // Generated files bundled with the library get minimal imports, everything - // else gets the wrapper so everything is usable. - if (is_bundled_proto_) { - headers.push_back("GPBDescriptor.h"); - headers.push_back("GPBMessage.h"); - headers.push_back("GPBRootObject.h"); - } else { - headers.push_back("GPBProtocolBuffers.h"); - } - PrintFileRuntimePreamble(printer, headers); - - // Add some verification that the generated code matches the source the - // code is being compiled with. - // NOTE: This captures the raw numeric values at the time the generator was - // compiled, since that will be the versions for the ObjC runtime at that - // time. The constants in the generated code will then get their values at - // at compile time (so checking against the headers being used to compile). - printer->Print( - "#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n" - "#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n" - "#endif\n" - "#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n" - "#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n" - "#endif\n" - "\n", - "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); - - // #import any headers for "public imports" in the proto file. - { - ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); - const TProtoStringType header_extension(kHeaderExtension); - for (int i = 0; i < file_->public_dependency_count(); i++) { - import_writer.AddFile(file_->public_dependency(i), header_extension); - } - import_writer.Print(printer); - } - - // Note: - // deprecated-declarations suppression is only needed if some place in this - // proto file is something deprecated or if it references something from - // another file that is deprecated. - printer->Print( - "// @@protoc_insertion_point(imports)\n" - "\n" - "#pragma clang diagnostic push\n" - "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n" - "\n" - "CF_EXTERN_C_BEGIN\n" - "\n"); - - std::set<TProtoStringType> fwd_decls; - for (const auto& generator : message_generators_) { - generator->DetermineForwardDeclarations(&fwd_decls); - } - for (std::set<TProtoStringType>::const_iterator i(fwd_decls.begin()); - i != fwd_decls.end(); ++i) { - printer->Print("$value$;\n", "value", *i); - } - if (fwd_decls.begin() != fwd_decls.end()) { - printer->Print("\n"); - } - - printer->Print( - "NS_ASSUME_NONNULL_BEGIN\n" - "\n"); - - // need to write out all enums first - for (const auto& generator : enum_generators_) { - generator->GenerateHeader(printer); - } - - for (const auto& generator : message_generators_) { - generator->GenerateEnumHeader(printer); - } - - // For extensions to chain together, the Root gets created even if there - // are no extensions. - printer->Print( - "#pragma mark - $root_class_name$\n" - "\n" - "/**\n" - " * Exposes the extension registry for this file.\n" - " *\n" - " * The base class provides:\n" - " * @code\n" - " * + (GPBExtensionRegistry *)extensionRegistry;\n" - " * @endcode\n" - " * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n" - " * this file and all files that it depends on.\n" - " **/\n" - "GPB_FINAL @interface $root_class_name$ : GPBRootObject\n" - "@end\n" - "\n", - "root_class_name", root_class_name_); - - if (!extension_generators_.empty()) { - // The dynamic methods block is only needed if there are extensions. - printer->Print( - "@interface $root_class_name$ (DynamicMethods)\n", - "root_class_name", root_class_name_); - - for (const auto& generator : extension_generators_) { - generator->GenerateMembersHeader(printer); - } - - printer->Print("@end\n\n"); - } // !extension_generators_.empty() - - for (const auto& generator : message_generators_) { - generator->GenerateMessageHeader(printer); - } - - printer->Print( - "NS_ASSUME_NONNULL_END\n" - "\n" - "CF_EXTERN_C_END\n" - "\n" - "#pragma clang diagnostic pop\n" - "\n" - "// @@protoc_insertion_point(global_scope)\n"); -} - -void FileGenerator::GenerateSource(io::Printer* printer) { - // #import the runtime support. - std::vector<TProtoStringType> headers; - headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); - PrintFileRuntimePreamble(printer, headers); - - // Enums use atomic in the generated code, so add the system import as needed. - if (FileContainsEnums(file_)) { - printer->Print( - "#import <stdatomic.h>\n" - "\n"); - } - - std::vector<const FileDescriptor*> deps_with_extensions; - CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); - - { - ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); - 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 any indirect dependency provided extensions, it needs to be directly - // imported so it can get merged into the root's extensions registry. - // See the Note by CollectMinimalFileDepsContainingExtensions before - // changing this. - for (std::vector<const FileDescriptor*>::iterator iter = - deps_with_extensions.begin(); - iter != deps_with_extensions.end(); ++iter) { - if (!IsDirectDependency(*iter, file_)) { - import_writer.AddFile(*iter, header_extension); - } - } - - import_writer.Print(printer); - } - - bool includes_oneof = false; - for (const auto& generator : message_generators_) { - if (generator->IncludesOneOfDefinition()) { - includes_oneof = true; - break; - } - } - - std::set<TProtoStringType> fwd_decls; - for (const auto& generator : message_generators_) { - generator->DetermineObjectiveCClassDefinitions(&fwd_decls); - } - for (const auto& generator : extension_generators_) { - generator->DetermineObjectiveCClassDefinitions(&fwd_decls); - } - - // Note: - // deprecated-declarations suppression is only needed if some place in this - // proto file is something deprecated or if it references something from - // another file that is deprecated. - // dollar-in-identifier-extension is needed because we use references to - // objc class names that have $ in identifiers. - printer->Print( - "// @@protoc_insertion_point(imports)\n" - "\n" - "#pragma clang diagnostic push\n" - "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"); - if (includes_oneof) { - // The generated code for oneof's uses direct ivar access, suppress the - // warning in case developer turn that on in the context they compile the - // generated code. - printer->Print( - "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n"); - } - if (!fwd_decls.empty()) { - printer->Print( - "#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n"); - } - printer->Print( - "\n"); - if (!fwd_decls.empty()) { - printer->Print( - "#pragma mark - Objective C Class declarations\n" - "// Forward declarations of Objective C classes that we can use as\n" - "// static values in struct initializers.\n" - "// We don't use [Foo class] because it is not a static value.\n"); - } - for (const auto& i : fwd_decls) { - printer->Print("$value$\n", "value", i); - } - if (!fwd_decls.empty()) { - printer->Print("\n"); - } - printer->Print( - "#pragma mark - $root_class_name$\n" - "\n" - "@implementation $root_class_name$\n\n", - "root_class_name", root_class_name_); - - const bool file_contains_extensions = FileContainsExtensions(file_); - - // If there were any extensions or this file has any dependencies, output - // a registry to override to create the file specific registry. - if (file_contains_extensions || !deps_with_extensions.empty()) { - printer->Print( - "+ (GPBExtensionRegistry*)extensionRegistry {\n" - " // This is called by +initialize so there is no need to worry\n" - " // about thread safety and initialization of registry.\n" - " static GPBExtensionRegistry* registry = nil;\n" - " if (!registry) {\n" - " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n" - " registry = [[GPBExtensionRegistry alloc] init];\n"); - - printer->Indent(); - printer->Indent(); - - if (file_contains_extensions) { - printer->Print( - "static GPBExtensionDescription descriptions[] = {\n"); - printer->Indent(); - for (const auto& generator : extension_generators_) { - generator->GenerateStaticVariablesInitialization(printer); - } - for (const auto& generator : message_generators_) { - generator->GenerateStaticVariablesInitialization(printer); - } - printer->Outdent(); - printer->Print( - "};\n" - "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n" - " GPBExtensionDescriptor *extension =\n" - " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]\n" - " usesClassRefs:YES];\n" - " [registry addExtension:extension];\n" - " [self globallyRegisterExtension:extension];\n" - " [extension release];\n" - "}\n"); - } - - if (deps_with_extensions.empty()) { - printer->Print( - "// None of the imports (direct or indirect) defined extensions, so no need to add\n" - "// them to this registry.\n"); - } else { - printer->Print( - "// Merge in the imports (direct or indirect) that defined extensions.\n"); - for (std::vector<const FileDescriptor*>::iterator iter = - deps_with_extensions.begin(); - iter != deps_with_extensions.end(); ++iter) { - const TProtoStringType root_class_name(FileClassName((*iter))); - printer->Print( - "[registry addExtensions:[$dependency$ extensionRegistry]];\n", - "dependency", root_class_name); - } - } - - printer->Outdent(); - printer->Outdent(); - - printer->Print( - " }\n" - " return registry;\n" - "}\n"); - } else { - if (file_->dependency_count() > 0) { - printer->Print( - "// No extensions in the file and none of the imports (direct or indirect)\n" - "// defined extensions, so no need to generate +extensionRegistry.\n"); - } else { - printer->Print( - "// No extensions in the file and no imports, so no need to generate\n" - "// +extensionRegistry.\n"); - } - } - - printer->Print("\n@end\n\n"); - - // File descriptor only needed if there are messages to use it. - if (!message_generators_.empty()) { - std::map<TProtoStringType, TProtoStringType> vars; - vars["root_class_name"] = root_class_name_; - vars["package"] = file_->package(); - vars["objc_prefix"] = FileClassPrefix(file_); - switch (file_->syntax()) { - case FileDescriptor::SYNTAX_UNKNOWN: - vars["syntax"] = "GPBFileSyntaxUnknown"; - break; - case FileDescriptor::SYNTAX_PROTO2: - vars["syntax"] = "GPBFileSyntaxProto2"; - break; - case FileDescriptor::SYNTAX_PROTO3: - vars["syntax"] = "GPBFileSyntaxProto3"; - break; - } - printer->Print(vars, - "#pragma mark - $root_class_name$_FileDescriptor\n" - "\n" - "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n" - " // This is called by +initialize so there is no need to worry\n" - " // about thread safety of the singleton.\n" - " static GPBFileDescriptor *descriptor = NULL;\n" - " if (!descriptor) {\n" - " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n"); - if (!vars["objc_prefix"].empty()) { - printer->Print( - vars, - " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n" - " objcPrefix:@\"$objc_prefix$\"\n" - " syntax:$syntax$];\n"); - } else { - printer->Print( - vars, - " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n" - " syntax:$syntax$];\n"); - } - printer->Print( - " }\n" - " return descriptor;\n" - "}\n" - "\n"); - } - - for (const auto& generator : enum_generators_) { - generator->GenerateSource(printer); - } - for (const auto& generator : message_generators_) { - generator->GenerateSource(printer); - } - - printer->Print( - "\n" - "#pragma clang diagnostic pop\n" - "\n" - "// @@protoc_insertion_point(global_scope)\n"); -} - -// Helper to print the import of the runtime support at the top of generated -// files. This currently only supports the runtime coming from a framework -// as defined by the official CocoaPod. -void FileGenerator::PrintFileRuntimePreamble( - io::Printer* printer, - const std::vector<TProtoStringType>& headers_to_import) const { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); - printer->Print("\n"); -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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/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_message.h> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/stubs/stl_util.h> +#include <google/protobuf/stubs/strutil.h> +#include <algorithm> // std::find() +#include <iostream> +#include <sstream> + +// 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 errors. + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +// This is also found in GPBBootstrap.h, and needs to be kept in sync. +const int32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004; + +const char* kHeaderExtension = ".pbobjc.h"; + +// Checks if a message contains any enums definitions (on the message or +// a nested message under it). +bool MessageContainsEnums(const Descriptor* message) { + if (message->enum_type_count() > 0) { + return true; + } + for (int i = 0; i < message->nested_type_count(); i++) { + if (MessageContainsEnums(message->nested_type(i))) { + return true; + } + } + return false; +} + +// Checks if a message contains any extension definitions (on the message or +// a nested message under it). +bool MessageContainsExtensions(const Descriptor* message) { + if (message->extension_count() > 0) { + return true; + } + for (int i = 0; i < message->nested_type_count(); i++) { + if (MessageContainsExtensions(message->nested_type(i))) { + return true; + } + } + return false; +} + +// Checks if the file contains any enum definitions (at the root or +// nested under a message). +bool FileContainsEnums(const FileDescriptor* file) { + if (file->enum_type_count() > 0) { + return true; + } + for (int i = 0; i < file->message_type_count(); i++) { + if (MessageContainsEnums(file->message_type(i))) { + return true; + } + } + return false; +} + +// Checks if the file contains any extensions definitions (at the root or +// nested under a message). +bool FileContainsExtensions(const FileDescriptor* file) { + if (file->extension_count() > 0) { + return true; + } + for (int i = 0; i < file->message_type_count(); i++) { + if (MessageContainsExtensions(file->message_type(i))) { + return true; + } + } + return false; +} + +// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all +// deps as visited and prunes them from the needed files list. +void PruneFileAndDepsMarkingAsVisited( + const FileDescriptor* file, + std::vector<const FileDescriptor*>* files, + std::set<const FileDescriptor*>* files_visited) { + std::vector<const FileDescriptor*>::iterator iter = + std::find(files->begin(), files->end(), file); + if (iter != files->end()) { + files->erase(iter); + } + files_visited->insert(file); + for (int i = 0; i < file->dependency_count(); i++) { + PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited); + } +} + +// Helper for CollectMinimalFileDepsContainingExtensions. +void CollectMinimalFileDepsContainingExtensionsWorker( + const FileDescriptor* file, + std::vector<const FileDescriptor*>* files, + std::set<const FileDescriptor*>* files_visited) { + if (files_visited->find(file) != files_visited->end()) { + return; + } + files_visited->insert(file); + + if (FileContainsExtensions(file)) { + files->push_back(file); + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dep = file->dependency(i); + PruneFileAndDepsMarkingAsVisited(dep, files, files_visited); + } + } else { + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dep = file->dependency(i); + CollectMinimalFileDepsContainingExtensionsWorker(dep, files, + files_visited); + } + } +} + +// Collect the deps of the given file that contain extensions. This can be used to +// create the chain of roots that need to be wired together. +// +// NOTE: If any changes are made to this and the supporting functions, you will +// need to manually validate what the generated code is for the test files: +// objectivec/Tests/unittest_extension_chain_*.proto +// There are comments about what the expected code should be line and limited +// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports +// specifically). +void CollectMinimalFileDepsContainingExtensions( + const FileDescriptor* file, + std::vector<const FileDescriptor*>* files) { + std::set<const FileDescriptor*> files_visited; + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dep = file->dependency(i); + CollectMinimalFileDepsContainingExtensionsWorker(dep, files, + &files_visited); + } +} + +bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { + for (int i = 0; i < file->dependency_count(); i++) { + if (dep == file->dependency(i)) { + return true; + } + } + return false; +} + +} // namespace + +FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) + : file_(file), + root_class_name_(FileClassName(file)), + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), + options_(options) { + 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_); + message_generators_.emplace_back(generator); + } + for (int i = 0; i < file_->extension_count(); i++) { + ExtensionGenerator* generator = + new ExtensionGenerator(root_class_name_, file_->extension(i)); + extension_generators_.emplace_back(generator); + } +} + +FileGenerator::~FileGenerator() {} + +void FileGenerator::GenerateHeader(io::Printer* printer) { + std::vector<TProtoStringType> headers; + // Generated files bundled with the library get minimal imports, everything + // else gets the wrapper so everything is usable. + if (is_bundled_proto_) { + headers.push_back("GPBDescriptor.h"); + headers.push_back("GPBMessage.h"); + headers.push_back("GPBRootObject.h"); + } else { + headers.push_back("GPBProtocolBuffers.h"); + } + PrintFileRuntimePreamble(printer, headers); + + // Add some verification that the generated code matches the source the + // code is being compiled with. + // NOTE: This captures the raw numeric values at the time the generator was + // compiled, since that will be the versions for the ObjC runtime at that + // time. The constants in the generated code will then get their values at + // at compile time (so checking against the headers being used to compile). + printer->Print( + "#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n" + "#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n" + "#endif\n" + "#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n" + "#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n" + "#endif\n" + "\n", + "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION)); + + // #import any headers for "public imports" in the proto file. + { + ImportWriter import_writer( + options_.generate_for_named_framework, + options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, + is_bundled_proto_); + const TProtoStringType header_extension(kHeaderExtension); + for (int i = 0; i < file_->public_dependency_count(); i++) { + import_writer.AddFile(file_->public_dependency(i), header_extension); + } + import_writer.Print(printer); + } + + // Note: + // deprecated-declarations suppression is only needed if some place in this + // proto file is something deprecated or if it references something from + // another file that is deprecated. + printer->Print( + "// @@protoc_insertion_point(imports)\n" + "\n" + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n" + "\n" + "CF_EXTERN_C_BEGIN\n" + "\n"); + + std::set<TProtoStringType> fwd_decls; + for (const auto& generator : message_generators_) { + generator->DetermineForwardDeclarations(&fwd_decls); + } + for (std::set<TProtoStringType>::const_iterator i(fwd_decls.begin()); + i != fwd_decls.end(); ++i) { + printer->Print("$value$;\n", "value", *i); + } + if (fwd_decls.begin() != fwd_decls.end()) { + printer->Print("\n"); + } + + printer->Print( + "NS_ASSUME_NONNULL_BEGIN\n" + "\n"); + + // need to write out all enums first + for (const auto& generator : enum_generators_) { + generator->GenerateHeader(printer); + } + + for (const auto& generator : message_generators_) { + generator->GenerateEnumHeader(printer); + } + + // For extensions to chain together, the Root gets created even if there + // are no extensions. + printer->Print( + "#pragma mark - $root_class_name$\n" + "\n" + "/**\n" + " * Exposes the extension registry for this file.\n" + " *\n" + " * The base class provides:\n" + " * @code\n" + " * + (GPBExtensionRegistry *)extensionRegistry;\n" + " * @endcode\n" + " * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n" + " * this file and all files that it depends on.\n" + " **/\n" + "GPB_FINAL @interface $root_class_name$ : GPBRootObject\n" + "@end\n" + "\n", + "root_class_name", root_class_name_); + + if (!extension_generators_.empty()) { + // The dynamic methods block is only needed if there are extensions. + printer->Print( + "@interface $root_class_name$ (DynamicMethods)\n", + "root_class_name", root_class_name_); + + for (const auto& generator : extension_generators_) { + generator->GenerateMembersHeader(printer); + } + + printer->Print("@end\n\n"); + } // !extension_generators_.empty() + + for (const auto& generator : message_generators_) { + generator->GenerateMessageHeader(printer); + } + + printer->Print( + "NS_ASSUME_NONNULL_END\n" + "\n" + "CF_EXTERN_C_END\n" + "\n" + "#pragma clang diagnostic pop\n" + "\n" + "// @@protoc_insertion_point(global_scope)\n"); +} + +void FileGenerator::GenerateSource(io::Printer* printer) { + // #import the runtime support. + std::vector<TProtoStringType> headers; + headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + PrintFileRuntimePreamble(printer, headers); + + // Enums use atomic in the generated code, so add the system import as needed. + if (FileContainsEnums(file_)) { + printer->Print( + "#import <stdatomic.h>\n" + "\n"); + } + + std::vector<const FileDescriptor*> deps_with_extensions; + CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions); + + { + ImportWriter import_writer( + options_.generate_for_named_framework, + options_.named_framework_to_proto_path_mappings_path, + options_.runtime_import_prefix, + is_bundled_proto_); + 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 any indirect dependency provided extensions, it needs to be directly + // imported so it can get merged into the root's extensions registry. + // See the Note by CollectMinimalFileDepsContainingExtensions before + // changing this. + for (std::vector<const FileDescriptor*>::iterator iter = + deps_with_extensions.begin(); + iter != deps_with_extensions.end(); ++iter) { + if (!IsDirectDependency(*iter, file_)) { + import_writer.AddFile(*iter, header_extension); + } + } + + import_writer.Print(printer); + } + + bool includes_oneof = false; + for (const auto& generator : message_generators_) { + if (generator->IncludesOneOfDefinition()) { + includes_oneof = true; + break; + } + } + + std::set<TProtoStringType> fwd_decls; + for (const auto& generator : message_generators_) { + generator->DetermineObjectiveCClassDefinitions(&fwd_decls); + } + for (const auto& generator : extension_generators_) { + generator->DetermineObjectiveCClassDefinitions(&fwd_decls); + } + + // Note: + // deprecated-declarations suppression is only needed if some place in this + // proto file is something deprecated or if it references something from + // another file that is deprecated. + // dollar-in-identifier-extension is needed because we use references to + // objc class names that have $ in identifiers. + printer->Print( + "// @@protoc_insertion_point(imports)\n" + "\n" + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"); + if (includes_oneof) { + // The generated code for oneof's uses direct ivar access, suppress the + // warning in case developer turn that on in the context they compile the + // generated code. + printer->Print( + "#pragma clang diagnostic ignored \"-Wdirect-ivar-access\"\n"); + } + if (!fwd_decls.empty()) { + printer->Print( + "#pragma clang diagnostic ignored \"-Wdollar-in-identifier-extension\"\n"); + } + printer->Print( + "\n"); + if (!fwd_decls.empty()) { + printer->Print( + "#pragma mark - Objective C Class declarations\n" + "// Forward declarations of Objective C classes that we can use as\n" + "// static values in struct initializers.\n" + "// We don't use [Foo class] because it is not a static value.\n"); + } + for (const auto& i : fwd_decls) { + printer->Print("$value$\n", "value", i); + } + if (!fwd_decls.empty()) { + printer->Print("\n"); + } + printer->Print( + "#pragma mark - $root_class_name$\n" + "\n" + "@implementation $root_class_name$\n\n", + "root_class_name", root_class_name_); + + const bool file_contains_extensions = FileContainsExtensions(file_); + + // If there were any extensions or this file has any dependencies, output + // a registry to override to create the file specific registry. + if (file_contains_extensions || !deps_with_extensions.empty()) { + printer->Print( + "+ (GPBExtensionRegistry*)extensionRegistry {\n" + " // This is called by +initialize so there is no need to worry\n" + " // about thread safety and initialization of registry.\n" + " static GPBExtensionRegistry* registry = nil;\n" + " if (!registry) {\n" + " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n" + " registry = [[GPBExtensionRegistry alloc] init];\n"); + + printer->Indent(); + printer->Indent(); + + if (file_contains_extensions) { + printer->Print( + "static GPBExtensionDescription descriptions[] = {\n"); + printer->Indent(); + for (const auto& generator : extension_generators_) { + generator->GenerateStaticVariablesInitialization(printer); + } + for (const auto& generator : message_generators_) { + generator->GenerateStaticVariablesInitialization(printer); + } + printer->Outdent(); + printer->Print( + "};\n" + "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n" + " GPBExtensionDescriptor *extension =\n" + " [[GPBExtensionDescriptor alloc] initWithExtensionDescription:&descriptions[i]\n" + " usesClassRefs:YES];\n" + " [registry addExtension:extension];\n" + " [self globallyRegisterExtension:extension];\n" + " [extension release];\n" + "}\n"); + } + + if (deps_with_extensions.empty()) { + printer->Print( + "// None of the imports (direct or indirect) defined extensions, so no need to add\n" + "// them to this registry.\n"); + } else { + printer->Print( + "// Merge in the imports (direct or indirect) that defined extensions.\n"); + for (std::vector<const FileDescriptor*>::iterator iter = + deps_with_extensions.begin(); + iter != deps_with_extensions.end(); ++iter) { + const TProtoStringType root_class_name(FileClassName((*iter))); + printer->Print( + "[registry addExtensions:[$dependency$ extensionRegistry]];\n", + "dependency", root_class_name); + } + } + + printer->Outdent(); + printer->Outdent(); + + printer->Print( + " }\n" + " return registry;\n" + "}\n"); + } else { + if (file_->dependency_count() > 0) { + printer->Print( + "// No extensions in the file and none of the imports (direct or indirect)\n" + "// defined extensions, so no need to generate +extensionRegistry.\n"); + } else { + printer->Print( + "// No extensions in the file and no imports, so no need to generate\n" + "// +extensionRegistry.\n"); + } + } + + printer->Print("\n@end\n\n"); + + // File descriptor only needed if there are messages to use it. + if (!message_generators_.empty()) { + std::map<TProtoStringType, TProtoStringType> vars; + vars["root_class_name"] = root_class_name_; + vars["package"] = file_->package(); + vars["objc_prefix"] = FileClassPrefix(file_); + switch (file_->syntax()) { + case FileDescriptor::SYNTAX_UNKNOWN: + vars["syntax"] = "GPBFileSyntaxUnknown"; + break; + case FileDescriptor::SYNTAX_PROTO2: + vars["syntax"] = "GPBFileSyntaxProto2"; + break; + case FileDescriptor::SYNTAX_PROTO3: + vars["syntax"] = "GPBFileSyntaxProto3"; + break; + } + printer->Print(vars, + "#pragma mark - $root_class_name$_FileDescriptor\n" + "\n" + "static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n" + " // This is called by +initialize so there is no need to worry\n" + " // about thread safety of the singleton.\n" + " static GPBFileDescriptor *descriptor = NULL;\n" + " if (!descriptor) {\n" + " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n"); + if (!vars["objc_prefix"].empty()) { + printer->Print( + vars, + " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n" + " objcPrefix:@\"$objc_prefix$\"\n" + " syntax:$syntax$];\n"); + } else { + printer->Print( + vars, + " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n" + " syntax:$syntax$];\n"); + } + printer->Print( + " }\n" + " return descriptor;\n" + "}\n" + "\n"); + } + + for (const auto& generator : enum_generators_) { + generator->GenerateSource(printer); + } + for (const auto& generator : message_generators_) { + generator->GenerateSource(printer); + } + + printer->Print( + "\n" + "#pragma clang diagnostic pop\n" + "\n" + "// @@protoc_insertion_point(global_scope)\n"); +} + +// Helper to print the import of the runtime support at the top of generated +// files. This currently only supports the runtime coming from a framework +// as defined by the official CocoaPod. +void FileGenerator::PrintFileRuntimePreamble( + io::Printer* printer, + const std::vector<TProtoStringType>& headers_to_import) const { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, options_.runtime_import_prefix, true); + printer->Print("\n"); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 c1f6cb19de..5635cff252 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 @@ -1,84 +1,84 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ - -#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> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class EnumGenerator; -class ExtensionGenerator; -class MessageGenerator; - -class FileGenerator { - public: - FileGenerator(const FileDescriptor* file, const Options& options); - ~FileGenerator(); - - FileGenerator(const FileGenerator&) = delete; - FileGenerator& operator=(const FileGenerator&) = delete; - - void GenerateSource(io::Printer* printer); - void GenerateHeader(io::Printer* printer); - - const TProtoStringType& RootClassName() const { return root_class_name_; } - - private: - const FileDescriptor* file_; - TProtoStringType root_class_name_; - bool is_bundled_proto_; - - std::vector<std::unique_ptr<EnumGenerator>> enum_generators_; - 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; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ + +#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> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class EnumGenerator; +class ExtensionGenerator; +class MessageGenerator; + +class FileGenerator { + public: + FileGenerator(const FileDescriptor* file, const Options& options); + ~FileGenerator(); + + FileGenerator(const FileGenerator&) = delete; + FileGenerator& operator=(const FileGenerator&) = delete; + + void GenerateSource(io::Printer* printer); + void GenerateHeader(io::Printer* printer); + + const TProtoStringType& RootClassName() const { return root_class_name_; } + + private: + const FileDescriptor* file_; + TProtoStringType root_class_name_; + bool is_bundled_proto_; + + std::vector<std::unique_ptr<EnumGenerator>> enum_generators_; + 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; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__ 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 2157896253..c19df01c69 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 @@ -1,183 +1,183 @@ -// 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 <iostream> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_generator.h> -#include <google/protobuf/compiler/objectivec/objectivec_file.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -ObjectiveCGenerator::ObjectiveCGenerator() {} - -ObjectiveCGenerator::~ObjectiveCGenerator() {} - -bool ObjectiveCGenerator::HasGenerateAll() const { - return true; -} - -bool ObjectiveCGenerator::Generate(const FileDescriptor* file, - const TProtoStringType& parameter, - GeneratorContext* context, - TProtoStringType* error) const { - *error = "Unimplemented Generate() method. Call GenerateAll() instead."; - return false; -} - -bool ObjectiveCGenerator::GenerateAll( - const std::vector<const FileDescriptor*>& files, - const TProtoStringType& parameter, GeneratorContext* context, - TProtoStringType* error) const { - // ----------------------------------------------------------------- - // Parse generator options. These options are passed to the compiler using the - // --objc_opt flag. The options are passed as a comma separated list of - // options along with their values. If the option appears multiple times, only - // the last value will be considered. - // - // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - - Options generation_options; - - std::vector<std::pair<TProtoStringType, TProtoStringType> > options; - ParseGeneratorParameter(parameter, &options); - for (int i = 0; i < options.size(); i++) { - if (options[i].first == "expected_prefixes_path") { - // Path to find a file containing the expected prefixes - // (objc_class_prefix "PREFIX") for proto packages (package NAME). The - // generator will then issue warnings/errors if in the proto files being - // generated the option is not listed/wrong/etc in the file. - // - // 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") - // - // 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; - } 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( - TProtoStringType(split_piece)); - } - } else if (options[i].first == "generate_for_named_framework") { - // The name of the framework that protos are being generated for. This - // will cause the #import statements to be framework based using this - // name (i.e. - "#import <NAME/proto.pbobjc.h>). - // - // NOTE: If this option is used with - // named_framework_to_proto_path_mappings_path, then this is effectively - // the "default" framework name used for everything that wasn't mapped by - // the mapping file. - generation_options.generate_for_named_framework = options[i].second; - } else if (options[i].first == "named_framework_to_proto_path_mappings_path") { - // Path to find a file containing the list of framework names and proto - // files. The generator uses this to decide if a proto file - // referenced should use a framework style import vs. a user level import - // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h"). - // - // The format of the file is: - // - An entry is a line of "frameworkName: file.proto, dir/file2.proto". - // - Comments start with "#". - // - A comment can go on a line after a expected package/prefix pair. - // (i.e. - "frameworkName: file.proto # comment") - // - // Any number of files can be listed for a framework, just separate them - // with commas. - // - // There can be multiple lines listing the same frameworkName in case it - // has a lot of proto files included in it; having multiple lines makes - // things easier to read. If a proto file is not configured in the - // mappings file, it will use the default framework name if one was passed - // with generate_for_named_framework, or the relative path to it's include - // path otherwise. - generation_options.named_framework_to_proto_path_mappings_path = options[i].second; - } else if (options[i].first == "runtime_import_prefix") { - // Path to use as a prefix on #imports of runtime provided headers in the - // 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, "/"); - } else { - *error = "error: Unknown generator option: " + options[i].first; - return false; - } - } - - // ----------------------------------------------------------------- - - // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { - // *error will have been filled in. - return false; - } - - for (int i = 0; i < files.size(); i++) { - const FileDescriptor* file = files[i]; - FileGenerator file_generator(file, generation_options); - TProtoStringType filepath = FilePath(file); - - // Generate header. - { - std::unique_ptr<io::ZeroCopyOutputStream> output( - context->Open(filepath + ".pbobjc.h")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateHeader(&printer); - } - - // Generate m file. - { - std::unique_ptr<io::ZeroCopyOutputStream> output( - context->Open(filepath + ".pbobjc.m")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateSource(&printer); - } - } - - return true; -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <iostream> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_generator.h> +#include <google/protobuf/compiler/objectivec/objectivec_file.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +ObjectiveCGenerator::ObjectiveCGenerator() {} + +ObjectiveCGenerator::~ObjectiveCGenerator() {} + +bool ObjectiveCGenerator::HasGenerateAll() const { + return true; +} + +bool ObjectiveCGenerator::Generate(const FileDescriptor* file, + const TProtoStringType& parameter, + GeneratorContext* context, + TProtoStringType* error) const { + *error = "Unimplemented Generate() method. Call GenerateAll() instead."; + return false; +} + +bool ObjectiveCGenerator::GenerateAll( + const std::vector<const FileDescriptor*>& files, + const TProtoStringType& parameter, GeneratorContext* context, + TProtoStringType* error) const { + // ----------------------------------------------------------------- + // Parse generator options. These options are passed to the compiler using the + // --objc_opt flag. The options are passed as a comma separated list of + // options along with their values. If the option appears multiple times, only + // the last value will be considered. + // + // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework + + Options generation_options; + + std::vector<std::pair<TProtoStringType, TProtoStringType> > options; + ParseGeneratorParameter(parameter, &options); + for (int i = 0; i < options.size(); i++) { + if (options[i].first == "expected_prefixes_path") { + // Path to find a file containing the expected prefixes + // (objc_class_prefix "PREFIX") for proto packages (package NAME). The + // generator will then issue warnings/errors if in the proto files being + // generated the option is not listed/wrong/etc in the file. + // + // 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") + // + // 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; + } 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( + TProtoStringType(split_piece)); + } + } else if (options[i].first == "generate_for_named_framework") { + // The name of the framework that protos are being generated for. This + // will cause the #import statements to be framework based using this + // name (i.e. - "#import <NAME/proto.pbobjc.h>). + // + // NOTE: If this option is used with + // named_framework_to_proto_path_mappings_path, then this is effectively + // the "default" framework name used for everything that wasn't mapped by + // the mapping file. + generation_options.generate_for_named_framework = options[i].second; + } else if (options[i].first == "named_framework_to_proto_path_mappings_path") { + // Path to find a file containing the list of framework names and proto + // files. The generator uses this to decide if a proto file + // referenced should use a framework style import vs. a user level import + // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h"). + // + // The format of the file is: + // - An entry is a line of "frameworkName: file.proto, dir/file2.proto". + // - Comments start with "#". + // - A comment can go on a line after a expected package/prefix pair. + // (i.e. - "frameworkName: file.proto # comment") + // + // Any number of files can be listed for a framework, just separate them + // with commas. + // + // There can be multiple lines listing the same frameworkName in case it + // has a lot of proto files included in it; having multiple lines makes + // things easier to read. If a proto file is not configured in the + // mappings file, it will use the default framework name if one was passed + // with generate_for_named_framework, or the relative path to it's include + // path otherwise. + generation_options.named_framework_to_proto_path_mappings_path = options[i].second; + } else if (options[i].first == "runtime_import_prefix") { + // Path to use as a prefix on #imports of runtime provided headers in the + // 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, "/"); + } else { + *error = "error: Unknown generator option: " + options[i].first; + return false; + } + } + + // ----------------------------------------------------------------- + + // Validate the objc prefix/package pairings. + if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + // *error will have been filled in. + return false; + } + + for (int i = 0; i < files.size(); i++) { + const FileDescriptor* file = files[i]; + FileGenerator file_generator(file, generation_options); + TProtoStringType filepath = FilePath(file); + + // Generate header. + { + std::unique_ptr<io::ZeroCopyOutputStream> output( + context->Open(filepath + ".pbobjc.h")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateHeader(&printer); + } + + // Generate m file. + { + std::unique_ptr<io::ZeroCopyOutputStream> output( + context->Open(filepath + ".pbobjc.m")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateSource(&printer); + } + } + + return true; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h index cdaac67c3b..c68536be1b 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -1,79 +1,79 @@ -// 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. - -// Generates ObjectiveC code for a given .proto file. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ - -#include <string> -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/descriptor.h> - -#include <google/protobuf/port_def.inc> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -// CodeGenerator implementation which generates a ObjectiveC source file and -// header. If you create your own protocol compiler binary and you want it to -// support ObjectiveC output, you can do so by registering an instance of this -// CodeGenerator with the CommandLineInterface in your main() function. -class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { - public: - ObjectiveCGenerator(); - ~ObjectiveCGenerator(); - - ObjectiveCGenerator(const ObjectiveCGenerator&) = delete; - ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete; - - // implements CodeGenerator ---------------------------------------- - bool HasGenerateAll() const override; - bool Generate(const FileDescriptor* file, const TProtoStringType& parameter, - GeneratorContext* context, TProtoStringType* error) const override; - bool GenerateAll(const std::vector<const FileDescriptor*>& files, - const TProtoStringType& parameter, GeneratorContext* context, - TProtoStringType* error) const override; - - uint64_t GetSupportedFeatures() const override { - return FEATURE_PROTO3_OPTIONAL; - } -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include <google/protobuf/port_undef.inc> - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ +// 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. + +// Generates ObjectiveC code for a given .proto file. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ + +#include <string> +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/descriptor.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// CodeGenerator implementation which generates a ObjectiveC source file and +// header. If you create your own protocol compiler binary and you want it to +// support ObjectiveC output, you can do so by registering an instance of this +// CodeGenerator with the CommandLineInterface in your main() function. +class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { + public: + ObjectiveCGenerator(); + ~ObjectiveCGenerator(); + + ObjectiveCGenerator(const ObjectiveCGenerator&) = delete; + ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete; + + // implements CodeGenerator ---------------------------------------- + bool HasGenerateAll() const override; + bool Generate(const FileDescriptor* file, const TProtoStringType& parameter, + GeneratorContext* context, TProtoStringType* error) const override; + bool GenerateAll(const std::vector<const FileDescriptor*>& files, + const TProtoStringType& parameter, GeneratorContext* context, + TProtoStringType* error) const override; + + uint64_t GetSupportedFeatures() const override { + return FEATURE_PROTO3_OPTIONAL; + } +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__ 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 dbcc4ce110..905947807a 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 @@ -1,1777 +1,1777 @@ -// 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. - -#ifndef _MSC_VER -#include <unistd.h> -#endif -#include <climits> -#include <errno.h> -#include <fcntl.h> -#include <fstream> -#include <iostream> -#include <sstream> -#include <stdlib.h> -#include <unordered_set> -#include <vector> - -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/io/io_win32.h> -#include <google/protobuf/port.h> -#include <google/protobuf/stubs/common.h> -#include <google/protobuf/stubs/port.h> -#include <google/protobuf/stubs/strutil.h> - -// 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 errors. - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -// <io.h> is transitively included in this file. Import the functions explicitly -// in this port namespace to avoid ambiguous definition. -namespace posix { -#ifdef _WIN32 -using ::google::protobuf::io::win32::open; -#else -using ::open; -#endif -} // namespace port - -Options::Options() { - // Default is the value of the env for the package prefixes. - const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); - if (file_path) { - expected_prefixes_path = file_path; - } - const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS"); - if (suppressions) { - expected_prefixes_suppressions = - Split(suppressions, ";", true); - } -} - -namespace { - -std::unordered_set<TProtoStringType> MakeWordsMap(const char* const words[], - size_t num_words) { - std::unordered_set<TProtoStringType> result; - for (int i = 0; i < num_words; i++) { - result.insert(words[i]); - } - return result; -} - -const char* const kUpperSegmentsList[] = {"url", "http", "https"}; - -std::unordered_set<TProtoStringType> kUpperSegments = - MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList)); - -bool ascii_isnewline(char c) { - return c == '\n' || c == '\r'; -} - -// Internal helper for name handing. -// Do not expose this outside of helpers, stick to having functions for specific -// cases (ClassName(), FieldName()), so there is always consistent suffix rules. -TProtoStringType UnderscoresToCamelCase(const TProtoStringType& input, - bool first_capitalized) { - std::vector<TProtoStringType> values; - TProtoStringType current; - - bool last_char_was_number = false; - bool last_char_was_lower = false; - bool last_char_was_upper = false; - for (int i = 0; i < input.size(); i++) { - char c = input[i]; - if (ascii_isdigit(c)) { - if (!last_char_was_number) { - values.push_back(current); - current = ""; - } - current += c; - last_char_was_number = last_char_was_lower = last_char_was_upper = false; - last_char_was_number = true; - } else if (ascii_islower(c)) { - // lowercase letter can follow a lowercase or uppercase letter - if (!last_char_was_lower && !last_char_was_upper) { - values.push_back(current); - current = ""; - } - current += c; // already lower - last_char_was_number = last_char_was_lower = last_char_was_upper = false; - last_char_was_lower = true; - } else if (ascii_isupper(c)) { - if (!last_char_was_upper) { - values.push_back(current); - current = ""; - } - current += ascii_tolower(c); - last_char_was_number = last_char_was_lower = last_char_was_upper = false; - last_char_was_upper = true; - } else { - last_char_was_number = last_char_was_lower = last_char_was_upper = false; - } - } - values.push_back(current); - - TProtoStringType result; - bool first_segment_forces_upper = false; - for (std::vector<TProtoStringType>::iterator i = values.begin(); i != values.end(); - ++i) { - TProtoStringType value = *i; - bool all_upper = (kUpperSegments.count(value) > 0); - if (all_upper && (result.length() == 0)) { - first_segment_forces_upper = true; - } - for (int j = 0; j < value.length(); j++) { - if (j == 0 || all_upper) { - value[j] = ascii_toupper(value[j]); - } else { - // Nothing, already in lower. - } - } - result += value; - } - if ((result.length() != 0) && - !first_capitalized && - !first_segment_forces_upper) { - result[0] = ascii_tolower(result[0]); - } - return result; -} - -const char* const kReservedWordList[] = { - // Note NSObject Methods: - // These are brought in from objectivec_nsobject_methods.h that is generated - // using method_dump.sh. See kNSObjectMethods below. - - // Objective C "keywords" that aren't in C - // From - // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c - // with some others added on. - "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway", - "self", "instancetype", "nullable", "nonnull", "nil", "Nil", - "YES", "NO", "weak", - - // C/C++ keywords (Incl C++ 0x11) - // From http://en.cppreference.com/w/cpp/keywords - "and", "and_eq", "alignas", "alignof", "asm", "auto", "bitand", "bitor", - "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class", - "compl", "const", "constexpr", "const_cast", "continue", "decltype", - "default", "delete", "double", "dynamic_cast", "else", "enum", "explicit", - "export", "extern ", "false", "float", "for", "friend", "goto", "if", - "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", - "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", - "public", "register", "reinterpret_cast", "return", "short", "signed", - "sizeof", "static", "static_assert", "static_cast", "struct", "switch", - "template", "this", "thread_local", "throw", "true", "try", "typedef", - "typeid", "typename", "union", "unsigned", "using", "virtual", "void", - "volatile", "wchar_t", "while", "xor", "xor_eq", - - // C99 keywords - // From - // http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fkeyw.htm - "restrict", - - // GCC/Clang extension - "typeof", - - // Not a keyword, but will break you - "NULL", - - // C88+ specs call for these to be macros, so depending on what they are - // defined to be it can lead to odd errors for some Xcode/SDK versions. - "stdin", "stdout", "stderr", - - // Objective-C Runtime typedefs - // From <obc/runtime.h> - "Category", "Ivar", "Method", "Protocol", - - // GPBMessage Methods - // Only need to add instance methods that may conflict with - // method declared in protos. The main cases are methods - // that take no arguments, or setFoo:/hasFoo: type methods. - "clear", "data", "delimitedData", "descriptor", "extensionRegistry", - "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize", - "sortedExtensionsInUse", "unknownFields", - - // MacTypes.h names - "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount", - "ByteOffset", "Duration", "AbsoluteTime", "OptionBits", "ItemCount", - "PBVersion", "ScriptCode", "LangCode", "RegionCode", "OSType", - "ProcessSerialNumber", "Point", "Rect", "FixedPoint", "FixedRect", "Style", - "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord", -}; - -// returns true is input starts with __ or _[A-Z] which are reserved identifiers -// in C/ C++. All calls should go through UnderscoresToCamelCase before getting here -// but this verifies and allows for future expansion if we decide to redefine what a -// reserved C identifier is (for example the GNU list -// https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html ) -bool IsReservedCIdentifier(const TProtoStringType& input) { - if (input.length() > 2) { - if (input.at(0) == '_') { - if (isupper(input.at(1)) || input.at(1) == '_') { - return true; - } - } - } - return false; -} - -TProtoStringType SanitizeNameForObjC(const TProtoStringType& prefix, - 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 = - MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList)); - TProtoStringType sanitized; - // We add the prefix in the cases where the string is missing a prefix. - // We define "missing a prefix" as where 'input': - // a) Doesn't start with the prefix or - // b) Isn't equivalent to the prefix or - // c) Has the prefix, but the letter after the prefix is lowercase - if (HasPrefixString(input, prefix)) { - if (input.length() == prefix.length() || !ascii_isupper(input[prefix.length()])) { - sanitized = prefix + input; - } else { - sanitized = input; - } - } else { - sanitized = prefix + input; - } - if (IsReservedCIdentifier(sanitized) || - (kReservedWords.count(sanitized) > 0) || - (kNSObjectMethods.count(sanitized) > 0)) { - if (out_suffix_added) *out_suffix_added = extension; - return sanitized + extension; - } - if (out_suffix_added) out_suffix_added->clear(); - return sanitized; -} - -TProtoStringType NameFromFieldDescriptor(const FieldDescriptor* field) { - if (field->type() == FieldDescriptor::TYPE_GROUP) { - return field->message_type()->name(); - } else { - return field->name(); - } -} - -void PathSplit(const TProtoStringType& path, TProtoStringType* directory, - TProtoStringType* basename) { - TProtoStringType::size_type last_slash = path.rfind('/'); - if (last_slash == TProtoStringType::npos) { - if (directory) { - *directory = ""; - } - if (basename) { - *basename = path; - } - } else { - if (directory) { - *directory = path.substr(0, last_slash); - } - if (basename) { - *basename = path.substr(last_slash + 1); - } - } -} - -bool IsSpecialName(const TProtoStringType& name, const TProtoStringType* special_names, - size_t count) { - for (size_t i = 0; i < count; ++i) { - size_t length = special_names[i].length(); - if (name.compare(0, length, special_names[i]) == 0) { - if (name.length() > length) { - // If name is longer than the retained_name[i] that it matches - // the next character must be not lower case (newton vs newTon vs - // new_ton). - return !ascii_islower(name[length]); - } else { - return true; - } - } - } - return false; -} - -TProtoStringType GetZeroEnumNameForFlagType(const FlagType flag_type) { - switch(flag_type) { - case FLAGTYPE_DESCRIPTOR_INITIALIZATION: - return "GPBDescriptorInitializationFlag_None"; - case FLAGTYPE_EXTENSION: - return "GPBExtensionNone"; - case FLAGTYPE_FIELD: - return "GPBFieldNone"; - default: - GOOGLE_LOG(FATAL) << "Can't get here."; - return "0"; - } -} - -TProtoStringType GetEnumNameForFlagType(const FlagType flag_type) { - switch(flag_type) { - case FLAGTYPE_DESCRIPTOR_INITIALIZATION: - return "GPBDescriptorInitializationFlags"; - case FLAGTYPE_EXTENSION: - return "GPBExtensionOptions"; - case FLAGTYPE_FIELD: - return "GPBFieldFlags"; - default: - GOOGLE_LOG(FATAL) << "Can't get here."; - return TProtoStringType(); - } -} - -} // namespace - -// Escape C++ trigraphs by escaping question marks to \? -TProtoStringType EscapeTrigraphs(const TProtoStringType& to_escape) { - return StringReplace(to_escape, "?", "\\?", true); -} - -void TrimWhitespace(StringPiece* input) { - while (!input->empty() && ascii_isspace(*input->data())) { - input->remove_prefix(1); - } - while (!input->empty() && ascii_isspace((*input)[input->length() - 1])) { - input->remove_suffix(1); - } -} - -bool IsRetainedName(const TProtoStringType& name) { - // List of prefixes from - // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html - static const TProtoStringType retained_names[] = {"new", "alloc", "copy", - "mutableCopy"}; - return IsSpecialName(name, retained_names, - sizeof(retained_names) / sizeof(retained_names[0])); -} - -bool IsInitName(const TProtoStringType& name) { - static const TProtoStringType init_names[] = {"init"}; - return IsSpecialName(name, init_names, - sizeof(init_names) / sizeof(init_names[0])); -} - -TProtoStringType BaseFileName(const FileDescriptor* file) { - TProtoStringType basename; - PathSplit(file->name(), NULL, &basename); - return basename; -} - -TProtoStringType FileClassPrefix(const FileDescriptor* file) { - // Default is empty string, no need to check has_objc_class_prefix. - TProtoStringType result = file->options().objc_class_prefix(); - return result; -} - -TProtoStringType FilePath(const FileDescriptor* file) { - TProtoStringType output; - TProtoStringType basename; - TProtoStringType directory; - PathSplit(file->name(), &directory, &basename); - if (directory.length() > 0) { - output = directory + "/"; - } - basename = StripProto(basename); - - // CamelCase to be more ObjC friendly. - basename = UnderscoresToCamelCase(basename, true); - - output += basename; - return output; -} - -TProtoStringType FilePathBasename(const FileDescriptor* file) { - TProtoStringType output; - TProtoStringType basename; - TProtoStringType directory; - PathSplit(file->name(), &directory, &basename); - basename = StripProto(basename); - - // CamelCase to be more ObjC friendly. - output = UnderscoresToCamelCase(basename, true); - - return output; -} - -TProtoStringType FileClassName(const FileDescriptor* file) { - const TProtoStringType prefix = FileClassPrefix(file); - const TProtoStringType name = - UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; - // There aren't really any reserved words that end in "Root", but playing - // it safe and checking. - return SanitizeNameForObjC(prefix, name, "_RootClass", NULL); -} - -TProtoStringType ClassNameWorker(const Descriptor* descriptor) { - TProtoStringType name; - if (descriptor->containing_type() != NULL) { - name = ClassNameWorker(descriptor->containing_type()); - name += "_"; - } - return name + descriptor->name(); -} - -TProtoStringType ClassNameWorker(const EnumDescriptor* descriptor) { - TProtoStringType name; - if (descriptor->containing_type() != NULL) { - name = ClassNameWorker(descriptor->containing_type()); - name += "_"; - } - return name + descriptor->name(); -} - -TProtoStringType ClassName(const Descriptor* descriptor) { - return ClassName(descriptor, NULL); -} - -TProtoStringType ClassName(const Descriptor* descriptor, - TProtoStringType* out_suffix_added) { - // 1. Message names are used as is (style calls for CamelCase, trust it). - // 2. Check for reserved word at the very end and then suffix things. - const TProtoStringType prefix = FileClassPrefix(descriptor->file()); - const TProtoStringType name = ClassNameWorker(descriptor); - return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added); -} - -TProtoStringType EnumName(const EnumDescriptor* descriptor) { - // 1. Enum names are used as is (style calls for CamelCase, trust it). - // 2. Check for reserved word at the every end and then suffix things. - // message Fixed { - // message Size {...} - // enum Mumble {...} - // ... - // } - // yields Fixed_Class, Fixed_Size. - const TProtoStringType prefix = FileClassPrefix(descriptor->file()); - const TProtoStringType name = ClassNameWorker(descriptor); - return SanitizeNameForObjC(prefix, name, "_Enum", NULL); -} - -TProtoStringType EnumValueName(const EnumValueDescriptor* descriptor) { - // Because of the Switch enum compatibility, the name on the enum has to have - // the suffix handing, so it slightly diverges from how nested classes work. - // enum Fixed { - // FOO = 1 - // } - // yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo). - const TProtoStringType class_name = EnumName(descriptor->type()); - const TProtoStringType value_str = - UnderscoresToCamelCase(descriptor->name(), true); - const TProtoStringType name = class_name + "_" + value_str; - // There aren't really any reserved words with an underscore and a leading - // capital letter, but playing it safe and checking. - return SanitizeNameForObjC("", name, "_Value", NULL); -} - -TProtoStringType EnumValueShortName(const EnumValueDescriptor* descriptor) { - // Enum value names (EnumValueName above) are the enum name turned into - // a class name and then the value name is CamelCased and concatenated; the - // whole thing then gets sanitized for reserved words. - // The "short name" is intended to be the final leaf, the value name; but - // you can't simply send that off to sanitize as that could result in it - // getting modified when the full name didn't. For example enum - // "StorageModes" has a value "retain". So the full name is - // "StorageModes_Retain", but if we sanitize "retain" it would become - // "RetainValue". - // So the right way to get the short name is to take the full enum name - // and then strip off the enum name (leaving the value name and anything - // done by sanitize). - const TProtoStringType class_name = EnumName(descriptor->type()); - const TProtoStringType long_name_prefix = class_name + "_"; - const TProtoStringType long_name = EnumValueName(descriptor); - return StripPrefixString(long_name, long_name_prefix); -} - -TProtoStringType UnCamelCaseEnumShortName(const TProtoStringType& name) { - TProtoStringType result; - for (int i = 0; i < name.size(); i++) { - char c = name[i]; - if (i > 0 && ascii_isupper(c)) { - result += '_'; - } - result += ascii_toupper(c); - } - return result; -} - -TProtoStringType ExtensionMethodName(const FieldDescriptor* descriptor) { - const TProtoStringType name = NameFromFieldDescriptor(descriptor); - const TProtoStringType result = UnderscoresToCamelCase(name, false); - return SanitizeNameForObjC("", result, "_Extension", NULL); -} - -TProtoStringType FieldName(const FieldDescriptor* field) { - const TProtoStringType name = NameFromFieldDescriptor(field); - TProtoStringType result = UnderscoresToCamelCase(name, false); - if (field->is_repeated() && !field->is_map()) { - // Add "Array" before do check for reserved worlds. - result += "Array"; - } else { - // If it wasn't repeated, but ends in "Array", force on the _p suffix. - if (HasSuffixString(result, "Array")) { - result += "_p"; - } - } - return SanitizeNameForObjC("", result, "_p", NULL); -} - -TProtoStringType FieldNameCapitalized(const FieldDescriptor* field) { - // Want the same suffix handling, so upcase the first letter of the other - // name. - TProtoStringType result = FieldName(field); - if (result.length() > 0) { - result[0] = ascii_toupper(result[0]); - } - return result; -} - -TProtoStringType OneofEnumName(const OneofDescriptor* descriptor) { - const Descriptor* fieldDescriptor = descriptor->containing_type(); - TProtoStringType name = ClassName(fieldDescriptor); - name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase"; - // No sanitize needed because the OS never has names that end in _OneOfCase. - return name; -} - -TProtoStringType OneofName(const OneofDescriptor* descriptor) { - TProtoStringType name = UnderscoresToCamelCase(descriptor->name(), false); - // No sanitize needed because it gets OneOfCase added and that shouldn't - // ever conflict. - return name; -} - -TProtoStringType OneofNameCapitalized(const OneofDescriptor* descriptor) { - // Use the common handling and then up-case the first letter. - TProtoStringType result = OneofName(descriptor); - if (result.length() > 0) { - result[0] = ascii_toupper(result[0]); - } - return result; -} - -TProtoStringType ObjCClass(const TProtoStringType& class_name) { - return TProtoStringType("GPBObjCClass(") + class_name + ")"; -} - -TProtoStringType ObjCClassDeclaration(const TProtoStringType& class_name) { - return TProtoStringType("GPBObjCClassDeclaration(") + class_name + ");"; -} - -TProtoStringType UnCamelCaseFieldName(const TProtoStringType& name, const FieldDescriptor* field) { - TProtoStringType worker(name); - if (HasSuffixString(worker, "_p")) { - worker = StripSuffixString(worker, "_p"); - } - if (field->is_repeated() && HasSuffixString(worker, "Array")) { - worker = StripSuffixString(worker, "Array"); - } - if (field->type() == FieldDescriptor::TYPE_GROUP) { - if (worker.length() > 0) { - if (ascii_islower(worker[0])) { - worker[0] = ascii_toupper(worker[0]); - } - } - return worker; - } else { - TProtoStringType result; - for (int i = 0; i < worker.size(); i++) { - char c = worker[i]; - if (ascii_isupper(c)) { - if (i > 0) { - result += '_'; - } - result += ascii_tolower(c); - } else { - result += c; - } - } - return result; - } -} - -TProtoStringType GetCapitalizedType(const FieldDescriptor* field) { - switch (field->type()) { - case FieldDescriptor::TYPE_INT32: - return "Int32"; - case FieldDescriptor::TYPE_UINT32: - return "UInt32"; - case FieldDescriptor::TYPE_SINT32: - return "SInt32"; - case FieldDescriptor::TYPE_FIXED32: - return "Fixed32"; - case FieldDescriptor::TYPE_SFIXED32: - return "SFixed32"; - case FieldDescriptor::TYPE_INT64: - return "Int64"; - case FieldDescriptor::TYPE_UINT64: - return "UInt64"; - case FieldDescriptor::TYPE_SINT64: - return "SInt64"; - case FieldDescriptor::TYPE_FIXED64: - return "Fixed64"; - case FieldDescriptor::TYPE_SFIXED64: - return "SFixed64"; - case FieldDescriptor::TYPE_FLOAT: - return "Float"; - case FieldDescriptor::TYPE_DOUBLE: - return "Double"; - case FieldDescriptor::TYPE_BOOL: - return "Bool"; - case FieldDescriptor::TYPE_STRING: - return "String"; - case FieldDescriptor::TYPE_BYTES: - return "Bytes"; - case FieldDescriptor::TYPE_ENUM: - return "Enum"; - case FieldDescriptor::TYPE_GROUP: - return "Group"; - case FieldDescriptor::TYPE_MESSAGE: - return "Message"; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return TProtoStringType(); -} - -ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) { - switch (field_type) { - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_SFIXED32: - return OBJECTIVECTYPE_INT32; - - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_FIXED32: - return OBJECTIVECTYPE_UINT32; - - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_SFIXED64: - return OBJECTIVECTYPE_INT64; - - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_FIXED64: - return OBJECTIVECTYPE_UINT64; - - case FieldDescriptor::TYPE_FLOAT: - return OBJECTIVECTYPE_FLOAT; - - case FieldDescriptor::TYPE_DOUBLE: - return OBJECTIVECTYPE_DOUBLE; - - case FieldDescriptor::TYPE_BOOL: - return OBJECTIVECTYPE_BOOLEAN; - - case FieldDescriptor::TYPE_STRING: - return OBJECTIVECTYPE_STRING; - - case FieldDescriptor::TYPE_BYTES: - return OBJECTIVECTYPE_DATA; - - case FieldDescriptor::TYPE_ENUM: - return OBJECTIVECTYPE_ENUM; - - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - return OBJECTIVECTYPE_MESSAGE; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return OBJECTIVECTYPE_INT32; -} - -bool IsPrimitiveType(const FieldDescriptor* field) { - ObjectiveCType type = GetObjectiveCType(field); - switch (type) { - case OBJECTIVECTYPE_INT32: - case OBJECTIVECTYPE_UINT32: - case OBJECTIVECTYPE_INT64: - case OBJECTIVECTYPE_UINT64: - case OBJECTIVECTYPE_FLOAT: - case OBJECTIVECTYPE_DOUBLE: - case OBJECTIVECTYPE_BOOLEAN: - case OBJECTIVECTYPE_ENUM: - return true; - break; - default: - return false; - } -} - -bool IsReferenceType(const FieldDescriptor* field) { - return !IsPrimitiveType(field); -} - -static TProtoStringType HandleExtremeFloatingPoint(TProtoStringType val, - bool add_float_suffix) { - if (val == "nan") { - return "NAN"; - } else if (val == "inf") { - return "INFINITY"; - } else if (val == "-inf") { - return "-INFINITY"; - } else { - // float strings with ., e or E need to have f appended - if (add_float_suffix && (val.find(".") != TProtoStringType::npos || - val.find("e") != TProtoStringType::npos || - val.find("E") != TProtoStringType::npos)) { - val += "f"; - } - return val; - } -} - -TProtoStringType GPBGenericValueFieldName(const FieldDescriptor* field) { - // Returns the field within the GPBGenericValue union to use for the given - // field. - if (field->is_repeated()) { - return "valueMessage"; - } - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - return "valueInt32"; - case FieldDescriptor::CPPTYPE_UINT32: - return "valueUInt32"; - case FieldDescriptor::CPPTYPE_INT64: - return "valueInt64"; - case FieldDescriptor::CPPTYPE_UINT64: - return "valueUInt64"; - case FieldDescriptor::CPPTYPE_FLOAT: - return "valueFloat"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return "valueDouble"; - case FieldDescriptor::CPPTYPE_BOOL: - return "valueBool"; - case FieldDescriptor::CPPTYPE_STRING: - if (field->type() == FieldDescriptor::TYPE_BYTES) { - return "valueData"; - } else { - return "valueString"; - } - case FieldDescriptor::CPPTYPE_ENUM: - return "valueEnum"; - case FieldDescriptor::CPPTYPE_MESSAGE: - return "valueMessage"; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return TProtoStringType(); -} - - -TProtoStringType DefaultValue(const FieldDescriptor* field) { - // Repeated fields don't have defaults. - if (field->is_repeated()) { - return "nil"; - } - - // Switch on cpp_type since we need to know which default_value_* method - // of FieldDescriptor to call. - switch (field->cpp_type()) { - case FieldDescriptor::CPPTYPE_INT32: - // gcc and llvm reject the decimal form of kint32min and kint64min. - if (field->default_value_int32() == INT_MIN) { - return "-0x80000000"; - } - return StrCat(field->default_value_int32()); - case FieldDescriptor::CPPTYPE_UINT32: - return StrCat(field->default_value_uint32()) + "U"; - case FieldDescriptor::CPPTYPE_INT64: - // gcc and llvm reject the decimal form of kint32min and kint64min. - if (field->default_value_int64() == LLONG_MIN) { - return "-0x8000000000000000LL"; - } - return StrCat(field->default_value_int64()) + "LL"; - case FieldDescriptor::CPPTYPE_UINT64: - return StrCat(field->default_value_uint64()) + "ULL"; - case FieldDescriptor::CPPTYPE_DOUBLE: - return HandleExtremeFloatingPoint( - SimpleDtoa(field->default_value_double()), false); - case FieldDescriptor::CPPTYPE_FLOAT: - return HandleExtremeFloatingPoint( - SimpleFtoa(field->default_value_float()), true); - case FieldDescriptor::CPPTYPE_BOOL: - return field->default_value_bool() ? "YES" : "NO"; - case FieldDescriptor::CPPTYPE_STRING: { - const bool has_default_value = field->has_default_value(); - const TProtoStringType& default_string = field->default_value_string(); - if (!has_default_value || default_string.length() == 0) { - // If the field is defined as being the empty string, - // then we will just assign to nil, as the empty string is the - // default for both strings and data. - return "nil"; - } - if (field->type() == FieldDescriptor::TYPE_BYTES) { - // We want constant fields in our data structures so we can - // declare them as static. To achieve this we cheat and stuff - // a escaped c string (prefixed with a length) into the data - // field, and cast it to an (NSData*) so it will compile. - // The runtime library knows how to handle it. - - // Must convert to a standard byte order for packing length into - // a cstring. - uint32 length = ghtonl(default_string.length()); - TProtoStringType bytes((const char*)&length, sizeof(length)); - bytes.append(default_string); - return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\""; - } else { - return "@\"" + EscapeTrigraphs(CEscape(default_string)) + "\""; - } - } - case FieldDescriptor::CPPTYPE_ENUM: - return EnumValueName(field->default_value_enum()); - case FieldDescriptor::CPPTYPE_MESSAGE: - return "nil"; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return TProtoStringType(); -} - -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. - GOOGLE_LOG(FATAL) << "Can't get here."; - return false; -} - -TProtoStringType BuildFlagsString(const FlagType flag_type, - const std::vector<TProtoStringType>& strings) { - if (strings.empty()) { - return GetZeroEnumNameForFlagType(flag_type); - } else if (strings.size() == 1) { - return strings[0]; - } - TProtoStringType string("(" + GetEnumNameForFlagType(flag_type) + ")("); - for (size_t i = 0; i != strings.size(); ++i) { - if (i > 0) { - string.append(" | "); - } - string.append(strings[i]); - } - string.append(")"); - return string; -} - -TProtoStringType BuildCommentsString(const SourceLocation& location, - bool prefer_single_line) { - const TProtoStringType& comments = location.leading_comments.empty() - ? location.trailing_comments - : location.leading_comments; - std::vector<TProtoStringType> lines; - lines = Split(comments, "\n", false); - while (!lines.empty() && lines.back().empty()) { - lines.pop_back(); - } - // If there are no comments, just return an empty string. - if (lines.empty()) { - return ""; - } - - TProtoStringType prefix; - TProtoStringType suffix; - TProtoStringType final_comments; - TProtoStringType epilogue; - - bool add_leading_space = false; - - if (prefer_single_line && lines.size() == 1) { - prefix = "/** "; - suffix = " */\n"; - } else { - prefix = "* "; - suffix = "\n"; - final_comments += "/**\n"; - epilogue = " **/\n"; - add_leading_space = true; - } - - for (int i = 0; i < lines.size(); i++) { - TProtoStringType line = StripPrefixString(lines[i], " "); - // HeaderDoc and appledoc use '\' and '@' for markers; escape them. - line = StringReplace(line, "\\", "\\\\", true); - line = StringReplace(line, "@", "\\@", true); - // Decouple / from * to not have inline comments inside comments. - line = StringReplace(line, "/*", "/\\*", true); - line = StringReplace(line, "*/", "*\\/", true); - line = prefix + line; - StripWhitespace(&line); - // If not a one line, need to add the first space before *, as - // StripWhitespace would have removed it. - line = (add_leading_space ? " " : "") + line; - final_comments += line + suffix; - } - final_comments += epilogue; - return final_comments; -} - -// Making these a generator option for folks that don't use CocoaPods, but do -// want to put the library in a framework is an interesting question. The -// problem is it means changing sources shipped with the library to actually -// use a different value; so it isn't as simple as a option. -const char* const ProtobufLibraryFrameworkName = "Protobuf"; - -TProtoStringType ProtobufFrameworkImportSymbol(const TProtoStringType& framework_name) { - // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS - TProtoStringType result = TProtoStringType("GPB_USE_"); - result += ToUpper(framework_name); - result += "_FRAMEWORK_IMPORTS"; - return result; -} - -bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { - // We don't check the name prefix or proto package because some files - // (descriptor.proto), aren't shipped generated by the library, so this - // seems to be the safest way to only catch the ones shipped. - const TProtoStringType name = file->name(); - if (name == "google/protobuf/any.proto" || - name == "google/protobuf/api.proto" || - name == "google/protobuf/duration.proto" || - name == "google/protobuf/empty.proto" || - name == "google/protobuf/field_mask.proto" || - name == "google/protobuf/source_context.proto" || - name == "google/protobuf/struct.proto" || - name == "google/protobuf/timestamp.proto" || - name == "google/protobuf/type.proto" || - name == "google/protobuf/wrappers.proto") { - return true; - } - return false; -} - -bool ReadLine(StringPiece* input, StringPiece* line) { - for (int len = 0; len < input->size(); ++len) { - if (ascii_isnewline((*input)[len])) { - *line = StringPiece(input->data(), len); - ++len; // advance over the newline - *input = StringPiece(input->data() + len, input->size() - len); - return true; - } - } - return false; // Ran out of input with no newline. -} - -void RemoveComment(StringPiece* input) { - int offset = input->find('#'); - if (offset != StringPiece::npos) { - input->remove_suffix(input->length() - offset); - } -} - -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); - - private: - std::map<TProtoStringType, TProtoStringType>* prefix_map_; -}; - -bool ExpectedPrefixesCollector::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) + "'."; - return false; - } - StringPiece package = line.substr(0, offset); - StringPiece prefix = line.substr(offset + 1); - TrimWhitespace(&package); - TrimWhitespace(&prefix); - // Don't really worry about error checking the package/prefix for - // being valid. Assume the file is validated when it is created/edited. - (*prefix_map_)[TProtoStringType(package)] = TProtoStringType(prefix); - return true; -} - -bool LoadExpectedPackagePrefixes(const Options& generation_options, - std::map<TProtoStringType, TProtoStringType>* prefix_map, - TProtoStringType* out_error) { - if (generation_options.expected_prefixes_path.empty()) { - return true; - } - - ExpectedPrefixesCollector collector(prefix_map); - return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); -} - -bool ValidateObjCClassPrefix( - const FileDescriptor* file, const TProtoStringType& expected_prefixes_path, - const std::map<TProtoStringType, TProtoStringType>& expected_package_prefixes, - TProtoStringType* out_error) { - const TProtoStringType prefix = file->options().objc_class_prefix(); - const TProtoStringType package = file->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. - - // 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); - if (package_match != expected_package_prefixes.end()) { - // There was an entry, and... - if (package_match->second == prefix) { - // ...it matches. All good, out of here! - return true; - } else { - // ...it didn't match! - *out_error = "error: Expected 'option objc_class_prefix = \"" + - package_match->second + "\";' for package '" + package + - "' in '" + file->name() + "'"; - if (prefix.length()) { - *out_error += "; but found '" + prefix + "' instead"; - } - *out_error += "."; - return false; - } - } - - // If there was no prefix option, we're done at this point. - if (prefix.empty()) { - // No prefix, nothing left to check. - return true; - } - - // Check: Warning - Make sure the prefix is is a reasonable value according - // to Apple's rules (the checks above implicitly whitelist anything that - // doesn't meet these rules). - if (!ascii_isupper(prefix[0])) { - std::cerr - << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " it should start with a capital letter." << std::endl; - std::cerr.flush(); - } - if (prefix.length() < 3) { - // Apple reserves 2 character prefixes for themselves. They do use some - // 3 character prefixes, but they haven't updated the rules/docs. - std::cerr - << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" - << prefix << "\";' in '" << file->name() << "';" - << " Apple recommends they should be at least 3 characters long." - << std::endl; - std::cerr.flush(); - } - - // Look for any other package that uses the same prefix. - TProtoStringType other_package_for_prefix; - for (std::map<TProtoStringType, TProtoStringType>::const_iterator i = - expected_package_prefixes.begin(); - 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 declared is being used by another package or not. - 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(); - } - return true; - } - - // Check: Error - Make sure the prefix wasn't expected for a different - // package (overlap is allowed, but it has to be listed as an expected - // overlap). - 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 + ")."; - return false; // Only report first usage of the prefix. - } - - // Check: Warning - If the given package/prefix pair wasn't expected, issue a - // warning issue a warning suggesting it gets added to the file. - if (!expected_package_prefixes.empty()) { - 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; - std::cerr.flush(); - } - - return true; -} - -} // namespace - -bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, - const Options& generation_options, - TProtoStringType* out_error) { - // Load the expected package prefixes, if available, to validate against. - std::map<TProtoStringType, TProtoStringType> expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, - &expected_package_prefixes, - out_error)) { - return false; - } - - for (int i = 0; i < files.size(); i++) { - bool should_skip = - (std::find(generation_options.expected_prefixes_suppressions.begin(), - generation_options.expected_prefixes_suppressions.end(), - files[i]->name()) - != generation_options.expected_prefixes_suppressions.end()); - if (should_skip) { - continue; - } - - bool is_valid = - ValidateObjCClassPrefix(files[i], - generation_options.expected_prefixes_path, - expected_package_prefixes, - out_error); - if (!is_valid) { - return false; - } - } - return true; -} - -TextFormatDecodeData::TextFormatDecodeData() { } - -TextFormatDecodeData::~TextFormatDecodeData() { } - -void TextFormatDecodeData::AddString(int32 key, - const TProtoStringType& input_for_decode, - const TProtoStringType& desired_output) { - for (std::vector<DataEntry>::const_iterator i = entries_.begin(); - i != entries_.end(); ++i) { - if (i->first == key) { - std::cerr << "error: duplicate key (" << key - << ") making TextFormat data, input: \"" << input_for_decode - << "\", desired: \"" << desired_output << "\"." << std::endl; - std::cerr.flush(); - abort(); - } - } - - const TProtoStringType& data = TextFormatDecodeData::DecodeDataForString( - input_for_decode, desired_output); - entries_.push_back(DataEntry(key, data)); -} - -TProtoStringType TextFormatDecodeData::Data() const { - std::ostringstream data_stringstream; - - if (num_entries() > 0) { - io::OstreamOutputStream data_outputstream(&data_stringstream); - io::CodedOutputStream output_stream(&data_outputstream); - - output_stream.WriteVarint32(num_entries()); - for (std::vector<DataEntry>::const_iterator i = entries_.begin(); - i != entries_.end(); ++i) { - output_stream.WriteVarint32(i->first); - output_stream.WriteString(i->second); - } - } - - data_stringstream.flush(); - return TProtoStringType{data_stringstream.str()}; -} - -namespace { - -// Helper to build up the decode data for a string. -class DecodeDataBuilder { - public: - DecodeDataBuilder() { Reset(); } - - bool AddCharacter(const char desired, const char input); - void AddUnderscore() { - Push(); - need_underscore_ = true; - } - TProtoStringType Finish() { - Push(); - return decode_data_; - } - - private: - static constexpr uint8 kAddUnderscore = 0x80; - - static constexpr uint8 kOpAsIs = 0x00; - static constexpr uint8 kOpFirstUpper = 0x40; - static constexpr uint8 kOpFirstLower = 0x20; - static constexpr uint8 kOpAllUpper = 0x60; - - static constexpr int kMaxSegmentLen = 0x1f; - - void AddChar(const char desired) { - ++segment_len_; - is_all_upper_ &= ascii_isupper(desired); - } - - void Push() { - uint8 op = (op_ | segment_len_); - if (need_underscore_) op |= kAddUnderscore; - if (op != 0) { - decode_data_ += (char)op; - } - Reset(); - } - - bool AddFirst(const char desired, const char input) { - if (desired == input) { - op_ = kOpAsIs; - } else if (desired == ascii_toupper(input)) { - op_ = kOpFirstUpper; - } else if (desired == ascii_tolower(input)) { - op_ = kOpFirstLower; - } else { - // Can't be transformed to match. - return false; - } - AddChar(desired); - return true; - } - - void Reset() { - need_underscore_ = false; - op_ = 0; - segment_len_ = 0; - is_all_upper_ = true; - } - - bool need_underscore_; - bool is_all_upper_; - uint8 op_; - int segment_len_; - - TProtoStringType decode_data_; -}; - -bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { - // If we've hit the max size, push to start a new segment. - if (segment_len_ == kMaxSegmentLen) { - Push(); - } - if (segment_len_ == 0) { - return AddFirst(desired, input); - } - - // Desired and input match... - if (desired == input) { - // If we aren't transforming it, or we're upper casing it and it is - // supposed to be uppercase; just add it to the segment. - if ((op_ != kOpAllUpper) || ascii_isupper(desired)) { - AddChar(desired); - return true; - } - - // Add the current segment, and start the next one. - Push(); - return AddFirst(desired, input); - } - - // If we need to uppercase, and everything so far has been uppercase, - // promote op to AllUpper. - if ((desired == ascii_toupper(input)) && is_all_upper_) { - op_ = kOpAllUpper; - AddChar(desired); - return true; - } - - // Give up, push and start a new segment. - Push(); - return AddFirst(desired, input); -} - -// If decode data can't be generated, a directive for the raw string -// is used instead. -TProtoStringType DirectDecodeString(const TProtoStringType& str) { - TProtoStringType result; - result += (char)'\0'; // Marker for full string. - result += str; - result += (char)'\0'; // End of string. - return result; -} - -} // namespace - -// static -TProtoStringType TextFormatDecodeData::DecodeDataForString( - const TProtoStringType& input_for_decode, const TProtoStringType& desired_output) { - if (input_for_decode.empty() || desired_output.empty()) { - std::cerr << "error: got empty string for making TextFormat data, input: \"" - << input_for_decode << "\", desired: \"" << desired_output << "\"." - << std::endl; - std::cerr.flush(); - abort(); - } - if ((input_for_decode.find('\0') != TProtoStringType::npos) || - (desired_output.find('\0') != TProtoStringType::npos)) { - std::cerr << "error: got a null char in a string for making TextFormat data," - << " input: \"" << CEscape(input_for_decode) << "\", desired: \"" - << CEscape(desired_output) << "\"." << std::endl; - std::cerr.flush(); - abort(); - } - - DecodeDataBuilder builder; - - // Walk the output building it from the input. - int x = 0; - for (int y = 0; y < desired_output.size(); y++) { - const char d = desired_output[y]; - if (d == '_') { - builder.AddUnderscore(); - continue; - } - - if (x >= input_for_decode.size()) { - // Out of input, no way to encode it, just return a full decode. - return DirectDecodeString(desired_output); - } - if (builder.AddCharacter(d, input_for_decode[x])) { - ++x; // Consumed one input - } else { - // Couldn't transform for the next character, just return a full decode. - return DirectDecodeString(desired_output); - } - } - - if (x != input_for_decode.size()) { - // Extra input (suffix from name sanitizing?), just return a full decode. - return DirectDecodeString(desired_output); - } - - // Add the end marker. - return builder.Finish() + (char)'\0'; -} - -namespace { - -class Parser { - public: - Parser(LineConsumer* line_consumer) - : line_consumer_(line_consumer), line_(0) {} - - // Parses a check of input, returning success/failure. - bool ParseChunk(StringPiece chunk); - - // Should be called to finish parsing (after all input has been provided via - // ParseChunk()). Returns success/failure. - bool Finish(); - - int last_line() const { return line_; } - TProtoStringType error_str() const { return error_str_; } - - private: - bool ParseLoop(); - - LineConsumer* line_consumer_; - int line_; - TProtoStringType error_str_; - StringPiece p_; - TProtoStringType leftover_; -}; - -bool Parser::ParseChunk(StringPiece chunk) { - if (!leftover_.empty()) { - leftover_ += TProtoStringType(chunk); - p_ = StringPiece(leftover_); - } else { - p_ = chunk; - } - bool result = ParseLoop(); - if (p_.empty()) { - leftover_.clear(); - } else { - leftover_ = TProtoStringType(p_); - } - return result; -} - -bool Parser::Finish() { - if (leftover_.empty()) { - return true; - } - // Force a newline onto the end to finish parsing. - leftover_ += "\n"; - p_ = StringPiece(leftover_); - if (!ParseLoop()) { - return false; - } - return p_.empty(); // Everything used? -} - -bool Parser::ParseLoop() { - StringPiece line; - while (ReadLine(&p_, &line)) { - ++line_; - RemoveComment(&line); - TrimWhitespace(&line); - if (line.empty()) { - continue; // Blank line. - } - if (!line_consumer_->ConsumeLine(line, &error_str_)) { - return false; - } - } - return true; -} - -} // namespace - -LineConsumer::LineConsumer() {} - -LineConsumer::~LineConsumer() {} - -bool ParseSimpleFile(const TProtoStringType& path, LineConsumer* line_consumer, - TProtoStringType* out_error) { - int fd; - do { - fd = posix::open(path.c_str(), O_RDONLY); - } while (fd < 0 && errno == EINTR); - if (fd < 0) { - *out_error = TProtoStringType("error: Unable to open \"") + path + "\", " + - strerror(errno); - return false; - } - io::FileInputStream file_stream(fd); - file_stream.SetCloseOnDelete(true); - - Parser parser(line_consumer); - const void* buf; - int buf_len; - while (file_stream.Next(&buf, &buf_len)) { - if (buf_len == 0) { - continue; - } - - if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) { - *out_error = - TProtoStringType("error: ") + path + - " Line " + StrCat(parser.last_line()) + ", " + parser.error_str(); - return false; - } - } - return parser.Finish(); -} - -ImportWriter::ImportWriter( - const TProtoStringType& generate_for_named_framework, - const TProtoStringType& named_framework_to_proto_path_mappings_path, - const TProtoStringType& runtime_import_prefix, bool include_wkt_imports) - : generate_for_named_framework_(generate_for_named_framework), - named_framework_to_proto_path_mappings_path_( - named_framework_to_proto_path_mappings_path), - runtime_import_prefix_(runtime_import_prefix), - include_wkt_imports_(include_wkt_imports), - need_to_parse_mapping_file_(true) {} - -ImportWriter::~ImportWriter() {} - -void ImportWriter::AddFile(const FileDescriptor* file, - const TProtoStringType& header_extension) { - if (IsProtobufLibraryBundledProtoFile(file)) { - // The imports of the WKTs are only needed within the library itself, - // in other cases, they get skipped because the generated code already - // import GPBProtocolBuffers.h and hence proves them. - if (include_wkt_imports_) { - const TProtoStringType header_name = - "GPB" + FilePathBasename(file) + header_extension; - protobuf_imports_.push_back(header_name); - } - return; - } - - // Lazy parse any mappings. - if (need_to_parse_mapping_file_) { - ParseFrameworkMappings(); - } - - std::map<TProtoStringType, TProtoStringType>::iterator proto_lookup = - proto_file_to_framework_name_.find(file->name()); - if (proto_lookup != proto_file_to_framework_name_.end()) { - other_framework_imports_.push_back( - proto_lookup->second + "/" + - FilePathBasename(file) + header_extension); - return; - } - - if (!generate_for_named_framework_.empty()) { - other_framework_imports_.push_back( - generate_for_named_framework_ + "/" + - FilePathBasename(file) + header_extension); - return; - } - - other_imports_.push_back(FilePath(file) + header_extension); -} - -void ImportWriter::Print(io::Printer* printer) const { - bool add_blank_line = false; - - if (!protobuf_imports_.empty()) { - PrintRuntimeImports(printer, protobuf_imports_, runtime_import_prefix_); - add_blank_line = true; - } - - if (!other_framework_imports_.empty()) { - if (add_blank_line) { - printer->Print("\n"); - } - - for (std::vector<TProtoStringType>::const_iterator iter = - other_framework_imports_.begin(); - iter != other_framework_imports_.end(); ++iter) { - printer->Print( - "#import <$header$>\n", - "header", *iter); - } - - add_blank_line = true; - } - - if (!other_imports_.empty()) { - if (add_blank_line) { - printer->Print("\n"); - } - - for (std::vector<TProtoStringType>::const_iterator iter = other_imports_.begin(); - iter != other_imports_.end(); ++iter) { - printer->Print( - "#import \"$header$\"\n", - "header", *iter); - } - } -} - -void ImportWriter::PrintRuntimeImports( - io::Printer* printer, const std::vector<TProtoStringType>& header_to_import, - const TProtoStringType& runtime_import_prefix, bool default_cpp_symbol) { - // Given an override, use that. - if (!runtime_import_prefix.empty()) { - for (const auto& header : header_to_import) { - printer->Print( - " #import \"$import_prefix$/$header$\"\n", - "import_prefix", runtime_import_prefix, - "header", header); - } - return; - } - - const TProtoStringType framework_name(ProtobufLibraryFrameworkName); - const TProtoStringType cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); - - if (default_cpp_symbol) { - printer->Print( - "// This CPP symbol can be defined to use imports that match up to the framework\n" - "// imports needed when using CocoaPods.\n" - "#if !defined($cpp_symbol$)\n" - " #define $cpp_symbol$ 0\n" - "#endif\n" - "\n", - "cpp_symbol", cpp_symbol); - } - - printer->Print( - "#if $cpp_symbol$\n", - "cpp_symbol", cpp_symbol); - for (const auto& header : header_to_import) { - printer->Print( - " #import <$framework_name$/$header$>\n", - "framework_name", framework_name, - "header", header); - } - printer->Print( - "#else\n"); - for (const auto& header : header_to_import) { - printer->Print( - " #import \"$header$\"\n", - "header", header); - } - printer->Print( - "#endif\n"); -} - -void ImportWriter::ParseFrameworkMappings() { - need_to_parse_mapping_file_ = false; - if (named_framework_to_proto_path_mappings_path_.empty()) { - return; // Nothing to do. - } - - ProtoFrameworkCollector collector(&proto_file_to_framework_name_); - TProtoStringType parse_error; - if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_, - &collector, &parse_error)) { - std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_ - << " : " << parse_error << std::endl; - std::cerr.flush(); - } -} - -bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( - const StringPiece& line, TProtoStringType* out_error) { - int offset = line.find(':'); - if (offset == StringPiece::npos) { - *out_error = - TProtoStringType("Framework/proto file mapping line without colon sign: '") + - TProtoStringType(line) + "'."; - return false; - } - StringPiece framework_name = line.substr(0, offset); - StringPiece proto_file_list = line.substr(offset + 1); - TrimWhitespace(&framework_name); - - int start = 0; - while (start < proto_file_list.length()) { - offset = proto_file_list.find(',', start); - if (offset == StringPiece::npos) { - offset = proto_file_list.length(); - } - - StringPiece proto_file = proto_file_list.substr(start, offset - start); - TrimWhitespace(&proto_file); - if (!proto_file.empty()) { - std::map<TProtoStringType, TProtoStringType>::iterator existing_entry = - map_->find(TProtoStringType(proto_file)); - if (existing_entry != map_->end()) { - std::cerr << "warning: duplicate proto file reference, replacing " - "framework entry for '" - << TProtoStringType(proto_file) << "' with '" << TProtoStringType(framework_name) - << "' (was '" << existing_entry->second << "')." << std::endl; - std::cerr.flush(); - } - - if (proto_file.find(' ') != StringPiece::npos) { - std::cerr << "note: framework mapping file had a proto file with a " - "space in, hopefully that isn't a missing comma: '" - << TProtoStringType(proto_file) << "'" << std::endl; - std::cerr.flush(); - } - - (*map_)[TProtoStringType(proto_file)] = TProtoStringType(framework_name); - } - - start = offset + 1; - } - - return true; -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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. + +#ifndef _MSC_VER +#include <unistd.h> +#endif +#include <climits> +#include <errno.h> +#include <fcntl.h> +#include <fstream> +#include <iostream> +#include <sstream> +#include <stdlib.h> +#include <unordered_set> +#include <vector> + +#include <google/protobuf/compiler/code_generator.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h> +#include <google/protobuf/descriptor.pb.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/io/io_win32.h> +#include <google/protobuf/port.h> +#include <google/protobuf/stubs/common.h> +#include <google/protobuf/stubs/port.h> +#include <google/protobuf/stubs/strutil.h> + +// 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 errors. + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// <io.h> is transitively included in this file. Import the functions explicitly +// in this port namespace to avoid ambiguous definition. +namespace posix { +#ifdef _WIN32 +using ::google::protobuf::io::win32::open; +#else +using ::open; +#endif +} // namespace port + +Options::Options() { + // Default is the value of the env for the package prefixes. + const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES"); + if (file_path) { + expected_prefixes_path = file_path; + } + const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS"); + if (suppressions) { + expected_prefixes_suppressions = + Split(suppressions, ";", true); + } +} + +namespace { + +std::unordered_set<TProtoStringType> MakeWordsMap(const char* const words[], + size_t num_words) { + std::unordered_set<TProtoStringType> result; + for (int i = 0; i < num_words; i++) { + result.insert(words[i]); + } + return result; +} + +const char* const kUpperSegmentsList[] = {"url", "http", "https"}; + +std::unordered_set<TProtoStringType> kUpperSegments = + MakeWordsMap(kUpperSegmentsList, GOOGLE_ARRAYSIZE(kUpperSegmentsList)); + +bool ascii_isnewline(char c) { + return c == '\n' || c == '\r'; +} + +// Internal helper for name handing. +// Do not expose this outside of helpers, stick to having functions for specific +// cases (ClassName(), FieldName()), so there is always consistent suffix rules. +TProtoStringType UnderscoresToCamelCase(const TProtoStringType& input, + bool first_capitalized) { + std::vector<TProtoStringType> values; + TProtoStringType current; + + bool last_char_was_number = false; + bool last_char_was_lower = false; + bool last_char_was_upper = false; + for (int i = 0; i < input.size(); i++) { + char c = input[i]; + if (ascii_isdigit(c)) { + if (!last_char_was_number) { + values.push_back(current); + current = ""; + } + current += c; + last_char_was_number = last_char_was_lower = last_char_was_upper = false; + last_char_was_number = true; + } else if (ascii_islower(c)) { + // lowercase letter can follow a lowercase or uppercase letter + if (!last_char_was_lower && !last_char_was_upper) { + values.push_back(current); + current = ""; + } + current += c; // already lower + last_char_was_number = last_char_was_lower = last_char_was_upper = false; + last_char_was_lower = true; + } else if (ascii_isupper(c)) { + if (!last_char_was_upper) { + values.push_back(current); + current = ""; + } + current += ascii_tolower(c); + last_char_was_number = last_char_was_lower = last_char_was_upper = false; + last_char_was_upper = true; + } else { + last_char_was_number = last_char_was_lower = last_char_was_upper = false; + } + } + values.push_back(current); + + TProtoStringType result; + bool first_segment_forces_upper = false; + for (std::vector<TProtoStringType>::iterator i = values.begin(); i != values.end(); + ++i) { + TProtoStringType value = *i; + bool all_upper = (kUpperSegments.count(value) > 0); + if (all_upper && (result.length() == 0)) { + first_segment_forces_upper = true; + } + for (int j = 0; j < value.length(); j++) { + if (j == 0 || all_upper) { + value[j] = ascii_toupper(value[j]); + } else { + // Nothing, already in lower. + } + } + result += value; + } + if ((result.length() != 0) && + !first_capitalized && + !first_segment_forces_upper) { + result[0] = ascii_tolower(result[0]); + } + return result; +} + +const char* const kReservedWordList[] = { + // Note NSObject Methods: + // These are brought in from objectivec_nsobject_methods.h that is generated + // using method_dump.sh. See kNSObjectMethods below. + + // Objective C "keywords" that aren't in C + // From + // http://stackoverflow.com/questions/1873630/reserved-keywords-in-objective-c + // with some others added on. + "id", "_cmd", "super", "in", "out", "inout", "bycopy", "byref", "oneway", + "self", "instancetype", "nullable", "nonnull", "nil", "Nil", + "YES", "NO", "weak", + + // C/C++ keywords (Incl C++ 0x11) + // From http://en.cppreference.com/w/cpp/keywords + "and", "and_eq", "alignas", "alignof", "asm", "auto", "bitand", "bitor", + "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class", + "compl", "const", "constexpr", "const_cast", "continue", "decltype", + "default", "delete", "double", "dynamic_cast", "else", "enum", "explicit", + "export", "extern ", "false", "float", "for", "friend", "goto", "if", + "inline", "int", "long", "mutable", "namespace", "new", "noexcept", "not", + "not_eq", "nullptr", "operator", "or", "or_eq", "private", "protected", + "public", "register", "reinterpret_cast", "return", "short", "signed", + "sizeof", "static", "static_assert", "static_cast", "struct", "switch", + "template", "this", "thread_local", "throw", "true", "try", "typedef", + "typeid", "typename", "union", "unsigned", "using", "virtual", "void", + "volatile", "wchar_t", "while", "xor", "xor_eq", + + // C99 keywords + // From + // http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fkeyw.htm + "restrict", + + // GCC/Clang extension + "typeof", + + // Not a keyword, but will break you + "NULL", + + // C88+ specs call for these to be macros, so depending on what they are + // defined to be it can lead to odd errors for some Xcode/SDK versions. + "stdin", "stdout", "stderr", + + // Objective-C Runtime typedefs + // From <obc/runtime.h> + "Category", "Ivar", "Method", "Protocol", + + // GPBMessage Methods + // Only need to add instance methods that may conflict with + // method declared in protos. The main cases are methods + // that take no arguments, or setFoo:/hasFoo: type methods. + "clear", "data", "delimitedData", "descriptor", "extensionRegistry", + "extensionsCurrentlySet", "initialized", "isInitialized", "serializedSize", + "sortedExtensionsInUse", "unknownFields", + + // MacTypes.h names + "Fixed", "Fract", "Size", "LogicalAddress", "PhysicalAddress", "ByteCount", + "ByteOffset", "Duration", "AbsoluteTime", "OptionBits", "ItemCount", + "PBVersion", "ScriptCode", "LangCode", "RegionCode", "OSType", + "ProcessSerialNumber", "Point", "Rect", "FixedPoint", "FixedRect", "Style", + "StyleParameter", "StyleField", "TimeScale", "TimeBase", "TimeRecord", +}; + +// returns true is input starts with __ or _[A-Z] which are reserved identifiers +// in C/ C++. All calls should go through UnderscoresToCamelCase before getting here +// but this verifies and allows for future expansion if we decide to redefine what a +// reserved C identifier is (for example the GNU list +// https://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html ) +bool IsReservedCIdentifier(const TProtoStringType& input) { + if (input.length() > 2) { + if (input.at(0) == '_') { + if (isupper(input.at(1)) || input.at(1) == '_') { + return true; + } + } + } + return false; +} + +TProtoStringType SanitizeNameForObjC(const TProtoStringType& prefix, + 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 = + MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList)); + TProtoStringType sanitized; + // We add the prefix in the cases where the string is missing a prefix. + // We define "missing a prefix" as where 'input': + // a) Doesn't start with the prefix or + // b) Isn't equivalent to the prefix or + // c) Has the prefix, but the letter after the prefix is lowercase + if (HasPrefixString(input, prefix)) { + if (input.length() == prefix.length() || !ascii_isupper(input[prefix.length()])) { + sanitized = prefix + input; + } else { + sanitized = input; + } + } else { + sanitized = prefix + input; + } + if (IsReservedCIdentifier(sanitized) || + (kReservedWords.count(sanitized) > 0) || + (kNSObjectMethods.count(sanitized) > 0)) { + if (out_suffix_added) *out_suffix_added = extension; + return sanitized + extension; + } + if (out_suffix_added) out_suffix_added->clear(); + return sanitized; +} + +TProtoStringType NameFromFieldDescriptor(const FieldDescriptor* field) { + if (field->type() == FieldDescriptor::TYPE_GROUP) { + return field->message_type()->name(); + } else { + return field->name(); + } +} + +void PathSplit(const TProtoStringType& path, TProtoStringType* directory, + TProtoStringType* basename) { + TProtoStringType::size_type last_slash = path.rfind('/'); + if (last_slash == TProtoStringType::npos) { + if (directory) { + *directory = ""; + } + if (basename) { + *basename = path; + } + } else { + if (directory) { + *directory = path.substr(0, last_slash); + } + if (basename) { + *basename = path.substr(last_slash + 1); + } + } +} + +bool IsSpecialName(const TProtoStringType& name, const TProtoStringType* special_names, + size_t count) { + for (size_t i = 0; i < count; ++i) { + size_t length = special_names[i].length(); + if (name.compare(0, length, special_names[i]) == 0) { + if (name.length() > length) { + // If name is longer than the retained_name[i] that it matches + // the next character must be not lower case (newton vs newTon vs + // new_ton). + return !ascii_islower(name[length]); + } else { + return true; + } + } + } + return false; +} + +TProtoStringType GetZeroEnumNameForFlagType(const FlagType flag_type) { + switch(flag_type) { + case FLAGTYPE_DESCRIPTOR_INITIALIZATION: + return "GPBDescriptorInitializationFlag_None"; + case FLAGTYPE_EXTENSION: + return "GPBExtensionNone"; + case FLAGTYPE_FIELD: + return "GPBFieldNone"; + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + return "0"; + } +} + +TProtoStringType GetEnumNameForFlagType(const FlagType flag_type) { + switch(flag_type) { + case FLAGTYPE_DESCRIPTOR_INITIALIZATION: + return "GPBDescriptorInitializationFlags"; + case FLAGTYPE_EXTENSION: + return "GPBExtensionOptions"; + case FLAGTYPE_FIELD: + return "GPBFieldFlags"; + default: + GOOGLE_LOG(FATAL) << "Can't get here."; + return TProtoStringType(); + } +} + +} // namespace + +// Escape C++ trigraphs by escaping question marks to \? +TProtoStringType EscapeTrigraphs(const TProtoStringType& to_escape) { + return StringReplace(to_escape, "?", "\\?", true); +} + +void TrimWhitespace(StringPiece* input) { + while (!input->empty() && ascii_isspace(*input->data())) { + input->remove_prefix(1); + } + while (!input->empty() && ascii_isspace((*input)[input->length() - 1])) { + input->remove_suffix(1); + } +} + +bool IsRetainedName(const TProtoStringType& name) { + // List of prefixes from + // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html + static const TProtoStringType retained_names[] = {"new", "alloc", "copy", + "mutableCopy"}; + return IsSpecialName(name, retained_names, + sizeof(retained_names) / sizeof(retained_names[0])); +} + +bool IsInitName(const TProtoStringType& name) { + static const TProtoStringType init_names[] = {"init"}; + return IsSpecialName(name, init_names, + sizeof(init_names) / sizeof(init_names[0])); +} + +TProtoStringType BaseFileName(const FileDescriptor* file) { + TProtoStringType basename; + PathSplit(file->name(), NULL, &basename); + return basename; +} + +TProtoStringType FileClassPrefix(const FileDescriptor* file) { + // Default is empty string, no need to check has_objc_class_prefix. + TProtoStringType result = file->options().objc_class_prefix(); + return result; +} + +TProtoStringType FilePath(const FileDescriptor* file) { + TProtoStringType output; + TProtoStringType basename; + TProtoStringType directory; + PathSplit(file->name(), &directory, &basename); + if (directory.length() > 0) { + output = directory + "/"; + } + basename = StripProto(basename); + + // CamelCase to be more ObjC friendly. + basename = UnderscoresToCamelCase(basename, true); + + output += basename; + return output; +} + +TProtoStringType FilePathBasename(const FileDescriptor* file) { + TProtoStringType output; + TProtoStringType basename; + TProtoStringType directory; + PathSplit(file->name(), &directory, &basename); + basename = StripProto(basename); + + // CamelCase to be more ObjC friendly. + output = UnderscoresToCamelCase(basename, true); + + return output; +} + +TProtoStringType FileClassName(const FileDescriptor* file) { + const TProtoStringType prefix = FileClassPrefix(file); + const TProtoStringType name = + UnderscoresToCamelCase(StripProto(BaseFileName(file)), true) + "Root"; + // There aren't really any reserved words that end in "Root", but playing + // it safe and checking. + return SanitizeNameForObjC(prefix, name, "_RootClass", NULL); +} + +TProtoStringType ClassNameWorker(const Descriptor* descriptor) { + TProtoStringType name; + if (descriptor->containing_type() != NULL) { + name = ClassNameWorker(descriptor->containing_type()); + name += "_"; + } + return name + descriptor->name(); +} + +TProtoStringType ClassNameWorker(const EnumDescriptor* descriptor) { + TProtoStringType name; + if (descriptor->containing_type() != NULL) { + name = ClassNameWorker(descriptor->containing_type()); + name += "_"; + } + return name + descriptor->name(); +} + +TProtoStringType ClassName(const Descriptor* descriptor) { + return ClassName(descriptor, NULL); +} + +TProtoStringType ClassName(const Descriptor* descriptor, + TProtoStringType* out_suffix_added) { + // 1. Message names are used as is (style calls for CamelCase, trust it). + // 2. Check for reserved word at the very end and then suffix things. + const TProtoStringType prefix = FileClassPrefix(descriptor->file()); + const TProtoStringType name = ClassNameWorker(descriptor); + return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added); +} + +TProtoStringType EnumName(const EnumDescriptor* descriptor) { + // 1. Enum names are used as is (style calls for CamelCase, trust it). + // 2. Check for reserved word at the every end and then suffix things. + // message Fixed { + // message Size {...} + // enum Mumble {...} + // ... + // } + // yields Fixed_Class, Fixed_Size. + const TProtoStringType prefix = FileClassPrefix(descriptor->file()); + const TProtoStringType name = ClassNameWorker(descriptor); + return SanitizeNameForObjC(prefix, name, "_Enum", NULL); +} + +TProtoStringType EnumValueName(const EnumValueDescriptor* descriptor) { + // Because of the Switch enum compatibility, the name on the enum has to have + // the suffix handing, so it slightly diverges from how nested classes work. + // enum Fixed { + // FOO = 1 + // } + // yields Fixed_Enum and Fixed_Enum_Foo (not Fixed_Foo). + const TProtoStringType class_name = EnumName(descriptor->type()); + const TProtoStringType value_str = + UnderscoresToCamelCase(descriptor->name(), true); + const TProtoStringType name = class_name + "_" + value_str; + // There aren't really any reserved words with an underscore and a leading + // capital letter, but playing it safe and checking. + return SanitizeNameForObjC("", name, "_Value", NULL); +} + +TProtoStringType EnumValueShortName(const EnumValueDescriptor* descriptor) { + // Enum value names (EnumValueName above) are the enum name turned into + // a class name and then the value name is CamelCased and concatenated; the + // whole thing then gets sanitized for reserved words. + // The "short name" is intended to be the final leaf, the value name; but + // you can't simply send that off to sanitize as that could result in it + // getting modified when the full name didn't. For example enum + // "StorageModes" has a value "retain". So the full name is + // "StorageModes_Retain", but if we sanitize "retain" it would become + // "RetainValue". + // So the right way to get the short name is to take the full enum name + // and then strip off the enum name (leaving the value name and anything + // done by sanitize). + const TProtoStringType class_name = EnumName(descriptor->type()); + const TProtoStringType long_name_prefix = class_name + "_"; + const TProtoStringType long_name = EnumValueName(descriptor); + return StripPrefixString(long_name, long_name_prefix); +} + +TProtoStringType UnCamelCaseEnumShortName(const TProtoStringType& name) { + TProtoStringType result; + for (int i = 0; i < name.size(); i++) { + char c = name[i]; + if (i > 0 && ascii_isupper(c)) { + result += '_'; + } + result += ascii_toupper(c); + } + return result; +} + +TProtoStringType ExtensionMethodName(const FieldDescriptor* descriptor) { + const TProtoStringType name = NameFromFieldDescriptor(descriptor); + const TProtoStringType result = UnderscoresToCamelCase(name, false); + return SanitizeNameForObjC("", result, "_Extension", NULL); +} + +TProtoStringType FieldName(const FieldDescriptor* field) { + const TProtoStringType name = NameFromFieldDescriptor(field); + TProtoStringType result = UnderscoresToCamelCase(name, false); + if (field->is_repeated() && !field->is_map()) { + // Add "Array" before do check for reserved worlds. + result += "Array"; + } else { + // If it wasn't repeated, but ends in "Array", force on the _p suffix. + if (HasSuffixString(result, "Array")) { + result += "_p"; + } + } + return SanitizeNameForObjC("", result, "_p", NULL); +} + +TProtoStringType FieldNameCapitalized(const FieldDescriptor* field) { + // Want the same suffix handling, so upcase the first letter of the other + // name. + TProtoStringType result = FieldName(field); + if (result.length() > 0) { + result[0] = ascii_toupper(result[0]); + } + return result; +} + +TProtoStringType OneofEnumName(const OneofDescriptor* descriptor) { + const Descriptor* fieldDescriptor = descriptor->containing_type(); + TProtoStringType name = ClassName(fieldDescriptor); + name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase"; + // No sanitize needed because the OS never has names that end in _OneOfCase. + return name; +} + +TProtoStringType OneofName(const OneofDescriptor* descriptor) { + TProtoStringType name = UnderscoresToCamelCase(descriptor->name(), false); + // No sanitize needed because it gets OneOfCase added and that shouldn't + // ever conflict. + return name; +} + +TProtoStringType OneofNameCapitalized(const OneofDescriptor* descriptor) { + // Use the common handling and then up-case the first letter. + TProtoStringType result = OneofName(descriptor); + if (result.length() > 0) { + result[0] = ascii_toupper(result[0]); + } + return result; +} + +TProtoStringType ObjCClass(const TProtoStringType& class_name) { + return TProtoStringType("GPBObjCClass(") + class_name + ")"; +} + +TProtoStringType ObjCClassDeclaration(const TProtoStringType& class_name) { + return TProtoStringType("GPBObjCClassDeclaration(") + class_name + ");"; +} + +TProtoStringType UnCamelCaseFieldName(const TProtoStringType& name, const FieldDescriptor* field) { + TProtoStringType worker(name); + if (HasSuffixString(worker, "_p")) { + worker = StripSuffixString(worker, "_p"); + } + if (field->is_repeated() && HasSuffixString(worker, "Array")) { + worker = StripSuffixString(worker, "Array"); + } + if (field->type() == FieldDescriptor::TYPE_GROUP) { + if (worker.length() > 0) { + if (ascii_islower(worker[0])) { + worker[0] = ascii_toupper(worker[0]); + } + } + return worker; + } else { + TProtoStringType result; + for (int i = 0; i < worker.size(); i++) { + char c = worker[i]; + if (ascii_isupper(c)) { + if (i > 0) { + result += '_'; + } + result += ascii_tolower(c); + } else { + result += c; + } + } + return result; + } +} + +TProtoStringType GetCapitalizedType(const FieldDescriptor* field) { + switch (field->type()) { + case FieldDescriptor::TYPE_INT32: + return "Int32"; + case FieldDescriptor::TYPE_UINT32: + return "UInt32"; + case FieldDescriptor::TYPE_SINT32: + return "SInt32"; + case FieldDescriptor::TYPE_FIXED32: + return "Fixed32"; + case FieldDescriptor::TYPE_SFIXED32: + return "SFixed32"; + case FieldDescriptor::TYPE_INT64: + return "Int64"; + case FieldDescriptor::TYPE_UINT64: + return "UInt64"; + case FieldDescriptor::TYPE_SINT64: + return "SInt64"; + case FieldDescriptor::TYPE_FIXED64: + return "Fixed64"; + case FieldDescriptor::TYPE_SFIXED64: + return "SFixed64"; + case FieldDescriptor::TYPE_FLOAT: + return "Float"; + case FieldDescriptor::TYPE_DOUBLE: + return "Double"; + case FieldDescriptor::TYPE_BOOL: + return "Bool"; + case FieldDescriptor::TYPE_STRING: + return "String"; + case FieldDescriptor::TYPE_BYTES: + return "Bytes"; + case FieldDescriptor::TYPE_ENUM: + return "Enum"; + case FieldDescriptor::TYPE_GROUP: + return "Group"; + case FieldDescriptor::TYPE_MESSAGE: + return "Message"; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return TProtoStringType(); +} + +ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type) { + switch (field_type) { + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_SFIXED32: + return OBJECTIVECTYPE_INT32; + + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_FIXED32: + return OBJECTIVECTYPE_UINT32; + + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_SFIXED64: + return OBJECTIVECTYPE_INT64; + + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_FIXED64: + return OBJECTIVECTYPE_UINT64; + + case FieldDescriptor::TYPE_FLOAT: + return OBJECTIVECTYPE_FLOAT; + + case FieldDescriptor::TYPE_DOUBLE: + return OBJECTIVECTYPE_DOUBLE; + + case FieldDescriptor::TYPE_BOOL: + return OBJECTIVECTYPE_BOOLEAN; + + case FieldDescriptor::TYPE_STRING: + return OBJECTIVECTYPE_STRING; + + case FieldDescriptor::TYPE_BYTES: + return OBJECTIVECTYPE_DATA; + + case FieldDescriptor::TYPE_ENUM: + return OBJECTIVECTYPE_ENUM; + + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + return OBJECTIVECTYPE_MESSAGE; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return OBJECTIVECTYPE_INT32; +} + +bool IsPrimitiveType(const FieldDescriptor* field) { + ObjectiveCType type = GetObjectiveCType(field); + switch (type) { + case OBJECTIVECTYPE_INT32: + case OBJECTIVECTYPE_UINT32: + case OBJECTIVECTYPE_INT64: + case OBJECTIVECTYPE_UINT64: + case OBJECTIVECTYPE_FLOAT: + case OBJECTIVECTYPE_DOUBLE: + case OBJECTIVECTYPE_BOOLEAN: + case OBJECTIVECTYPE_ENUM: + return true; + break; + default: + return false; + } +} + +bool IsReferenceType(const FieldDescriptor* field) { + return !IsPrimitiveType(field); +} + +static TProtoStringType HandleExtremeFloatingPoint(TProtoStringType val, + bool add_float_suffix) { + if (val == "nan") { + return "NAN"; + } else if (val == "inf") { + return "INFINITY"; + } else if (val == "-inf") { + return "-INFINITY"; + } else { + // float strings with ., e or E need to have f appended + if (add_float_suffix && (val.find(".") != TProtoStringType::npos || + val.find("e") != TProtoStringType::npos || + val.find("E") != TProtoStringType::npos)) { + val += "f"; + } + return val; + } +} + +TProtoStringType GPBGenericValueFieldName(const FieldDescriptor* field) { + // Returns the field within the GPBGenericValue union to use for the given + // field. + if (field->is_repeated()) { + return "valueMessage"; + } + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + return "valueInt32"; + case FieldDescriptor::CPPTYPE_UINT32: + return "valueUInt32"; + case FieldDescriptor::CPPTYPE_INT64: + return "valueInt64"; + case FieldDescriptor::CPPTYPE_UINT64: + return "valueUInt64"; + case FieldDescriptor::CPPTYPE_FLOAT: + return "valueFloat"; + case FieldDescriptor::CPPTYPE_DOUBLE: + return "valueDouble"; + case FieldDescriptor::CPPTYPE_BOOL: + return "valueBool"; + case FieldDescriptor::CPPTYPE_STRING: + if (field->type() == FieldDescriptor::TYPE_BYTES) { + return "valueData"; + } else { + return "valueString"; + } + case FieldDescriptor::CPPTYPE_ENUM: + return "valueEnum"; + case FieldDescriptor::CPPTYPE_MESSAGE: + return "valueMessage"; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return TProtoStringType(); +} + + +TProtoStringType DefaultValue(const FieldDescriptor* field) { + // Repeated fields don't have defaults. + if (field->is_repeated()) { + return "nil"; + } + + // Switch on cpp_type since we need to know which default_value_* method + // of FieldDescriptor to call. + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_INT32: + // gcc and llvm reject the decimal form of kint32min and kint64min. + if (field->default_value_int32() == INT_MIN) { + return "-0x80000000"; + } + return StrCat(field->default_value_int32()); + case FieldDescriptor::CPPTYPE_UINT32: + return StrCat(field->default_value_uint32()) + "U"; + case FieldDescriptor::CPPTYPE_INT64: + // gcc and llvm reject the decimal form of kint32min and kint64min. + if (field->default_value_int64() == LLONG_MIN) { + return "-0x8000000000000000LL"; + } + return StrCat(field->default_value_int64()) + "LL"; + case FieldDescriptor::CPPTYPE_UINT64: + return StrCat(field->default_value_uint64()) + "ULL"; + case FieldDescriptor::CPPTYPE_DOUBLE: + return HandleExtremeFloatingPoint( + SimpleDtoa(field->default_value_double()), false); + case FieldDescriptor::CPPTYPE_FLOAT: + return HandleExtremeFloatingPoint( + SimpleFtoa(field->default_value_float()), true); + case FieldDescriptor::CPPTYPE_BOOL: + return field->default_value_bool() ? "YES" : "NO"; + case FieldDescriptor::CPPTYPE_STRING: { + const bool has_default_value = field->has_default_value(); + const TProtoStringType& default_string = field->default_value_string(); + if (!has_default_value || default_string.length() == 0) { + // If the field is defined as being the empty string, + // then we will just assign to nil, as the empty string is the + // default for both strings and data. + return "nil"; + } + if (field->type() == FieldDescriptor::TYPE_BYTES) { + // We want constant fields in our data structures so we can + // declare them as static. To achieve this we cheat and stuff + // a escaped c string (prefixed with a length) into the data + // field, and cast it to an (NSData*) so it will compile. + // The runtime library knows how to handle it. + + // Must convert to a standard byte order for packing length into + // a cstring. + uint32 length = ghtonl(default_string.length()); + TProtoStringType bytes((const char*)&length, sizeof(length)); + bytes.append(default_string); + return "(NSData*)\"" + EscapeTrigraphs(CEscape(bytes)) + "\""; + } else { + return "@\"" + EscapeTrigraphs(CEscape(default_string)) + "\""; + } + } + case FieldDescriptor::CPPTYPE_ENUM: + return EnumValueName(field->default_value_enum()); + case FieldDescriptor::CPPTYPE_MESSAGE: + return "nil"; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return TProtoStringType(); +} + +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. + GOOGLE_LOG(FATAL) << "Can't get here."; + return false; +} + +TProtoStringType BuildFlagsString(const FlagType flag_type, + const std::vector<TProtoStringType>& strings) { + if (strings.empty()) { + return GetZeroEnumNameForFlagType(flag_type); + } else if (strings.size() == 1) { + return strings[0]; + } + TProtoStringType string("(" + GetEnumNameForFlagType(flag_type) + ")("); + for (size_t i = 0; i != strings.size(); ++i) { + if (i > 0) { + string.append(" | "); + } + string.append(strings[i]); + } + string.append(")"); + return string; +} + +TProtoStringType BuildCommentsString(const SourceLocation& location, + bool prefer_single_line) { + const TProtoStringType& comments = location.leading_comments.empty() + ? location.trailing_comments + : location.leading_comments; + std::vector<TProtoStringType> lines; + lines = Split(comments, "\n", false); + while (!lines.empty() && lines.back().empty()) { + lines.pop_back(); + } + // If there are no comments, just return an empty string. + if (lines.empty()) { + return ""; + } + + TProtoStringType prefix; + TProtoStringType suffix; + TProtoStringType final_comments; + TProtoStringType epilogue; + + bool add_leading_space = false; + + if (prefer_single_line && lines.size() == 1) { + prefix = "/** "; + suffix = " */\n"; + } else { + prefix = "* "; + suffix = "\n"; + final_comments += "/**\n"; + epilogue = " **/\n"; + add_leading_space = true; + } + + for (int i = 0; i < lines.size(); i++) { + TProtoStringType line = StripPrefixString(lines[i], " "); + // HeaderDoc and appledoc use '\' and '@' for markers; escape them. + line = StringReplace(line, "\\", "\\\\", true); + line = StringReplace(line, "@", "\\@", true); + // Decouple / from * to not have inline comments inside comments. + line = StringReplace(line, "/*", "/\\*", true); + line = StringReplace(line, "*/", "*\\/", true); + line = prefix + line; + StripWhitespace(&line); + // If not a one line, need to add the first space before *, as + // StripWhitespace would have removed it. + line = (add_leading_space ? " " : "") + line; + final_comments += line + suffix; + } + final_comments += epilogue; + return final_comments; +} + +// Making these a generator option for folks that don't use CocoaPods, but do +// want to put the library in a framework is an interesting question. The +// problem is it means changing sources shipped with the library to actually +// use a different value; so it isn't as simple as a option. +const char* const ProtobufLibraryFrameworkName = "Protobuf"; + +TProtoStringType ProtobufFrameworkImportSymbol(const TProtoStringType& framework_name) { + // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS + TProtoStringType result = TProtoStringType("GPB_USE_"); + result += ToUpper(framework_name); + result += "_FRAMEWORK_IMPORTS"; + return result; +} + +bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file) { + // We don't check the name prefix or proto package because some files + // (descriptor.proto), aren't shipped generated by the library, so this + // seems to be the safest way to only catch the ones shipped. + const TProtoStringType name = file->name(); + if (name == "google/protobuf/any.proto" || + name == "google/protobuf/api.proto" || + name == "google/protobuf/duration.proto" || + name == "google/protobuf/empty.proto" || + name == "google/protobuf/field_mask.proto" || + name == "google/protobuf/source_context.proto" || + name == "google/protobuf/struct.proto" || + name == "google/protobuf/timestamp.proto" || + name == "google/protobuf/type.proto" || + name == "google/protobuf/wrappers.proto") { + return true; + } + return false; +} + +bool ReadLine(StringPiece* input, StringPiece* line) { + for (int len = 0; len < input->size(); ++len) { + if (ascii_isnewline((*input)[len])) { + *line = StringPiece(input->data(), len); + ++len; // advance over the newline + *input = StringPiece(input->data() + len, input->size() - len); + return true; + } + } + return false; // Ran out of input with no newline. +} + +void RemoveComment(StringPiece* input) { + int offset = input->find('#'); + if (offset != StringPiece::npos) { + input->remove_suffix(input->length() - offset); + } +} + +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); + + private: + std::map<TProtoStringType, TProtoStringType>* prefix_map_; +}; + +bool ExpectedPrefixesCollector::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) + "'."; + return false; + } + StringPiece package = line.substr(0, offset); + StringPiece prefix = line.substr(offset + 1); + TrimWhitespace(&package); + TrimWhitespace(&prefix); + // Don't really worry about error checking the package/prefix for + // being valid. Assume the file is validated when it is created/edited. + (*prefix_map_)[TProtoStringType(package)] = TProtoStringType(prefix); + return true; +} + +bool LoadExpectedPackagePrefixes(const Options& generation_options, + std::map<TProtoStringType, TProtoStringType>* prefix_map, + TProtoStringType* out_error) { + if (generation_options.expected_prefixes_path.empty()) { + return true; + } + + ExpectedPrefixesCollector collector(prefix_map); + return ParseSimpleFile( + generation_options.expected_prefixes_path, &collector, out_error); +} + +bool ValidateObjCClassPrefix( + const FileDescriptor* file, const TProtoStringType& expected_prefixes_path, + const std::map<TProtoStringType, TProtoStringType>& expected_package_prefixes, + TProtoStringType* out_error) { + const TProtoStringType prefix = file->options().objc_class_prefix(); + const TProtoStringType package = file->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. + + // 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); + if (package_match != expected_package_prefixes.end()) { + // There was an entry, and... + if (package_match->second == prefix) { + // ...it matches. All good, out of here! + return true; + } else { + // ...it didn't match! + *out_error = "error: Expected 'option objc_class_prefix = \"" + + package_match->second + "\";' for package '" + package + + "' in '" + file->name() + "'"; + if (prefix.length()) { + *out_error += "; but found '" + prefix + "' instead"; + } + *out_error += "."; + return false; + } + } + + // If there was no prefix option, we're done at this point. + if (prefix.empty()) { + // No prefix, nothing left to check. + return true; + } + + // Check: Warning - Make sure the prefix is is a reasonable value according + // to Apple's rules (the checks above implicitly whitelist anything that + // doesn't meet these rules). + if (!ascii_isupper(prefix[0])) { + std::cerr + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " it should start with a capital letter." << std::endl; + std::cerr.flush(); + } + if (prefix.length() < 3) { + // Apple reserves 2 character prefixes for themselves. They do use some + // 3 character prefixes, but they haven't updated the rules/docs. + std::cerr + << "protoc:0: warning: Invalid 'option objc_class_prefix = \"" + << prefix << "\";' in '" << file->name() << "';" + << " Apple recommends they should be at least 3 characters long." + << std::endl; + std::cerr.flush(); + } + + // Look for any other package that uses the same prefix. + TProtoStringType other_package_for_prefix; + for (std::map<TProtoStringType, TProtoStringType>::const_iterator i = + expected_package_prefixes.begin(); + 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 declared is being used by another package or not. + 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(); + } + return true; + } + + // Check: Error - Make sure the prefix wasn't expected for a different + // package (overlap is allowed, but it has to be listed as an expected + // overlap). + 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 + ")."; + return false; // Only report first usage of the prefix. + } + + // Check: Warning - If the given package/prefix pair wasn't expected, issue a + // warning issue a warning suggesting it gets added to the file. + if (!expected_package_prefixes.empty()) { + 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; + std::cerr.flush(); + } + + return true; +} + +} // namespace + +bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files, + const Options& generation_options, + TProtoStringType* out_error) { + // Load the expected package prefixes, if available, to validate against. + std::map<TProtoStringType, TProtoStringType> expected_package_prefixes; + if (!LoadExpectedPackagePrefixes(generation_options, + &expected_package_prefixes, + out_error)) { + return false; + } + + for (int i = 0; i < files.size(); i++) { + bool should_skip = + (std::find(generation_options.expected_prefixes_suppressions.begin(), + generation_options.expected_prefixes_suppressions.end(), + files[i]->name()) + != generation_options.expected_prefixes_suppressions.end()); + if (should_skip) { + continue; + } + + bool is_valid = + ValidateObjCClassPrefix(files[i], + generation_options.expected_prefixes_path, + expected_package_prefixes, + out_error); + if (!is_valid) { + return false; + } + } + return true; +} + +TextFormatDecodeData::TextFormatDecodeData() { } + +TextFormatDecodeData::~TextFormatDecodeData() { } + +void TextFormatDecodeData::AddString(int32 key, + const TProtoStringType& input_for_decode, + const TProtoStringType& desired_output) { + for (std::vector<DataEntry>::const_iterator i = entries_.begin(); + i != entries_.end(); ++i) { + if (i->first == key) { + std::cerr << "error: duplicate key (" << key + << ") making TextFormat data, input: \"" << input_for_decode + << "\", desired: \"" << desired_output << "\"." << std::endl; + std::cerr.flush(); + abort(); + } + } + + const TProtoStringType& data = TextFormatDecodeData::DecodeDataForString( + input_for_decode, desired_output); + entries_.push_back(DataEntry(key, data)); +} + +TProtoStringType TextFormatDecodeData::Data() const { + std::ostringstream data_stringstream; + + if (num_entries() > 0) { + io::OstreamOutputStream data_outputstream(&data_stringstream); + io::CodedOutputStream output_stream(&data_outputstream); + + output_stream.WriteVarint32(num_entries()); + for (std::vector<DataEntry>::const_iterator i = entries_.begin(); + i != entries_.end(); ++i) { + output_stream.WriteVarint32(i->first); + output_stream.WriteString(i->second); + } + } + + data_stringstream.flush(); + return TProtoStringType{data_stringstream.str()}; +} + +namespace { + +// Helper to build up the decode data for a string. +class DecodeDataBuilder { + public: + DecodeDataBuilder() { Reset(); } + + bool AddCharacter(const char desired, const char input); + void AddUnderscore() { + Push(); + need_underscore_ = true; + } + TProtoStringType Finish() { + Push(); + return decode_data_; + } + + private: + static constexpr uint8 kAddUnderscore = 0x80; + + static constexpr uint8 kOpAsIs = 0x00; + static constexpr uint8 kOpFirstUpper = 0x40; + static constexpr uint8 kOpFirstLower = 0x20; + static constexpr uint8 kOpAllUpper = 0x60; + + static constexpr int kMaxSegmentLen = 0x1f; + + void AddChar(const char desired) { + ++segment_len_; + is_all_upper_ &= ascii_isupper(desired); + } + + void Push() { + uint8 op = (op_ | segment_len_); + if (need_underscore_) op |= kAddUnderscore; + if (op != 0) { + decode_data_ += (char)op; + } + Reset(); + } + + bool AddFirst(const char desired, const char input) { + if (desired == input) { + op_ = kOpAsIs; + } else if (desired == ascii_toupper(input)) { + op_ = kOpFirstUpper; + } else if (desired == ascii_tolower(input)) { + op_ = kOpFirstLower; + } else { + // Can't be transformed to match. + return false; + } + AddChar(desired); + return true; + } + + void Reset() { + need_underscore_ = false; + op_ = 0; + segment_len_ = 0; + is_all_upper_ = true; + } + + bool need_underscore_; + bool is_all_upper_; + uint8 op_; + int segment_len_; + + TProtoStringType decode_data_; +}; + +bool DecodeDataBuilder::AddCharacter(const char desired, const char input) { + // If we've hit the max size, push to start a new segment. + if (segment_len_ == kMaxSegmentLen) { + Push(); + } + if (segment_len_ == 0) { + return AddFirst(desired, input); + } + + // Desired and input match... + if (desired == input) { + // If we aren't transforming it, or we're upper casing it and it is + // supposed to be uppercase; just add it to the segment. + if ((op_ != kOpAllUpper) || ascii_isupper(desired)) { + AddChar(desired); + return true; + } + + // Add the current segment, and start the next one. + Push(); + return AddFirst(desired, input); + } + + // If we need to uppercase, and everything so far has been uppercase, + // promote op to AllUpper. + if ((desired == ascii_toupper(input)) && is_all_upper_) { + op_ = kOpAllUpper; + AddChar(desired); + return true; + } + + // Give up, push and start a new segment. + Push(); + return AddFirst(desired, input); +} + +// If decode data can't be generated, a directive for the raw string +// is used instead. +TProtoStringType DirectDecodeString(const TProtoStringType& str) { + TProtoStringType result; + result += (char)'\0'; // Marker for full string. + result += str; + result += (char)'\0'; // End of string. + return result; +} + +} // namespace + +// static +TProtoStringType TextFormatDecodeData::DecodeDataForString( + const TProtoStringType& input_for_decode, const TProtoStringType& desired_output) { + if (input_for_decode.empty() || desired_output.empty()) { + std::cerr << "error: got empty string for making TextFormat data, input: \"" + << input_for_decode << "\", desired: \"" << desired_output << "\"." + << std::endl; + std::cerr.flush(); + abort(); + } + if ((input_for_decode.find('\0') != TProtoStringType::npos) || + (desired_output.find('\0') != TProtoStringType::npos)) { + std::cerr << "error: got a null char in a string for making TextFormat data," + << " input: \"" << CEscape(input_for_decode) << "\", desired: \"" + << CEscape(desired_output) << "\"." << std::endl; + std::cerr.flush(); + abort(); + } + + DecodeDataBuilder builder; + + // Walk the output building it from the input. + int x = 0; + for (int y = 0; y < desired_output.size(); y++) { + const char d = desired_output[y]; + if (d == '_') { + builder.AddUnderscore(); + continue; + } + + if (x >= input_for_decode.size()) { + // Out of input, no way to encode it, just return a full decode. + return DirectDecodeString(desired_output); + } + if (builder.AddCharacter(d, input_for_decode[x])) { + ++x; // Consumed one input + } else { + // Couldn't transform for the next character, just return a full decode. + return DirectDecodeString(desired_output); + } + } + + if (x != input_for_decode.size()) { + // Extra input (suffix from name sanitizing?), just return a full decode. + return DirectDecodeString(desired_output); + } + + // Add the end marker. + return builder.Finish() + (char)'\0'; +} + +namespace { + +class Parser { + public: + Parser(LineConsumer* line_consumer) + : line_consumer_(line_consumer), line_(0) {} + + // Parses a check of input, returning success/failure. + bool ParseChunk(StringPiece chunk); + + // Should be called to finish parsing (after all input has been provided via + // ParseChunk()). Returns success/failure. + bool Finish(); + + int last_line() const { return line_; } + TProtoStringType error_str() const { return error_str_; } + + private: + bool ParseLoop(); + + LineConsumer* line_consumer_; + int line_; + TProtoStringType error_str_; + StringPiece p_; + TProtoStringType leftover_; +}; + +bool Parser::ParseChunk(StringPiece chunk) { + if (!leftover_.empty()) { + leftover_ += TProtoStringType(chunk); + p_ = StringPiece(leftover_); + } else { + p_ = chunk; + } + bool result = ParseLoop(); + if (p_.empty()) { + leftover_.clear(); + } else { + leftover_ = TProtoStringType(p_); + } + return result; +} + +bool Parser::Finish() { + if (leftover_.empty()) { + return true; + } + // Force a newline onto the end to finish parsing. + leftover_ += "\n"; + p_ = StringPiece(leftover_); + if (!ParseLoop()) { + return false; + } + return p_.empty(); // Everything used? +} + +bool Parser::ParseLoop() { + StringPiece line; + while (ReadLine(&p_, &line)) { + ++line_; + RemoveComment(&line); + TrimWhitespace(&line); + if (line.empty()) { + continue; // Blank line. + } + if (!line_consumer_->ConsumeLine(line, &error_str_)) { + return false; + } + } + return true; +} + +} // namespace + +LineConsumer::LineConsumer() {} + +LineConsumer::~LineConsumer() {} + +bool ParseSimpleFile(const TProtoStringType& path, LineConsumer* line_consumer, + TProtoStringType* out_error) { + int fd; + do { + fd = posix::open(path.c_str(), O_RDONLY); + } while (fd < 0 && errno == EINTR); + if (fd < 0) { + *out_error = TProtoStringType("error: Unable to open \"") + path + "\", " + + strerror(errno); + return false; + } + io::FileInputStream file_stream(fd); + file_stream.SetCloseOnDelete(true); + + Parser parser(line_consumer); + const void* buf; + int buf_len; + while (file_stream.Next(&buf, &buf_len)) { + if (buf_len == 0) { + continue; + } + + if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len))) { + *out_error = + TProtoStringType("error: ") + path + + " Line " + StrCat(parser.last_line()) + ", " + parser.error_str(); + return false; + } + } + return parser.Finish(); +} + +ImportWriter::ImportWriter( + const TProtoStringType& generate_for_named_framework, + const TProtoStringType& named_framework_to_proto_path_mappings_path, + const TProtoStringType& runtime_import_prefix, bool include_wkt_imports) + : generate_for_named_framework_(generate_for_named_framework), + named_framework_to_proto_path_mappings_path_( + named_framework_to_proto_path_mappings_path), + runtime_import_prefix_(runtime_import_prefix), + include_wkt_imports_(include_wkt_imports), + need_to_parse_mapping_file_(true) {} + +ImportWriter::~ImportWriter() {} + +void ImportWriter::AddFile(const FileDescriptor* file, + const TProtoStringType& header_extension) { + if (IsProtobufLibraryBundledProtoFile(file)) { + // The imports of the WKTs are only needed within the library itself, + // in other cases, they get skipped because the generated code already + // import GPBProtocolBuffers.h and hence proves them. + if (include_wkt_imports_) { + const TProtoStringType header_name = + "GPB" + FilePathBasename(file) + header_extension; + protobuf_imports_.push_back(header_name); + } + return; + } + + // Lazy parse any mappings. + if (need_to_parse_mapping_file_) { + ParseFrameworkMappings(); + } + + std::map<TProtoStringType, TProtoStringType>::iterator proto_lookup = + proto_file_to_framework_name_.find(file->name()); + if (proto_lookup != proto_file_to_framework_name_.end()) { + other_framework_imports_.push_back( + proto_lookup->second + "/" + + FilePathBasename(file) + header_extension); + return; + } + + if (!generate_for_named_framework_.empty()) { + other_framework_imports_.push_back( + generate_for_named_framework_ + "/" + + FilePathBasename(file) + header_extension); + return; + } + + other_imports_.push_back(FilePath(file) + header_extension); +} + +void ImportWriter::Print(io::Printer* printer) const { + bool add_blank_line = false; + + if (!protobuf_imports_.empty()) { + PrintRuntimeImports(printer, protobuf_imports_, runtime_import_prefix_); + add_blank_line = true; + } + + if (!other_framework_imports_.empty()) { + if (add_blank_line) { + printer->Print("\n"); + } + + for (std::vector<TProtoStringType>::const_iterator iter = + other_framework_imports_.begin(); + iter != other_framework_imports_.end(); ++iter) { + printer->Print( + "#import <$header$>\n", + "header", *iter); + } + + add_blank_line = true; + } + + if (!other_imports_.empty()) { + if (add_blank_line) { + printer->Print("\n"); + } + + for (std::vector<TProtoStringType>::const_iterator iter = other_imports_.begin(); + iter != other_imports_.end(); ++iter) { + printer->Print( + "#import \"$header$\"\n", + "header", *iter); + } + } +} + +void ImportWriter::PrintRuntimeImports( + io::Printer* printer, const std::vector<TProtoStringType>& header_to_import, + const TProtoStringType& runtime_import_prefix, bool default_cpp_symbol) { + // Given an override, use that. + if (!runtime_import_prefix.empty()) { + for (const auto& header : header_to_import) { + printer->Print( + " #import \"$import_prefix$/$header$\"\n", + "import_prefix", runtime_import_prefix, + "header", header); + } + return; + } + + const TProtoStringType framework_name(ProtobufLibraryFrameworkName); + const TProtoStringType cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + + if (default_cpp_symbol) { + printer->Print( + "// This CPP symbol can be defined to use imports that match up to the framework\n" + "// imports needed when using CocoaPods.\n" + "#if !defined($cpp_symbol$)\n" + " #define $cpp_symbol$ 0\n" + "#endif\n" + "\n", + "cpp_symbol", cpp_symbol); + } + + printer->Print( + "#if $cpp_symbol$\n", + "cpp_symbol", cpp_symbol); + for (const auto& header : header_to_import) { + printer->Print( + " #import <$framework_name$/$header$>\n", + "framework_name", framework_name, + "header", header); + } + printer->Print( + "#else\n"); + for (const auto& header : header_to_import) { + printer->Print( + " #import \"$header$\"\n", + "header", header); + } + printer->Print( + "#endif\n"); +} + +void ImportWriter::ParseFrameworkMappings() { + need_to_parse_mapping_file_ = false; + if (named_framework_to_proto_path_mappings_path_.empty()) { + return; // Nothing to do. + } + + ProtoFrameworkCollector collector(&proto_file_to_framework_name_); + TProtoStringType parse_error; + if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_, + &collector, &parse_error)) { + std::cerr << "error parsing " << named_framework_to_proto_path_mappings_path_ + << " : " << parse_error << std::endl; + std::cerr.flush(); + } +} + +bool ImportWriter::ProtoFrameworkCollector::ConsumeLine( + const StringPiece& line, TProtoStringType* out_error) { + int offset = line.find(':'); + if (offset == StringPiece::npos) { + *out_error = + TProtoStringType("Framework/proto file mapping line without colon sign: '") + + TProtoStringType(line) + "'."; + return false; + } + StringPiece framework_name = line.substr(0, offset); + StringPiece proto_file_list = line.substr(offset + 1); + TrimWhitespace(&framework_name); + + int start = 0; + while (start < proto_file_list.length()) { + offset = proto_file_list.find(',', start); + if (offset == StringPiece::npos) { + offset = proto_file_list.length(); + } + + StringPiece proto_file = proto_file_list.substr(start, offset - start); + TrimWhitespace(&proto_file); + if (!proto_file.empty()) { + std::map<TProtoStringType, TProtoStringType>::iterator existing_entry = + map_->find(TProtoStringType(proto_file)); + if (existing_entry != map_->end()) { + std::cerr << "warning: duplicate proto file reference, replacing " + "framework entry for '" + << TProtoStringType(proto_file) << "' with '" << TProtoStringType(framework_name) + << "' (was '" << existing_entry->second << "')." << std::endl; + std::cerr.flush(); + } + + if (proto_file.find(' ') != StringPiece::npos) { + std::cerr << "note: framework mapping file had a proto file with a " + "space in, hopefully that isn't a missing comma: '" + << TProtoStringType(proto_file) << "'" << std::endl; + std::cerr.flush(); + } + + (*map_)[TProtoStringType(proto_file)] = TProtoStringType(framework_name); + } + + start = offset + 1; + } + + return true; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 9fb24936c2..9f5f085431 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 @@ -1,326 +1,326 @@ -// 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. - -// Helper functions for generating ObjectiveC code. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ - -#include <string> -#include <vector> - -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> - -#include <google/protobuf/port_def.inc> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -// Generator 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; -}; - -// Escape C++ trigraphs by escaping question marks to "\?". -TProtoStringType PROTOC_EXPORT EscapeTrigraphs(const TProtoStringType& to_escape); - -// Remove white space from either end of a StringPiece. -void PROTOC_EXPORT TrimWhitespace(StringPiece* input); - -// Returns true if the name requires a ns_returns_not_retained attribute applied -// to it. -bool PROTOC_EXPORT IsRetainedName(const TProtoStringType& name); - -// Returns true if the name starts with "init" and will need to have special -// handling under ARC. -bool PROTOC_EXPORT IsInitName(const TProtoStringType& name); - -// Gets the objc_class_prefix. -TProtoStringType PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); - -// Gets the path of the file we're going to generate (sans the .pb.h -// extension). The path will be dependent on the objectivec package -// declared in the proto package. -TProtoStringType PROTOC_EXPORT FilePath(const FileDescriptor* file); - -// Just like FilePath(), but without the directory part. -TProtoStringType PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); - -// Gets the name of the root class we'll generate in the file. This class -// is not meant for external consumption, but instead contains helpers that -// the rest of the classes need -TProtoStringType PROTOC_EXPORT FileClassName(const FileDescriptor* file); - -// These return the fully-qualified class name corresponding to the given -// descriptor. -TProtoStringType PROTOC_EXPORT ClassName(const Descriptor* descriptor); -TProtoStringType PROTOC_EXPORT ClassName(const Descriptor* descriptor, - TProtoStringType* out_suffix_added); -TProtoStringType PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); - -// Returns the fully-qualified name of the enum value corresponding to the -// the descriptor. -TProtoStringType PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); - -// Returns the name of the enum value corresponding to the descriptor. -TProtoStringType PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); - -// Reverse what an enum does. -TProtoStringType PROTOC_EXPORT UnCamelCaseEnumShortName(const TProtoStringType& name); - -// Returns the name to use for the extension (used as the method off the file's -// Root class). -TProtoStringType PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); - -// Returns the transformed field name. -TProtoStringType PROTOC_EXPORT FieldName(const FieldDescriptor* field); -TProtoStringType PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); - -// Returns the transformed oneof name. -TProtoStringType PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); -TProtoStringType PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); -TProtoStringType PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); - -// Returns a symbol that can be used in C code to refer to an Objective C -// class without initializing the class. -TProtoStringType PROTOC_EXPORT ObjCClass(const TProtoStringType& class_name); - -// Declares an Objective C class without initializing the class so that it can -// be refrerred to by ObjCClass. -TProtoStringType PROTOC_EXPORT ObjCClassDeclaration(const TProtoStringType& class_name); - -inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { - return file->syntax() == FileDescriptor::SYNTAX_PROTO3; -} - -inline bool IsMapEntryMessage(const Descriptor* descriptor) { - return descriptor->options().map_entry(); -} - -// Reverse of the above. -TProtoStringType PROTOC_EXPORT UnCamelCaseFieldName(const TProtoStringType& name, - const FieldDescriptor* field); - -enum ObjectiveCType { - OBJECTIVECTYPE_INT32, - OBJECTIVECTYPE_UINT32, - OBJECTIVECTYPE_INT64, - OBJECTIVECTYPE_UINT64, - OBJECTIVECTYPE_FLOAT, - OBJECTIVECTYPE_DOUBLE, - OBJECTIVECTYPE_BOOLEAN, - OBJECTIVECTYPE_STRING, - OBJECTIVECTYPE_DATA, - OBJECTIVECTYPE_ENUM, - OBJECTIVECTYPE_MESSAGE -}; - -enum FlagType { - FLAGTYPE_DESCRIPTOR_INITIALIZATION, - FLAGTYPE_EXTENSION, - FLAGTYPE_FIELD -}; - -template <class TDescriptor> -TProtoStringType GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, - const FileDescriptor* file = NULL, - bool preSpace = true, - bool postNewline = false) { - bool isDeprecated = descriptor->options().deprecated(); - // The file is only passed when checking Messages & Enums, so those types - // get tagged. At the moment, it doesn't seem to make sense to tag every - // field or enum value with when the file is deprecated. - bool isFileLevelDeprecation = false; - if (!isDeprecated && file) { - isFileLevelDeprecation = file->options().deprecated(); - isDeprecated = isFileLevelDeprecation; - } - if (isDeprecated) { - TProtoStringType message; - const FileDescriptor* sourceFile = descriptor->file(); - if (isFileLevelDeprecation) { - message = sourceFile->name() + " is deprecated."; - } else { - message = descriptor->full_name() + " is deprecated (see " + - sourceFile->name() + ")."; - } - - TProtoStringType result = TProtoStringType("GPB_DEPRECATED_MSG(\"") + message + "\")"; - if (preSpace) { - result.insert(0, " "); - } - if (postNewline) { - result.append("\n"); - } - return result; - } else { - return ""; - } -} - -TProtoStringType PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); - -ObjectiveCType PROTOC_EXPORT -GetObjectiveCType(FieldDescriptor::Type field_type); - -inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { - return GetObjectiveCType(field->type()); -} - -bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field); -bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field); - -TProtoStringType PROTOC_EXPORT -GPBGenericValueFieldName(const FieldDescriptor* field); -TProtoStringType PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); -bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field); - -TProtoStringType PROTOC_EXPORT -BuildFlagsString(const FlagType type, const std::vector<TProtoStringType>& strings); - -// Builds HeaderDoc/appledoc style comments out of the comments in the .proto -// file. -TProtoStringType PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, - bool prefer_single_line); - -// The name the commonly used by the library when built as a framework. -// This lines up to the name used in the CocoaPod. -extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; -// Returns the CPP symbol name to use as the gate for framework style imports -// for the given framework name to use. -TProtoStringType PROTOC_EXPORT -ProtobufFrameworkImportSymbol(const TProtoStringType& framework_name); - -// Checks if the file is one of the proto's bundled with the library. -bool PROTOC_EXPORT -IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); - -// Checks the prefix for the given files and outputs any warnings as needed. If -// there are flat out errors, then out_error is filled in with the first error -// and the result is false. -bool PROTOC_EXPORT ValidateObjCClassPrefixes( - const std::vector<const FileDescriptor*>& files, - const Options& generation_options, TProtoStringType* out_error); - -// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform -// the input into the expected output. -class PROTOC_EXPORT TextFormatDecodeData { - public: - TextFormatDecodeData(); - ~TextFormatDecodeData(); - - TextFormatDecodeData(const TextFormatDecodeData&) = delete; - TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete; - - void AddString(int32 key, const TProtoStringType& input_for_decode, - const TProtoStringType& desired_output); - size_t num_entries() const { return entries_.size(); } - TProtoStringType Data() const; - - static TProtoStringType DecodeDataForString(const TProtoStringType& input_for_decode, - const TProtoStringType& desired_output); - - private: - typedef std::pair<int32, TProtoStringType> DataEntry; - std::vector<DataEntry> entries_; -}; - -// Helper for parsing simple files. -class PROTOC_EXPORT LineConsumer { - public: - LineConsumer(); - virtual ~LineConsumer(); - virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) = 0; -}; - -bool PROTOC_EXPORT ParseSimpleFile(const TProtoStringType& path, - LineConsumer* line_consumer, - TProtoStringType* out_error); - -// Helper class for parsing framework import mappings and generating -// import statements. -class PROTOC_EXPORT ImportWriter { - public: - ImportWriter(const TProtoStringType& generate_for_named_framework, - const TProtoStringType& named_framework_to_proto_path_mappings_path, - const TProtoStringType& runtime_import_prefix, - bool include_wkt_imports); - ~ImportWriter(); - - void AddFile(const FileDescriptor* file, const TProtoStringType& header_extension); - void Print(io::Printer* printer) const; - - static void PrintRuntimeImports(io::Printer* printer, - const std::vector<TProtoStringType>& header_to_import, - const TProtoStringType& runtime_import_prefix, - bool default_cpp_symbol = false); - - private: - class ProtoFrameworkCollector : public LineConsumer { - public: - ProtoFrameworkCollector(std::map<TProtoStringType, TProtoStringType>* inout_proto_file_to_framework_name) - : map_(inout_proto_file_to_framework_name) {} - - virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error); - - private: - std::map<TProtoStringType, TProtoStringType>* map_; - }; - - void ParseFrameworkMappings(); - - const TProtoStringType generate_for_named_framework_; - const TProtoStringType named_framework_to_proto_path_mappings_path_; - const TProtoStringType runtime_import_prefix_; - const bool include_wkt_imports_; - std::map<TProtoStringType, TProtoStringType> proto_file_to_framework_name_; - bool need_to_parse_mapping_file_; - - std::vector<TProtoStringType> protobuf_imports_; - std::vector<TProtoStringType> other_framework_imports_; - std::vector<TProtoStringType> other_imports_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#include <google/protobuf/port_undef.inc> - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ +// 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. + +// Helper functions for generating ObjectiveC code. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ + +#include <string> +#include <vector> + +#include <google/protobuf/descriptor.h> +#include <google/protobuf/descriptor.pb.h> + +#include <google/protobuf/port_def.inc> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// Generator 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; +}; + +// Escape C++ trigraphs by escaping question marks to "\?". +TProtoStringType PROTOC_EXPORT EscapeTrigraphs(const TProtoStringType& to_escape); + +// Remove white space from either end of a StringPiece. +void PROTOC_EXPORT TrimWhitespace(StringPiece* input); + +// Returns true if the name requires a ns_returns_not_retained attribute applied +// to it. +bool PROTOC_EXPORT IsRetainedName(const TProtoStringType& name); + +// Returns true if the name starts with "init" and will need to have special +// handling under ARC. +bool PROTOC_EXPORT IsInitName(const TProtoStringType& name); + +// Gets the objc_class_prefix. +TProtoStringType PROTOC_EXPORT FileClassPrefix(const FileDescriptor* file); + +// Gets the path of the file we're going to generate (sans the .pb.h +// extension). The path will be dependent on the objectivec package +// declared in the proto package. +TProtoStringType PROTOC_EXPORT FilePath(const FileDescriptor* file); + +// Just like FilePath(), but without the directory part. +TProtoStringType PROTOC_EXPORT FilePathBasename(const FileDescriptor* file); + +// Gets the name of the root class we'll generate in the file. This class +// is not meant for external consumption, but instead contains helpers that +// the rest of the classes need +TProtoStringType PROTOC_EXPORT FileClassName(const FileDescriptor* file); + +// These return the fully-qualified class name corresponding to the given +// descriptor. +TProtoStringType PROTOC_EXPORT ClassName(const Descriptor* descriptor); +TProtoStringType PROTOC_EXPORT ClassName(const Descriptor* descriptor, + TProtoStringType* out_suffix_added); +TProtoStringType PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor); + +// Returns the fully-qualified name of the enum value corresponding to the +// the descriptor. +TProtoStringType PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor); + +// Returns the name of the enum value corresponding to the descriptor. +TProtoStringType PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor); + +// Reverse what an enum does. +TProtoStringType PROTOC_EXPORT UnCamelCaseEnumShortName(const TProtoStringType& name); + +// Returns the name to use for the extension (used as the method off the file's +// Root class). +TProtoStringType PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor); + +// Returns the transformed field name. +TProtoStringType PROTOC_EXPORT FieldName(const FieldDescriptor* field); +TProtoStringType PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field); + +// Returns the transformed oneof name. +TProtoStringType PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor); +TProtoStringType PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor); +TProtoStringType PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor); + +// Returns a symbol that can be used in C code to refer to an Objective C +// class without initializing the class. +TProtoStringType PROTOC_EXPORT ObjCClass(const TProtoStringType& class_name); + +// Declares an Objective C class without initializing the class so that it can +// be refrerred to by ObjCClass. +TProtoStringType PROTOC_EXPORT ObjCClassDeclaration(const TProtoStringType& class_name); + +inline bool HasPreservingUnknownEnumSemantics(const FileDescriptor* file) { + return file->syntax() == FileDescriptor::SYNTAX_PROTO3; +} + +inline bool IsMapEntryMessage(const Descriptor* descriptor) { + return descriptor->options().map_entry(); +} + +// Reverse of the above. +TProtoStringType PROTOC_EXPORT UnCamelCaseFieldName(const TProtoStringType& name, + const FieldDescriptor* field); + +enum ObjectiveCType { + OBJECTIVECTYPE_INT32, + OBJECTIVECTYPE_UINT32, + OBJECTIVECTYPE_INT64, + OBJECTIVECTYPE_UINT64, + OBJECTIVECTYPE_FLOAT, + OBJECTIVECTYPE_DOUBLE, + OBJECTIVECTYPE_BOOLEAN, + OBJECTIVECTYPE_STRING, + OBJECTIVECTYPE_DATA, + OBJECTIVECTYPE_ENUM, + OBJECTIVECTYPE_MESSAGE +}; + +enum FlagType { + FLAGTYPE_DESCRIPTOR_INITIALIZATION, + FLAGTYPE_EXTENSION, + FLAGTYPE_FIELD +}; + +template <class TDescriptor> +TProtoStringType GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, + const FileDescriptor* file = NULL, + bool preSpace = true, + bool postNewline = false) { + bool isDeprecated = descriptor->options().deprecated(); + // The file is only passed when checking Messages & Enums, so those types + // get tagged. At the moment, it doesn't seem to make sense to tag every + // field or enum value with when the file is deprecated. + bool isFileLevelDeprecation = false; + if (!isDeprecated && file) { + isFileLevelDeprecation = file->options().deprecated(); + isDeprecated = isFileLevelDeprecation; + } + if (isDeprecated) { + TProtoStringType message; + const FileDescriptor* sourceFile = descriptor->file(); + if (isFileLevelDeprecation) { + message = sourceFile->name() + " is deprecated."; + } else { + message = descriptor->full_name() + " is deprecated (see " + + sourceFile->name() + ")."; + } + + TProtoStringType result = TProtoStringType("GPB_DEPRECATED_MSG(\"") + message + "\")"; + if (preSpace) { + result.insert(0, " "); + } + if (postNewline) { + result.append("\n"); + } + return result; + } else { + return ""; + } +} + +TProtoStringType PROTOC_EXPORT GetCapitalizedType(const FieldDescriptor* field); + +ObjectiveCType PROTOC_EXPORT +GetObjectiveCType(FieldDescriptor::Type field_type); + +inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) { + return GetObjectiveCType(field->type()); +} + +bool PROTOC_EXPORT IsPrimitiveType(const FieldDescriptor* field); +bool PROTOC_EXPORT IsReferenceType(const FieldDescriptor* field); + +TProtoStringType PROTOC_EXPORT +GPBGenericValueFieldName(const FieldDescriptor* field); +TProtoStringType PROTOC_EXPORT DefaultValue(const FieldDescriptor* field); +bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field); + +TProtoStringType PROTOC_EXPORT +BuildFlagsString(const FlagType type, const std::vector<TProtoStringType>& strings); + +// Builds HeaderDoc/appledoc style comments out of the comments in the .proto +// file. +TProtoStringType PROTOC_EXPORT BuildCommentsString(const SourceLocation& location, + bool prefer_single_line); + +// The name the commonly used by the library when built as a framework. +// This lines up to the name used in the CocoaPod. +extern PROTOC_EXPORT const char* const ProtobufLibraryFrameworkName; +// Returns the CPP symbol name to use as the gate for framework style imports +// for the given framework name to use. +TProtoStringType PROTOC_EXPORT +ProtobufFrameworkImportSymbol(const TProtoStringType& framework_name); + +// Checks if the file is one of the proto's bundled with the library. +bool PROTOC_EXPORT +IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); + +// Checks the prefix for the given files and outputs any warnings as needed. If +// there are flat out errors, then out_error is filled in with the first error +// and the result is false. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector<const FileDescriptor*>& files, + const Options& generation_options, TProtoStringType* out_error); + +// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform +// the input into the expected output. +class PROTOC_EXPORT TextFormatDecodeData { + public: + TextFormatDecodeData(); + ~TextFormatDecodeData(); + + TextFormatDecodeData(const TextFormatDecodeData&) = delete; + TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete; + + void AddString(int32 key, const TProtoStringType& input_for_decode, + const TProtoStringType& desired_output); + size_t num_entries() const { return entries_.size(); } + TProtoStringType Data() const; + + static TProtoStringType DecodeDataForString(const TProtoStringType& input_for_decode, + const TProtoStringType& desired_output); + + private: + typedef std::pair<int32, TProtoStringType> DataEntry; + std::vector<DataEntry> entries_; +}; + +// Helper for parsing simple files. +class PROTOC_EXPORT LineConsumer { + public: + LineConsumer(); + virtual ~LineConsumer(); + virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) = 0; +}; + +bool PROTOC_EXPORT ParseSimpleFile(const TProtoStringType& path, + LineConsumer* line_consumer, + TProtoStringType* out_error); + +// Helper class for parsing framework import mappings and generating +// import statements. +class PROTOC_EXPORT ImportWriter { + public: + ImportWriter(const TProtoStringType& generate_for_named_framework, + const TProtoStringType& named_framework_to_proto_path_mappings_path, + const TProtoStringType& runtime_import_prefix, + bool include_wkt_imports); + ~ImportWriter(); + + void AddFile(const FileDescriptor* file, const TProtoStringType& header_extension); + void Print(io::Printer* printer) const; + + static void PrintRuntimeImports(io::Printer* printer, + const std::vector<TProtoStringType>& header_to_import, + const TProtoStringType& runtime_import_prefix, + bool default_cpp_symbol = false); + + private: + class ProtoFrameworkCollector : public LineConsumer { + public: + ProtoFrameworkCollector(std::map<TProtoStringType, TProtoStringType>* inout_proto_file_to_framework_name) + : map_(inout_proto_file_to_framework_name) {} + + virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error); + + private: + std::map<TProtoStringType, TProtoStringType>* map_; + }; + + void ParseFrameworkMappings(); + + const TProtoStringType generate_for_named_framework_; + const TProtoStringType named_framework_to_proto_path_mappings_path_; + const TProtoStringType runtime_import_prefix_; + const bool include_wkt_imports_; + std::map<TProtoStringType, TProtoStringType> proto_file_to_framework_name_; + bool need_to_parse_mapping_file_; + + std::vector<TProtoStringType> protobuf_imports_; + std::vector<TProtoStringType> other_framework_imports_; + std::vector<TProtoStringType> other_imports_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#include <google/protobuf/port_undef.inc> + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__ 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..fcc8a67eee 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 @@ -1,189 +1,189 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2015 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_map_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -// MapFieldGenerator uses RepeatedFieldGenerator as the parent because it -// provides a bunch of things (no has* methods, comments for contained type, -// etc.). - -namespace { - -const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { - ObjectiveCType type = GetObjectiveCType(descriptor); - switch (type) { - case OBJECTIVECTYPE_INT32: - return "Int32"; - case OBJECTIVECTYPE_UINT32: - return "UInt32"; - case OBJECTIVECTYPE_INT64: - return "Int64"; - case OBJECTIVECTYPE_UINT64: - return "UInt64"; - case OBJECTIVECTYPE_FLOAT: - return "Float"; - case OBJECTIVECTYPE_DOUBLE: - return "Double"; - case OBJECTIVECTYPE_BOOLEAN: - return "Bool"; - case OBJECTIVECTYPE_STRING: - return (isKey ? "String" : "Object"); - case OBJECTIVECTYPE_DATA: - return "Object"; - case OBJECTIVECTYPE_ENUM: - return "Enum"; - case OBJECTIVECTYPE_MESSAGE: - return "Object"; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -} // namespace - -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { - 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)); - - // Pull over some variables_ from the value. - variables_["field_type"] = value_field_generator_->variable("field_type"); - variables_["default"] = value_field_generator_->variable("default"); - variables_["default_name"] = value_field_generator_->variable("default_name"); - - // Build custom field flags. - std::vector<TProtoStringType> field_flags; - field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); - // Pull over the current text format custom name values that was calculated. - if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") != - TProtoStringType::npos) { - field_flags.push_back("GPBFieldTextFormatNameCustom"); - } - // Pull over some info from the value's flags. - const TProtoStringType& value_field_flags = - value_field_generator_->variable("fieldflags"); - if (value_field_flags.find("GPBFieldHasDefaultValue") != TProtoStringType::npos) { - field_flags.push_back("GPBFieldHasDefaultValue"); - } - if (value_field_flags.find("GPBFieldHasEnumDescriptor") != - TProtoStringType::npos) { - field_flags.push_back("GPBFieldHasEnumDescriptor"); - } - - variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags); - - ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor); - const bool value_is_object_type = - ((value_objc_type == OBJECTIVECTYPE_STRING) || - (value_objc_type == OBJECTIVECTYPE_DATA) || - (value_objc_type == OBJECTIVECTYPE_MESSAGE)); - if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) && - value_is_object_type) { - variables_["array_storage_type"] = "NSMutableDictionary"; - variables_["array_property_type"] = - "NSMutableDictionary<NSString*, " + - value_field_generator_->variable("storage_type") + "*>"; - } else { - TProtoStringType class_name("GPB"); - class_name += MapEntryTypeName(key_descriptor, true); - class_name += MapEntryTypeName(value_descriptor, false); - class_name += "Dictionary"; - variables_["array_storage_type"] = class_name; - if (value_is_object_type) { - variables_["array_property_type"] = - class_name + "<" + - value_field_generator_->variable("storage_type") + "*>"; - } - } - - variables_["dataTypeSpecific_name"] = - value_field_generator_->variable("dataTypeSpecific_name"); - variables_["dataTypeSpecific_value"] = - value_field_generator_->variable("dataTypeSpecific_value"); -} - -MapFieldGenerator::~MapFieldGenerator() {} - -void MapFieldGenerator::FinishInitialization(void) { - RepeatedFieldGenerator::FinishInitialization(); - // 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"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { - variables_["array_comment"] = - "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; - } -} - -void MapFieldGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const { - RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); - const FieldDescriptor* value_descriptor = - descriptor_->message_type()->FindFieldByName("value"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { - const TProtoStringType& value_storage_type = - value_field_generator_->variable("storage_type"); - fwd_decls->insert("@class " + value_storage_type); - } -} - -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"); - if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { - fwd_decls->insert(ObjCClassDeclaration( - value_field_generator_->variable("storage_type"))); - } -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// Protocol Buffers - Google's data interchange format +// Copyright 2015 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_map_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +// MapFieldGenerator uses RepeatedFieldGenerator as the parent because it +// provides a bunch of things (no has* methods, comments for contained type, +// etc.). + +namespace { + +const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { + ObjectiveCType type = GetObjectiveCType(descriptor); + switch (type) { + case OBJECTIVECTYPE_INT32: + return "Int32"; + case OBJECTIVECTYPE_UINT32: + return "UInt32"; + case OBJECTIVECTYPE_INT64: + return "Int64"; + case OBJECTIVECTYPE_UINT64: + return "UInt64"; + case OBJECTIVECTYPE_FLOAT: + return "Float"; + case OBJECTIVECTYPE_DOUBLE: + return "Double"; + case OBJECTIVECTYPE_BOOLEAN: + return "Bool"; + case OBJECTIVECTYPE_STRING: + return (isKey ? "String" : "Object"); + case OBJECTIVECTYPE_DATA: + return "Object"; + case OBJECTIVECTYPE_ENUM: + return "Enum"; + case OBJECTIVECTYPE_MESSAGE: + return "Object"; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +} // namespace + +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : RepeatedFieldGenerator(descriptor, options) { + 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)); + + // Pull over some variables_ from the value. + variables_["field_type"] = value_field_generator_->variable("field_type"); + variables_["default"] = value_field_generator_->variable("default"); + variables_["default_name"] = value_field_generator_->variable("default_name"); + + // Build custom field flags. + std::vector<TProtoStringType> field_flags; + field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor)); + // Pull over the current text format custom name values that was calculated. + if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") != + TProtoStringType::npos) { + field_flags.push_back("GPBFieldTextFormatNameCustom"); + } + // Pull over some info from the value's flags. + const TProtoStringType& value_field_flags = + value_field_generator_->variable("fieldflags"); + if (value_field_flags.find("GPBFieldHasDefaultValue") != TProtoStringType::npos) { + field_flags.push_back("GPBFieldHasDefaultValue"); + } + if (value_field_flags.find("GPBFieldHasEnumDescriptor") != + TProtoStringType::npos) { + field_flags.push_back("GPBFieldHasEnumDescriptor"); + } + + variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags); + + ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor); + const bool value_is_object_type = + ((value_objc_type == OBJECTIVECTYPE_STRING) || + (value_objc_type == OBJECTIVECTYPE_DATA) || + (value_objc_type == OBJECTIVECTYPE_MESSAGE)); + if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) && + value_is_object_type) { + variables_["array_storage_type"] = "NSMutableDictionary"; + variables_["array_property_type"] = + "NSMutableDictionary<NSString*, " + + value_field_generator_->variable("storage_type") + "*>"; + } else { + TProtoStringType class_name("GPB"); + class_name += MapEntryTypeName(key_descriptor, true); + class_name += MapEntryTypeName(value_descriptor, false); + class_name += "Dictionary"; + variables_["array_storage_type"] = class_name; + if (value_is_object_type) { + variables_["array_property_type"] = + class_name + "<" + + value_field_generator_->variable("storage_type") + "*>"; + } + } + + variables_["dataTypeSpecific_name"] = + value_field_generator_->variable("dataTypeSpecific_name"); + variables_["dataTypeSpecific_value"] = + value_field_generator_->variable("dataTypeSpecific_value"); +} + +MapFieldGenerator::~MapFieldGenerator() {} + +void MapFieldGenerator::FinishInitialization(void) { + RepeatedFieldGenerator::FinishInitialization(); + // 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"); + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) { + variables_["array_comment"] = + "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n"; + } +} + +void MapFieldGenerator::DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const { + RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls); + const FieldDescriptor* value_descriptor = + descriptor_->message_type()->FindFieldByName("value"); + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + const TProtoStringType& value_storage_type = + value_field_generator_->variable("storage_type"); + fwd_decls->insert("@class " + value_storage_type); + } +} + +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"); + if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) { + fwd_decls->insert(ObjCClassDeclaration( + value_field_generator_->variable("storage_type"))); + } +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 48ff7e9162..472b02c2cb 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 @@ -1,71 +1,71 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2015 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - public: - virtual void FinishInitialization(void); - - MapFieldGenerator(const MapFieldGenerator&) = delete; - MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; - - protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); - virtual ~MapFieldGenerator(); - - virtual void DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const; - virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; - - private: - std::unique_ptr<FieldGenerator> value_field_generator_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ +// Protocol Buffers - Google's data interchange format +// Copyright 2015 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class MapFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + public: + virtual void FinishInitialization(void); + + MapFieldGenerator(const MapFieldGenerator&) = delete; + MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; + + protected: + MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + virtual ~MapFieldGenerator(); + + virtual void DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const; + virtual void DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const; + + private: + std::unique_ptr<FieldGenerator> value_field_generator_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__ 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 0f0087e5a3..935af05158 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 @@ -1,636 +1,636 @@ -// 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 <algorithm> -#include <iostream> -#include <sstream> - -#include <google/protobuf/compiler/objectivec/objectivec_message.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/stubs/stl_util.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/coded_stream.h> -#include <google/protobuf/io/zero_copy_stream_impl.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/wire_format_lite.h> -#include <google/protobuf/descriptor.pb.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -namespace { -struct FieldOrderingByNumber { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - return a->number() < b->number(); - } -}; - -int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) { - // The first item in the object structure is our uint32[] for has bits. - // We then want to order things to make the instances as small as - // possible. So we follow the has bits with: - // 1. Anything always 4 bytes - float, *32, enums - // 2. Anything that is always a pointer (they will be 8 bytes on 64 bit - // builds and 4 bytes on 32bit builds. - // 3. Anything always 8 bytes - double, *64 - // - // NOTE: Bools aren't listed, they were stored in the has bits. - // - // Why? Using 64bit builds as an example, this means worse case, we have - // enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes - // are wasted before the 4 byte values. Then if we have an odd number of - // those 4 byte values, the 8 byte values will be pushed down by 32bits to - // keep them aligned. But the structure will end 8 byte aligned, so no - // waste on the end. If you did the reverse order, you could waste 4 bytes - // before the first 8 byte value (after the has array), then a single - // bool on the end would need 7 bytes of padding to make the overall - // structure 8 byte aligned; so 11 bytes, wasted total. - - // Anything repeated is a GPB*Array/NSArray, so pointer. - if (descriptor->is_repeated()) { - return 3; - } - - switch (descriptor->type()) { - // All always 8 bytes. - case FieldDescriptor::TYPE_DOUBLE: - case FieldDescriptor::TYPE_INT64: - case FieldDescriptor::TYPE_SINT64: - case FieldDescriptor::TYPE_UINT64: - case FieldDescriptor::TYPE_SFIXED64: - case FieldDescriptor::TYPE_FIXED64: - return 4; - - // Pointers (string and bytes are NSString and NSData); 8 or 4 bytes - // depending on the build architecture. - case FieldDescriptor::TYPE_GROUP: - case FieldDescriptor::TYPE_MESSAGE: - case FieldDescriptor::TYPE_STRING: - case FieldDescriptor::TYPE_BYTES: - return 3; - - // All always 4 bytes (enums are int32s). - case FieldDescriptor::TYPE_FLOAT: - case FieldDescriptor::TYPE_INT32: - case FieldDescriptor::TYPE_SINT32: - case FieldDescriptor::TYPE_UINT32: - case FieldDescriptor::TYPE_SFIXED32: - case FieldDescriptor::TYPE_FIXED32: - case FieldDescriptor::TYPE_ENUM: - return 2; - - // 0 bytes. Stored in the has bits. - case FieldDescriptor::TYPE_BOOL: - return 99; // End of the list (doesn't really matter). - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; -} - -struct FieldOrderingByStorageSize { - inline bool operator()(const FieldDescriptor* a, - const FieldDescriptor* b) const { - // Order by grouping. - const int order_group_a = OrderGroupForFieldDescriptor(a); - const int order_group_b = OrderGroupForFieldDescriptor(b); - if (order_group_a != order_group_b) { - return order_group_a < order_group_b; - } - // Within the group, order by field number (provides stable ordering). - return a->number() < b->number(); - } -}; - -struct ExtensionRangeOrdering { - bool operator()(const Descriptor::ExtensionRange* a, - const Descriptor::ExtensionRange* b) const { - return a->start < b->start; - } -}; - -// Sort the fields of the given Descriptor by number into a new[]'d array -// and return it. -const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor* [descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - std::sort(fields, fields + descriptor->field_count(), FieldOrderingByNumber()); - return fields; -} - -// Sort the fields of the given Descriptor by storage size into a new[]'d -// array and return it. -const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { - const FieldDescriptor** fields = - new const FieldDescriptor* [descriptor->field_count()]; - for (int i = 0; i < descriptor->field_count(); i++) { - fields[i] = descriptor->field(i); - } - std::sort(fields, fields + descriptor->field_count(), - FieldOrderingByStorageSize()); - return fields; -} -} // namespace - -MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, - const Options& options) - : root_classname_(root_classname), - descriptor_(descriptor), - field_generators_(descriptor, options), - class_name_(ClassName(descriptor_)), - deprecated_attribute_(GetOptionalDeprecatedAttribute( - descriptor, descriptor->file(), false, true)) { - for (int i = 0; i < descriptor_->extension_count(); i++) { - extension_generators_.emplace_back( - new ExtensionGenerator(class_name_, descriptor_->extension(i))); - } - - for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { - OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i)); - oneof_generators_.emplace_back(generator); - } - - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i)); - enum_generators_.emplace_back(generator); - } - - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - MessageGenerator* generator = - new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); - nested_message_generators_.emplace_back(generator); - } -} - -MessageGenerator::~MessageGenerator() {} - -void MessageGenerator::GenerateStaticVariablesInitialization( - io::Printer* printer) { - for (const auto& generator : extension_generators_) { - generator->GenerateStaticVariablesInitialization(printer); - } - - for (const auto& generator : nested_message_generators_) { - generator->GenerateStaticVariablesInitialization(printer); - } -} - -void MessageGenerator::DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) { - 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); - } - } - - for (const auto& generator : nested_message_generators_) { - generator->DetermineForwardDeclarations(fwd_decls); - } -} - -void MessageGenerator::DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) { - if (!IsMapEntryMessage(descriptor_)) { - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* fieldDescriptor = descriptor_->field(i); - field_generators_.get(fieldDescriptor) - .DetermineObjectiveCClassDefinitions(fwd_decls); - } - } - - for (const auto& generator : extension_generators_) { - generator->DetermineObjectiveCClassDefinitions(fwd_decls); - } - - for (const auto& generator : nested_message_generators_) { - generator->DetermineObjectiveCClassDefinitions(fwd_decls); - } - - const Descriptor* containing_descriptor = descriptor_->containing_type(); - if (containing_descriptor != NULL) { - TProtoStringType containing_class = ClassName(containing_descriptor); - fwd_decls->insert(ObjCClassDeclaration(containing_class)); - } -} - -bool MessageGenerator::IncludesOneOfDefinition() const { - if (!oneof_generators_.empty()) { - return true; - } - - for (const auto& generator : nested_message_generators_) { - if (generator->IncludesOneOfDefinition()) { - return true; - } - } - - return false; -} - -void MessageGenerator::GenerateEnumHeader(io::Printer* printer) { - for (const auto& generator : enum_generators_) { - generator->GenerateHeader(printer); - } - - for (const auto& generator : nested_message_generators_) { - generator->GenerateEnumHeader(printer); - } -} - -void MessageGenerator::GenerateExtensionRegistrationSource( - io::Printer* printer) { - for (const auto& generator : extension_generators_) { - generator->GenerateRegistrationSource(printer); - } - - for (const auto& generator : nested_message_generators_) { - generator->GenerateExtensionRegistrationSource(printer); - } -} - -void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { - // This a a map entry message, just recurse and do nothing directly. - if (IsMapEntryMessage(descriptor_)) { - for (const auto& generator : nested_message_generators_) { - generator->GenerateMessageHeader(printer); - } - return; - } - - printer->Print( - "#pragma mark - $classname$\n" - "\n", - "classname", class_name_); - - if (descriptor_->field_count()) { - std::unique_ptr<const FieldDescriptor*[]> sorted_fields( - SortFieldsByNumber(descriptor_)); - - printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n", - "classname", class_name_); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(sorted_fields[i]) - .GenerateFieldNumberConstant(printer); - } - - printer->Outdent(); - printer->Print("};\n\n"); - } - - for (const auto& generator : oneof_generators_) { - generator->GenerateCaseEnum(printer); - } - - TProtoStringType message_comments; - SourceLocation location; - if (descriptor_->GetSourceLocation(&location)) { - message_comments = BuildCommentsString(location, false); - } else { - message_comments = ""; - } - - printer->Print( - "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n", - "classname", class_name_, - "deprecated_attribute", deprecated_attribute_, - "comments", message_comments); - - std::vector<char> seen_oneofs(oneof_generators_.size(), 0); - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* field = descriptor_->field(i); - const OneofDescriptor* oneof = field->real_containing_oneof(); - if (oneof) { - const int oneof_index = oneof->index(); - if (!seen_oneofs[oneof_index]) { - seen_oneofs[oneof_index] = 1; - oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration( - printer); - } - } - field_generators_.get(field).GeneratePropertyDeclaration(printer); - } - - printer->Print("@end\n\n"); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateCFunctionDeclarations(printer); - } - - if (!oneof_generators_.empty()) { - for (const auto& generator : oneof_generators_) { - generator->GenerateClearFunctionDeclaration(printer); - } - printer->Print("\n"); - } - - if (descriptor_->extension_count() > 0) { - printer->Print("@interface $classname$ (DynamicMethods)\n\n", - "classname", class_name_); - for (const auto& generator : extension_generators_) { - generator->GenerateMembersHeader(printer); - } - printer->Print("@end\n\n"); - } - - for (const auto& generator : nested_message_generators_) { - generator->GenerateMessageHeader(printer); - } -} - -void MessageGenerator::GenerateSource(io::Printer* printer) { - if (!IsMapEntryMessage(descriptor_)) { - printer->Print( - "#pragma mark - $classname$\n" - "\n", - "classname", class_name_); - - if (!deprecated_attribute_.empty()) { - // No warnings when compiling the impl of this deprecated class. - printer->Print( - "#pragma clang diagnostic push\n" - "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n" - "\n"); - } - - printer->Print("@implementation $classname$\n\n", - "classname", class_name_); - - for (const auto& generator : oneof_generators_) { - generator->GeneratePropertyImplementation(printer); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GeneratePropertyImplementation(printer); - } - - std::unique_ptr<const FieldDescriptor*[]> sorted_fields( - SortFieldsByNumber(descriptor_)); - std::unique_ptr<const FieldDescriptor*[]> size_order_fields( - SortFieldsByStorageSize(descriptor_)); - - std::vector<const Descriptor::ExtensionRange*> sorted_extensions; - sorted_extensions.reserve(descriptor_->extension_range_count()); - for (int i = 0; i < descriptor_->extension_range_count(); ++i) { - sorted_extensions.push_back(descriptor_->extension_range(i)); - } - - std::sort(sorted_extensions.begin(), sorted_extensions.end(), - ExtensionRangeOrdering()); - - // Assign has bits: - // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing - // who needs has bits and assigning them. - // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative - // index that groups all the elements in the oneof. - size_t num_has_bits = field_generators_.CalculateHasBits(); - size_t sizeof_has_storage = (num_has_bits + 31) / 32; - if (sizeof_has_storage == 0) { - // In the case where no field needs has bits, don't let the _has_storage_ - // end up as zero length (zero length arrays are sort of a grey area - // since it has to be at the start of the struct). This also ensures a - // field with only oneofs keeps the required negative indices they need. - sizeof_has_storage = 1; - } - // Tell all the fields the oneof base. - for (const auto& generator : oneof_generators_) { - generator->SetOneofIndexBase(sizeof_has_storage); - } - field_generators_.SetOneofIndexBase(sizeof_has_storage); - // sizeof_has_storage needs enough bits for the single fields that aren't in - // any oneof, and then one int32 for each oneof (to store the field number). - sizeof_has_storage += oneof_generators_.size(); - - printer->Print( - "\n" - "typedef struct $classname$__storage_ {\n" - " uint32_t _has_storage_[$sizeof_has_storage$];\n", - "classname", class_name_, - "sizeof_has_storage", StrCat(sizeof_has_storage)); - printer->Indent(); - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(size_order_fields[i]) - .GenerateFieldStorageDeclaration(printer); - } - printer->Outdent(); - - printer->Print("} $classname$__storage_;\n\n", "classname", class_name_); - - - printer->Print( - "// This method is threadsafe because it is initially called\n" - "// in +initialize for each subclass.\n" - "+ (GPBDescriptor *)descriptor {\n" - " static GPBDescriptor *descriptor = nil;\n" - " if (!descriptor) {\n"); - - TextFormatDecodeData text_format_decode_data; - bool has_fields = descriptor_->field_count() > 0; - bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault(); - TProtoStringType field_description_type; - if (need_defaults) { - field_description_type = "GPBMessageFieldDescriptionWithDefault"; - } else { - field_description_type = "GPBMessageFieldDescription"; - } - if (has_fields) { - printer->Indent(); - printer->Indent(); - printer->Print( - "static $field_description_type$ fields[] = {\n", - "field_description_type", field_description_type); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); ++i) { - const FieldGenerator& field_generator = - field_generators_.get(sorted_fields[i]); - field_generator.GenerateFieldDescription(printer, need_defaults); - if (field_generator.needs_textformat_name_support()) { - text_format_decode_data.AddString(sorted_fields[i]->number(), - field_generator.generated_objc_name(), - field_generator.raw_field_name()); - } - } - printer->Outdent(); - printer->Print( - "};\n"); - printer->Outdent(); - printer->Outdent(); - } - - std::map<TProtoStringType, TProtoStringType> vars; - vars["classname"] = class_name_; - vars["rootclassname"] = root_classname_; - vars["fields"] = has_fields ? "fields" : "NULL"; - if (has_fields) { - vars["fields_count"] = - "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))"; - } else { - vars["fields_count"] = "0"; - } - - std::vector<TProtoStringType> init_flags; - init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs"); - init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown"); - if (need_defaults) { - init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault"); - } - if (descriptor_->options().message_set_wire_format()) { - init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat"); - } - vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION, - init_flags); - - printer->Print( - vars, - " GPBDescriptor *localDescriptor =\n" - " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n" - " rootClass:[$rootclassname$ class]\n" - " file:$rootclassname$_FileDescriptor()\n" - " fields:$fields$\n" - " fieldCount:$fields_count$\n" - " storageSize:sizeof($classname$__storage_)\n" - " flags:$init_flags$];\n"); - if (!oneof_generators_.empty()) { - printer->Print( - " static const char *oneofs[] = {\n"); - for (const auto& generator : oneof_generators_) { - printer->Print(" \"$name$\",\n", "name", - generator->DescriptorName()); - } - printer->Print( - " };\n" - " [localDescriptor setupOneofs:oneofs\n" - " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n" - " firstHasIndex:$first_has_index$];\n", - "first_has_index", oneof_generators_[0]->HasIndexAsString()); - } - if (text_format_decode_data.num_entries() != 0) { - const TProtoStringType text_format_data_str(text_format_decode_data.Data()); - printer->Print( - "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" - " static const char *extraTextFormatInfo ="); - static const int kBytesPerLine = 40; // allow for escaping - for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) { - printer->Print( - "\n \"$data$\"", - "data", EscapeTrigraphs( - CEscape(text_format_data_str.substr(i, kBytesPerLine)))); - } - printer->Print( - ";\n" - " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n" - "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"); - } - if (!sorted_extensions.empty()) { - printer->Print( - " static const GPBExtensionRange ranges[] = {\n"); - for (int i = 0; i < sorted_extensions.size(); i++) { - printer->Print(" { .start = $start$, .end = $end$ },\n", - "start", StrCat(sorted_extensions[i]->start), - "end", StrCat(sorted_extensions[i]->end)); - } - printer->Print( - " };\n" - " [localDescriptor setupExtensionRanges:ranges\n" - " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n"); - } - if (descriptor_->containing_type() != NULL) { - TProtoStringType containing_class = ClassName(descriptor_->containing_type()); - TProtoStringType parent_class_ref = ObjCClass(containing_class); - printer->Print( - " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n", - "parent_class_ref", parent_class_ref); - } - TProtoStringType suffix_added; - ClassName(descriptor_, &suffix_added); - if (!suffix_added.empty()) { - printer->Print( - " [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n", - "suffix", suffix_added); - } - printer->Print( - " #if defined(DEBUG) && DEBUG\n" - " NSAssert(descriptor == nil, @\"Startup recursed!\");\n" - " #endif // DEBUG\n" - " descriptor = localDescriptor;\n" - " }\n" - " return descriptor;\n" - "}\n\n" - "@end\n\n"); - - if (!deprecated_attribute_.empty()) { - printer->Print( - "#pragma clang diagnostic pop\n" - "\n"); - } - - for (int i = 0; i < descriptor_->field_count(); i++) { - field_generators_.get(descriptor_->field(i)) - .GenerateCFunctionImplementations(printer); - } - - for (const auto& generator : oneof_generators_) { - generator->GenerateClearFunctionImplementation(printer); - } - } - - for (const auto& generator : enum_generators_) { - generator->GenerateSource(printer); - } - - for (const auto& generator : nested_message_generators_) { - generator->GenerateSource(printer); - } -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <algorithm> +#include <iostream> +#include <sstream> + +#include <google/protobuf/compiler/objectivec/objectivec_message.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/stubs/stl_util.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/io/coded_stream.h> +#include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> +#include <google/protobuf/descriptor.pb.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { +struct FieldOrderingByNumber { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + return a->number() < b->number(); + } +}; + +int OrderGroupForFieldDescriptor(const FieldDescriptor* descriptor) { + // The first item in the object structure is our uint32[] for has bits. + // We then want to order things to make the instances as small as + // possible. So we follow the has bits with: + // 1. Anything always 4 bytes - float, *32, enums + // 2. Anything that is always a pointer (they will be 8 bytes on 64 bit + // builds and 4 bytes on 32bit builds. + // 3. Anything always 8 bytes - double, *64 + // + // NOTE: Bools aren't listed, they were stored in the has bits. + // + // Why? Using 64bit builds as an example, this means worse case, we have + // enough bools that we overflow 1 byte from 4 byte alignment, so 3 bytes + // are wasted before the 4 byte values. Then if we have an odd number of + // those 4 byte values, the 8 byte values will be pushed down by 32bits to + // keep them aligned. But the structure will end 8 byte aligned, so no + // waste on the end. If you did the reverse order, you could waste 4 bytes + // before the first 8 byte value (after the has array), then a single + // bool on the end would need 7 bytes of padding to make the overall + // structure 8 byte aligned; so 11 bytes, wasted total. + + // Anything repeated is a GPB*Array/NSArray, so pointer. + if (descriptor->is_repeated()) { + return 3; + } + + switch (descriptor->type()) { + // All always 8 bytes. + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_INT64: + case FieldDescriptor::TYPE_SINT64: + case FieldDescriptor::TYPE_UINT64: + case FieldDescriptor::TYPE_SFIXED64: + case FieldDescriptor::TYPE_FIXED64: + return 4; + + // Pointers (string and bytes are NSString and NSData); 8 or 4 bytes + // depending on the build architecture. + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: + return 3; + + // All always 4 bytes (enums are int32s). + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_INT32: + case FieldDescriptor::TYPE_SINT32: + case FieldDescriptor::TYPE_UINT32: + case FieldDescriptor::TYPE_SFIXED32: + case FieldDescriptor::TYPE_FIXED32: + case FieldDescriptor::TYPE_ENUM: + return 2; + + // 0 bytes. Stored in the has bits. + case FieldDescriptor::TYPE_BOOL: + return 99; // End of the list (doesn't really matter). + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; +} + +struct FieldOrderingByStorageSize { + inline bool operator()(const FieldDescriptor* a, + const FieldDescriptor* b) const { + // Order by grouping. + const int order_group_a = OrderGroupForFieldDescriptor(a); + const int order_group_b = OrderGroupForFieldDescriptor(b); + if (order_group_a != order_group_b) { + return order_group_a < order_group_b; + } + // Within the group, order by field number (provides stable ordering). + return a->number() < b->number(); + } +}; + +struct ExtensionRangeOrdering { + bool operator()(const Descriptor::ExtensionRange* a, + const Descriptor::ExtensionRange* b) const { + return a->start < b->start; + } +}; + +// Sort the fields of the given Descriptor by number into a new[]'d array +// and return it. +const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor* [descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + std::sort(fields, fields + descriptor->field_count(), FieldOrderingByNumber()); + return fields; +} + +// Sort the fields of the given Descriptor by storage size into a new[]'d +// array and return it. +const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { + const FieldDescriptor** fields = + new const FieldDescriptor* [descriptor->field_count()]; + for (int i = 0; i < descriptor->field_count(); i++) { + fields[i] = descriptor->field(i); + } + std::sort(fields, fields + descriptor->field_count(), + FieldOrderingByStorageSize()); + return fields; +} +} // namespace + +MessageGenerator::MessageGenerator(const TProtoStringType& root_classname, + const Descriptor* descriptor, + const Options& options) + : root_classname_(root_classname), + descriptor_(descriptor), + field_generators_(descriptor, options), + class_name_(ClassName(descriptor_)), + deprecated_attribute_(GetOptionalDeprecatedAttribute( + descriptor, descriptor->file(), false, true)) { + for (int i = 0; i < descriptor_->extension_count(); i++) { + extension_generators_.emplace_back( + new ExtensionGenerator(class_name_, descriptor_->extension(i))); + } + + for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { + OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i)); + oneof_generators_.emplace_back(generator); + } + + for (int i = 0; i < descriptor_->enum_type_count(); i++) { + EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i)); + enum_generators_.emplace_back(generator); + } + + for (int i = 0; i < descriptor_->nested_type_count(); i++) { + MessageGenerator* generator = + new MessageGenerator(root_classname_, + descriptor_->nested_type(i), + options); + nested_message_generators_.emplace_back(generator); + } +} + +MessageGenerator::~MessageGenerator() {} + +void MessageGenerator::GenerateStaticVariablesInitialization( + io::Printer* printer) { + for (const auto& generator : extension_generators_) { + generator->GenerateStaticVariablesInitialization(printer); + } + + for (const auto& generator : nested_message_generators_) { + generator->GenerateStaticVariablesInitialization(printer); + } +} + +void MessageGenerator::DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) { + 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); + } + } + + for (const auto& generator : nested_message_generators_) { + generator->DetermineForwardDeclarations(fwd_decls); + } +} + +void MessageGenerator::DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) { + if (!IsMapEntryMessage(descriptor_)) { + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* fieldDescriptor = descriptor_->field(i); + field_generators_.get(fieldDescriptor) + .DetermineObjectiveCClassDefinitions(fwd_decls); + } + } + + for (const auto& generator : extension_generators_) { + generator->DetermineObjectiveCClassDefinitions(fwd_decls); + } + + for (const auto& generator : nested_message_generators_) { + generator->DetermineObjectiveCClassDefinitions(fwd_decls); + } + + const Descriptor* containing_descriptor = descriptor_->containing_type(); + if (containing_descriptor != NULL) { + TProtoStringType containing_class = ClassName(containing_descriptor); + fwd_decls->insert(ObjCClassDeclaration(containing_class)); + } +} + +bool MessageGenerator::IncludesOneOfDefinition() const { + if (!oneof_generators_.empty()) { + return true; + } + + for (const auto& generator : nested_message_generators_) { + if (generator->IncludesOneOfDefinition()) { + return true; + } + } + + return false; +} + +void MessageGenerator::GenerateEnumHeader(io::Printer* printer) { + for (const auto& generator : enum_generators_) { + generator->GenerateHeader(printer); + } + + for (const auto& generator : nested_message_generators_) { + generator->GenerateEnumHeader(printer); + } +} + +void MessageGenerator::GenerateExtensionRegistrationSource( + io::Printer* printer) { + for (const auto& generator : extension_generators_) { + generator->GenerateRegistrationSource(printer); + } + + for (const auto& generator : nested_message_generators_) { + generator->GenerateExtensionRegistrationSource(printer); + } +} + +void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { + // This a a map entry message, just recurse and do nothing directly. + if (IsMapEntryMessage(descriptor_)) { + for (const auto& generator : nested_message_generators_) { + generator->GenerateMessageHeader(printer); + } + return; + } + + printer->Print( + "#pragma mark - $classname$\n" + "\n", + "classname", class_name_); + + if (descriptor_->field_count()) { + std::unique_ptr<const FieldDescriptor*[]> sorted_fields( + SortFieldsByNumber(descriptor_)); + + printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n", + "classname", class_name_); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(sorted_fields[i]) + .GenerateFieldNumberConstant(printer); + } + + printer->Outdent(); + printer->Print("};\n\n"); + } + + for (const auto& generator : oneof_generators_) { + generator->GenerateCaseEnum(printer); + } + + TProtoStringType message_comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + message_comments = BuildCommentsString(location, false); + } else { + message_comments = ""; + } + + printer->Print( + "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n", + "classname", class_name_, + "deprecated_attribute", deprecated_attribute_, + "comments", message_comments); + + std::vector<char> seen_oneofs(oneof_generators_.size(), 0); + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + const OneofDescriptor* oneof = field->real_containing_oneof(); + if (oneof) { + const int oneof_index = oneof->index(); + if (!seen_oneofs[oneof_index]) { + seen_oneofs[oneof_index] = 1; + oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration( + printer); + } + } + field_generators_.get(field).GeneratePropertyDeclaration(printer); + } + + printer->Print("@end\n\n"); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateCFunctionDeclarations(printer); + } + + if (!oneof_generators_.empty()) { + for (const auto& generator : oneof_generators_) { + generator->GenerateClearFunctionDeclaration(printer); + } + printer->Print("\n"); + } + + if (descriptor_->extension_count() > 0) { + printer->Print("@interface $classname$ (DynamicMethods)\n\n", + "classname", class_name_); + for (const auto& generator : extension_generators_) { + generator->GenerateMembersHeader(printer); + } + printer->Print("@end\n\n"); + } + + for (const auto& generator : nested_message_generators_) { + generator->GenerateMessageHeader(printer); + } +} + +void MessageGenerator::GenerateSource(io::Printer* printer) { + if (!IsMapEntryMessage(descriptor_)) { + printer->Print( + "#pragma mark - $classname$\n" + "\n", + "classname", class_name_); + + if (!deprecated_attribute_.empty()) { + // No warnings when compiling the impl of this deprecated class. + printer->Print( + "#pragma clang diagnostic push\n" + "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n" + "\n"); + } + + printer->Print("@implementation $classname$\n\n", + "classname", class_name_); + + for (const auto& generator : oneof_generators_) { + generator->GeneratePropertyImplementation(printer); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GeneratePropertyImplementation(printer); + } + + std::unique_ptr<const FieldDescriptor*[]> sorted_fields( + SortFieldsByNumber(descriptor_)); + std::unique_ptr<const FieldDescriptor*[]> size_order_fields( + SortFieldsByStorageSize(descriptor_)); + + std::vector<const Descriptor::ExtensionRange*> sorted_extensions; + sorted_extensions.reserve(descriptor_->extension_range_count()); + for (int i = 0; i < descriptor_->extension_range_count(); ++i) { + sorted_extensions.push_back(descriptor_->extension_range(i)); + } + + std::sort(sorted_extensions.begin(), sorted_extensions.end(), + ExtensionRangeOrdering()); + + // Assign has bits: + // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing + // who needs has bits and assigning them. + // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative + // index that groups all the elements in the oneof. + size_t num_has_bits = field_generators_.CalculateHasBits(); + size_t sizeof_has_storage = (num_has_bits + 31) / 32; + if (sizeof_has_storage == 0) { + // In the case where no field needs has bits, don't let the _has_storage_ + // end up as zero length (zero length arrays are sort of a grey area + // since it has to be at the start of the struct). This also ensures a + // field with only oneofs keeps the required negative indices they need. + sizeof_has_storage = 1; + } + // Tell all the fields the oneof base. + for (const auto& generator : oneof_generators_) { + generator->SetOneofIndexBase(sizeof_has_storage); + } + field_generators_.SetOneofIndexBase(sizeof_has_storage); + // sizeof_has_storage needs enough bits for the single fields that aren't in + // any oneof, and then one int32 for each oneof (to store the field number). + sizeof_has_storage += oneof_generators_.size(); + + printer->Print( + "\n" + "typedef struct $classname$__storage_ {\n" + " uint32_t _has_storage_[$sizeof_has_storage$];\n", + "classname", class_name_, + "sizeof_has_storage", StrCat(sizeof_has_storage)); + printer->Indent(); + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(size_order_fields[i]) + .GenerateFieldStorageDeclaration(printer); + } + printer->Outdent(); + + printer->Print("} $classname$__storage_;\n\n", "classname", class_name_); + + + printer->Print( + "// This method is threadsafe because it is initially called\n" + "// in +initialize for each subclass.\n" + "+ (GPBDescriptor *)descriptor {\n" + " static GPBDescriptor *descriptor = nil;\n" + " if (!descriptor) {\n"); + + TextFormatDecodeData text_format_decode_data; + bool has_fields = descriptor_->field_count() > 0; + bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault(); + TProtoStringType field_description_type; + if (need_defaults) { + field_description_type = "GPBMessageFieldDescriptionWithDefault"; + } else { + field_description_type = "GPBMessageFieldDescription"; + } + if (has_fields) { + printer->Indent(); + printer->Indent(); + printer->Print( + "static $field_description_type$ fields[] = {\n", + "field_description_type", field_description_type); + printer->Indent(); + for (int i = 0; i < descriptor_->field_count(); ++i) { + const FieldGenerator& field_generator = + field_generators_.get(sorted_fields[i]); + field_generator.GenerateFieldDescription(printer, need_defaults); + if (field_generator.needs_textformat_name_support()) { + text_format_decode_data.AddString(sorted_fields[i]->number(), + field_generator.generated_objc_name(), + field_generator.raw_field_name()); + } + } + printer->Outdent(); + printer->Print( + "};\n"); + printer->Outdent(); + printer->Outdent(); + } + + std::map<TProtoStringType, TProtoStringType> vars; + vars["classname"] = class_name_; + vars["rootclassname"] = root_classname_; + vars["fields"] = has_fields ? "fields" : "NULL"; + if (has_fields) { + vars["fields_count"] = + "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))"; + } else { + vars["fields_count"] = "0"; + } + + std::vector<TProtoStringType> init_flags; + init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs"); + init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown"); + if (need_defaults) { + init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault"); + } + if (descriptor_->options().message_set_wire_format()) { + init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat"); + } + vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION, + init_flags); + + printer->Print( + vars, + " GPBDescriptor *localDescriptor =\n" + " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n" + " rootClass:[$rootclassname$ class]\n" + " file:$rootclassname$_FileDescriptor()\n" + " fields:$fields$\n" + " fieldCount:$fields_count$\n" + " storageSize:sizeof($classname$__storage_)\n" + " flags:$init_flags$];\n"); + if (!oneof_generators_.empty()) { + printer->Print( + " static const char *oneofs[] = {\n"); + for (const auto& generator : oneof_generators_) { + printer->Print(" \"$name$\",\n", "name", + generator->DescriptorName()); + } + printer->Print( + " };\n" + " [localDescriptor setupOneofs:oneofs\n" + " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n" + " firstHasIndex:$first_has_index$];\n", + "first_has_index", oneof_generators_[0]->HasIndexAsString()); + } + if (text_format_decode_data.num_entries() != 0) { + const TProtoStringType text_format_data_str(text_format_decode_data.Data()); + printer->Print( + "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n" + " static const char *extraTextFormatInfo ="); + static const int kBytesPerLine = 40; // allow for escaping + for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) { + printer->Print( + "\n \"$data$\"", + "data", EscapeTrigraphs( + CEscape(text_format_data_str.substr(i, kBytesPerLine)))); + } + printer->Print( + ";\n" + " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n" + "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"); + } + if (!sorted_extensions.empty()) { + printer->Print( + " static const GPBExtensionRange ranges[] = {\n"); + for (int i = 0; i < sorted_extensions.size(); i++) { + printer->Print(" { .start = $start$, .end = $end$ },\n", + "start", StrCat(sorted_extensions[i]->start), + "end", StrCat(sorted_extensions[i]->end)); + } + printer->Print( + " };\n" + " [localDescriptor setupExtensionRanges:ranges\n" + " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n"); + } + if (descriptor_->containing_type() != NULL) { + TProtoStringType containing_class = ClassName(descriptor_->containing_type()); + TProtoStringType parent_class_ref = ObjCClass(containing_class); + printer->Print( + " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n", + "parent_class_ref", parent_class_ref); + } + TProtoStringType suffix_added; + ClassName(descriptor_, &suffix_added); + if (!suffix_added.empty()) { + printer->Print( + " [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n", + "suffix", suffix_added); + } + printer->Print( + " #if defined(DEBUG) && DEBUG\n" + " NSAssert(descriptor == nil, @\"Startup recursed!\");\n" + " #endif // DEBUG\n" + " descriptor = localDescriptor;\n" + " }\n" + " return descriptor;\n" + "}\n\n" + "@end\n\n"); + + if (!deprecated_attribute_.empty()) { + printer->Print( + "#pragma clang diagnostic pop\n" + "\n"); + } + + for (int i = 0; i < descriptor_->field_count(); i++) { + field_generators_.get(descriptor_->field(i)) + .GenerateCFunctionImplementations(printer); + } + + for (const auto& generator : oneof_generators_) { + generator->GenerateClearFunctionImplementation(printer); + } + } + + for (const auto& generator : enum_generators_) { + generator->GenerateSource(printer); + } + + for (const auto& generator : nested_message_generators_) { + generator->GenerateSource(printer); + } +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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..6d559aa82e 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 @@ -1,99 +1,99 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ - -#include <string> -#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> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class ExtensionGenerator; -class EnumGenerator; - -class MessageGenerator { - public: - MessageGenerator(const TProtoStringType& root_classname, - const Descriptor* descriptor, const Options& options); - ~MessageGenerator(); - - MessageGenerator(const MessageGenerator&) = delete; - MessageGenerator& operator=(const MessageGenerator&) = delete; - - void GenerateStaticVariablesInitialization(io::Printer* printer); - void GenerateEnumHeader(io::Printer* printer); - void GenerateMessageHeader(io::Printer* printer); - void GenerateSource(io::Printer* printer); - void GenerateExtensionRegistrationSource(io::Printer* printer); - void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); - void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls); - - // Checks if the message or a nested message includes a oneof definition. - bool IncludesOneOfDefinition() const; - - private: - void GenerateParseFromMethodsHeader(io::Printer* printer); - - void GenerateSerializeOneFieldSource(io::Printer* printer, - const FieldDescriptor* field); - void GenerateSerializeOneExtensionRangeSource( - io::Printer* printer, const Descriptor::ExtensionRange* range); - - void GenerateMessageDescriptionSource(io::Printer* printer); - void GenerateDescriptionOneFieldSource(io::Printer* printer, - const FieldDescriptor* field); - - const TProtoStringType root_classname_; - const Descriptor* descriptor_; - FieldGeneratorMap field_generators_; - const TProtoStringType class_name_; - const TProtoStringType deprecated_attribute_; - std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_; - std::vector<std::unique_ptr<EnumGenerator>> enum_generators_; - std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_; - std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ + +#include <string> +#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> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class ExtensionGenerator; +class EnumGenerator; + +class MessageGenerator { + public: + MessageGenerator(const TProtoStringType& root_classname, + const Descriptor* descriptor, const Options& options); + ~MessageGenerator(); + + MessageGenerator(const MessageGenerator&) = delete; + MessageGenerator& operator=(const MessageGenerator&) = delete; + + void GenerateStaticVariablesInitialization(io::Printer* printer); + void GenerateEnumHeader(io::Printer* printer); + void GenerateMessageHeader(io::Printer* printer); + void GenerateSource(io::Printer* printer); + void GenerateExtensionRegistrationSource(io::Printer* printer); + void DetermineObjectiveCClassDefinitions(std::set<TProtoStringType>* fwd_decls); + void DetermineForwardDeclarations(std::set<TProtoStringType>* fwd_decls); + + // Checks if the message or a nested message includes a oneof definition. + bool IncludesOneOfDefinition() const; + + private: + void GenerateParseFromMethodsHeader(io::Printer* printer); + + void GenerateSerializeOneFieldSource(io::Printer* printer, + const FieldDescriptor* field); + void GenerateSerializeOneExtensionRangeSource( + io::Printer* printer, const Descriptor::ExtensionRange* range); + + void GenerateMessageDescriptionSource(io::Printer* printer); + void GenerateDescriptionOneFieldSource(io::Printer* printer, + const FieldDescriptor* field); + + const TProtoStringType root_classname_; + const Descriptor* descriptor_; + FieldGeneratorMap field_generators_; + const TProtoStringType class_name_; + const TProtoStringType deprecated_attribute_; + std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_; + std::vector<std::unique_ptr<EnumGenerator>> enum_generators_; + std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_; + std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__ 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..351741f404 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 @@ -1,107 +1,107 @@ -// 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/wire_format.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -namespace { - -void SetMessageVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables) { - const TProtoStringType& message_type = ClassName(descriptor->message_type()); - const TProtoStringType& containing_class = - ClassName(descriptor->containing_type()); - (*variables)["type"] = message_type; - (*variables)["containing_class"] = containing_class; - (*variables)["storage_type"] = message_type; - (*variables)["group_or_message"] = - (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; - (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type); -} - -} // namespace - -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { - 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")); -} - -void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const { - fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); -} - -RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { - SetMessageVariables(descriptor, &variables_); - variables_["array_storage_type"] = "NSMutableArray"; - variables_["array_property_type"] = - "NSMutableArray<" + variables_["storage_type"] + "*>"; -} - -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")); -} - -void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const { - fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_message_field.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/wire_format.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +namespace { + +void SetMessageVariables(const FieldDescriptor* descriptor, + std::map<TProtoStringType, TProtoStringType>* variables) { + const TProtoStringType& message_type = ClassName(descriptor->message_type()); + const TProtoStringType& containing_class = + ClassName(descriptor->containing_type()); + (*variables)["type"] = message_type; + (*variables)["containing_class"] = containing_class; + (*variables)["storage_type"] = message_type; + (*variables)["group_or_message"] = + (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; + (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type); +} + +} // namespace + +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options) + : ObjCObjFieldGenerator(descriptor, options) { + 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")); +} + +void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const { + fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); +} + +RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : RepeatedFieldGenerator(descriptor, options) { + SetMessageVariables(descriptor, &variables_); + variables_["array_storage_type"] = "NSMutableArray"; + variables_["array_property_type"] = + "NSMutableArray<" + variables_["storage_type"] + "*>"; +} + +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")); +} + +void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const { + fwd_decls->insert(ObjCClassDeclaration(variable("storage_type"))); +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 ff89f66299..f2eb192383 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 @@ -1,87 +1,87 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - - MessageFieldGenerator(const MessageFieldGenerator&) = delete; - MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; - - virtual ~MessageFieldGenerator(); - - public: - virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const; -}; - -class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual ~RepeatedMessageFieldGenerator(); - - RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; - RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete; - - public: - virtual void DetermineForwardDeclarations( - std::set<TProtoStringType>* fwd_decls) const; - virtual void DetermineObjectiveCClassDefinitions( - std::set<TProtoStringType>* fwd_decls) const; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class MessageFieldGenerator : public ObjCObjFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + protected: + MessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + + MessageFieldGenerator(const MessageFieldGenerator&) = delete; + MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; + + virtual ~MessageFieldGenerator(); + + public: + virtual void DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const; +}; + +class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + protected: + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual ~RepeatedMessageFieldGenerator(); + + RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; + RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete; + + public: + virtual void DetermineForwardDeclarations( + std::set<TProtoStringType>* fwd_decls) const; + virtual void DetermineObjectiveCClassDefinitions( + std::set<TProtoStringType>* fwd_decls) const; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__ diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h index 163304665c..a99bcd49e1 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h @@ -1,197 +1,197 @@ -// NSObject methods -// Autogenerated by method_dump.sh. Do not edit by hand. -// Date: Thu Nov 1 14:12:16 PDT 2018 -// macOS: MacOSX10.14.sdk -// iOS: iPhoneSimulator12.1.sdk - -const char* const kNSObjectMethodsList[] = { - "CAMLType", - "CA_copyRenderValue", - "CA_prepareRenderValue", - "NS_copyCGImage", - "NS_tiledLayerVisibleRect", - "___tryRetain_OA", - "__autorelease_OA", - "__dealloc_zombie", - "__release_OA", - "__retain_OA", - "_accessibilityFinalize", - "_accessibilityIsTableViewDescendant", - "_accessibilityUIElementSpecifier", - "_accessibilityUseConvenienceAPI", - "_allowsDirectEncoding", - "_asScriptTerminologyNameArray", - "_asScriptTerminologyNameString", - "_bindingAdaptor", - "_cfTypeID", - "_copyDescription", - "_destroyObserverList", - "_didEndKeyValueObserving", - "_implicitObservationInfo", - "_internalAccessibilityAttributedHint", - "_internalAccessibilityAttributedLabel", - "_internalAccessibilityAttributedValue", - "_isAXConnector", - "_isAccessibilityContainerSectionCandidate", - "_isAccessibilityContentNavigatorSectionCandidate", - "_isAccessibilityContentSectionCandidate", - "_isAccessibilityTopLevelNavigatorSectionCandidate", - "_isDeallocating", - "_isKVOA", - "_isToManyChangeInformation", - "_ivarDescription", - "_localClassNameForClass", - "_methodDescription", - "_observerStorage", - "_overrideUseFastBlockObservers", - "_propertyDescription", - "_releaseBindingAdaptor", - "_scriptingCount", - "_scriptingCountNonrecursively", - "_scriptingDebugDescription", - "_scriptingExists", - "_scriptingShouldCheckObjectIndexes", - "_shortMethodDescription", - "_shouldSearchChildrenForSection", - "_traitStorageList", - "_tryRetain", - "_ui_descriptionBuilder", - "_uikit_variesByTraitCollections", - "_web_description", - "_webkit_invokeOnMainThread", - "_willBeginKeyValueObserving", - "accessibilityActivate", - "accessibilityActivationPoint", - "accessibilityAllowsOverriddenAttributesWhenIgnored", - "accessibilityAssistiveTechnologyFocusedIdentifiers", - "accessibilityAttributedHint", - "accessibilityAttributedLabel", - "accessibilityAttributedValue", - "accessibilityContainer", - "accessibilityContainerType", - "accessibilityCustomActions", - "accessibilityCustomRotors", - "accessibilityDecrement", - "accessibilityDragSourceDescriptors", - "accessibilityDropPointDescriptors", - "accessibilityElementCount", - "accessibilityElementDidBecomeFocused", - "accessibilityElementDidLoseFocus", - "accessibilityElementIsFocused", - "accessibilityElements", - "accessibilityElementsHidden", - "accessibilityFrame", - "accessibilityHeaderElements", - "accessibilityHint", - "accessibilityIdentification", - "accessibilityIdentifier", - "accessibilityIncrement", - "accessibilityLabel", - "accessibilityLanguage", - "accessibilityLocalizedStringKey", - "accessibilityNavigationStyle", - "accessibilityOverriddenAttributes", - "accessibilityParameterizedAttributeNames", - "accessibilityPath", - "accessibilityPerformEscape", - "accessibilityPerformMagicTap", - "accessibilityPresenterProcessIdentifier", - "accessibilityShouldUseUniqueId", - "accessibilitySupportsNotifications", - "accessibilitySupportsOverriddenAttributes", - "accessibilityTemporaryChildren", - "accessibilityTraits", - "accessibilityValue", - "accessibilityViewIsModal", - "accessibilityVisibleArea", - "allPropertyKeys", - "allowsWeakReference", - "attributeKeys", - "autoContentAccessingProxy", - "autorelease", - "awakeFromNib", - "boolValueSafe", - "bs_encoded", - "bs_isPlistableType", - "bs_secureEncoded", - "cl_json_serializeKey", - "class", - "classCode", - "classDescription", - "classForArchiver", - "classForCoder", - "classForKeyedArchiver", - "classForPortCoder", - "className", - "clearProperties", - "copy", - "dealloc", - "debugDescription", - "defaultAccessibilityTraits", - "description", - "doubleValueSafe", - "entityName", - "exposedBindings", - "finalize", - "finishObserving", - "flushKeyBindings", - "hash", - "init", - "int64ValueSafe", - "isAccessibilityElement", - "isAccessibilityElementByDefault", - "isElementAccessibilityExposedToInterfaceBuilder", - "isFault", - "isNSArray__", - "isNSCFConstantString__", - "isNSData__", - "isNSDate__", - "isNSDictionary__", - "isNSNumber__", - "isNSObject__", - "isNSOrderedSet__", - "isNSSet__", - "isNSString__", - "isNSTimeZone__", - "isNSValue__", - "isProxy", - "mutableCopy", - "nilValueForKey", - "objectSpecifier", - "observationInfo", - "pep_onDetachedThread", - "pep_onMainThread", - "pep_onMainThreadIfNecessary", - "prepareForInterfaceBuilder", - "release", - "releaseOnMainThread", - "retain", - "retainCount", - "retainWeakReference", - "scriptingProperties", - "self", - "shouldGroupAccessibilityChildren", - "storedAccessibilityActivationPoint", - "storedAccessibilityContainerType", - "storedAccessibilityElementsHidden", - "storedAccessibilityFrame", - "storedAccessibilityNavigationStyle", - "storedAccessibilityTraits", - "storedAccessibilityViewIsModal", - "storedIsAccessibilityElement", - "storedShouldGroupAccessibilityChildren", - "stringValueSafe", - "superclass", - "toManyRelationshipKeys", - "toOneRelationshipKeys", - "traitStorageList", - "un_safeBoolValue", - "userInterfaceItemIdentifier", - "utf8ValueSafe", - "valuesForKeysWithDictionary", - "zone", -// Protocol: CAAnimatableValue -// Protocol: CARenderValue -// Protocol: NSObject -// Protocol: ROCKRemoteInvocationInterface -}; +// NSObject methods +// Autogenerated by method_dump.sh. Do not edit by hand. +// Date: Thu Nov 1 14:12:16 PDT 2018 +// macOS: MacOSX10.14.sdk +// iOS: iPhoneSimulator12.1.sdk + +const char* const kNSObjectMethodsList[] = { + "CAMLType", + "CA_copyRenderValue", + "CA_prepareRenderValue", + "NS_copyCGImage", + "NS_tiledLayerVisibleRect", + "___tryRetain_OA", + "__autorelease_OA", + "__dealloc_zombie", + "__release_OA", + "__retain_OA", + "_accessibilityFinalize", + "_accessibilityIsTableViewDescendant", + "_accessibilityUIElementSpecifier", + "_accessibilityUseConvenienceAPI", + "_allowsDirectEncoding", + "_asScriptTerminologyNameArray", + "_asScriptTerminologyNameString", + "_bindingAdaptor", + "_cfTypeID", + "_copyDescription", + "_destroyObserverList", + "_didEndKeyValueObserving", + "_implicitObservationInfo", + "_internalAccessibilityAttributedHint", + "_internalAccessibilityAttributedLabel", + "_internalAccessibilityAttributedValue", + "_isAXConnector", + "_isAccessibilityContainerSectionCandidate", + "_isAccessibilityContentNavigatorSectionCandidate", + "_isAccessibilityContentSectionCandidate", + "_isAccessibilityTopLevelNavigatorSectionCandidate", + "_isDeallocating", + "_isKVOA", + "_isToManyChangeInformation", + "_ivarDescription", + "_localClassNameForClass", + "_methodDescription", + "_observerStorage", + "_overrideUseFastBlockObservers", + "_propertyDescription", + "_releaseBindingAdaptor", + "_scriptingCount", + "_scriptingCountNonrecursively", + "_scriptingDebugDescription", + "_scriptingExists", + "_scriptingShouldCheckObjectIndexes", + "_shortMethodDescription", + "_shouldSearchChildrenForSection", + "_traitStorageList", + "_tryRetain", + "_ui_descriptionBuilder", + "_uikit_variesByTraitCollections", + "_web_description", + "_webkit_invokeOnMainThread", + "_willBeginKeyValueObserving", + "accessibilityActivate", + "accessibilityActivationPoint", + "accessibilityAllowsOverriddenAttributesWhenIgnored", + "accessibilityAssistiveTechnologyFocusedIdentifiers", + "accessibilityAttributedHint", + "accessibilityAttributedLabel", + "accessibilityAttributedValue", + "accessibilityContainer", + "accessibilityContainerType", + "accessibilityCustomActions", + "accessibilityCustomRotors", + "accessibilityDecrement", + "accessibilityDragSourceDescriptors", + "accessibilityDropPointDescriptors", + "accessibilityElementCount", + "accessibilityElementDidBecomeFocused", + "accessibilityElementDidLoseFocus", + "accessibilityElementIsFocused", + "accessibilityElements", + "accessibilityElementsHidden", + "accessibilityFrame", + "accessibilityHeaderElements", + "accessibilityHint", + "accessibilityIdentification", + "accessibilityIdentifier", + "accessibilityIncrement", + "accessibilityLabel", + "accessibilityLanguage", + "accessibilityLocalizedStringKey", + "accessibilityNavigationStyle", + "accessibilityOverriddenAttributes", + "accessibilityParameterizedAttributeNames", + "accessibilityPath", + "accessibilityPerformEscape", + "accessibilityPerformMagicTap", + "accessibilityPresenterProcessIdentifier", + "accessibilityShouldUseUniqueId", + "accessibilitySupportsNotifications", + "accessibilitySupportsOverriddenAttributes", + "accessibilityTemporaryChildren", + "accessibilityTraits", + "accessibilityValue", + "accessibilityViewIsModal", + "accessibilityVisibleArea", + "allPropertyKeys", + "allowsWeakReference", + "attributeKeys", + "autoContentAccessingProxy", + "autorelease", + "awakeFromNib", + "boolValueSafe", + "bs_encoded", + "bs_isPlistableType", + "bs_secureEncoded", + "cl_json_serializeKey", + "class", + "classCode", + "classDescription", + "classForArchiver", + "classForCoder", + "classForKeyedArchiver", + "classForPortCoder", + "className", + "clearProperties", + "copy", + "dealloc", + "debugDescription", + "defaultAccessibilityTraits", + "description", + "doubleValueSafe", + "entityName", + "exposedBindings", + "finalize", + "finishObserving", + "flushKeyBindings", + "hash", + "init", + "int64ValueSafe", + "isAccessibilityElement", + "isAccessibilityElementByDefault", + "isElementAccessibilityExposedToInterfaceBuilder", + "isFault", + "isNSArray__", + "isNSCFConstantString__", + "isNSData__", + "isNSDate__", + "isNSDictionary__", + "isNSNumber__", + "isNSObject__", + "isNSOrderedSet__", + "isNSSet__", + "isNSString__", + "isNSTimeZone__", + "isNSValue__", + "isProxy", + "mutableCopy", + "nilValueForKey", + "objectSpecifier", + "observationInfo", + "pep_onDetachedThread", + "pep_onMainThread", + "pep_onMainThreadIfNecessary", + "prepareForInterfaceBuilder", + "release", + "releaseOnMainThread", + "retain", + "retainCount", + "retainWeakReference", + "scriptingProperties", + "self", + "shouldGroupAccessibilityChildren", + "storedAccessibilityActivationPoint", + "storedAccessibilityContainerType", + "storedAccessibilityElementsHidden", + "storedAccessibilityFrame", + "storedAccessibilityNavigationStyle", + "storedAccessibilityTraits", + "storedAccessibilityViewIsModal", + "storedIsAccessibilityElement", + "storedShouldGroupAccessibilityChildren", + "stringValueSafe", + "superclass", + "toManyRelationshipKeys", + "toOneRelationshipKeys", + "traitStorageList", + "un_safeBoolValue", + "userInterfaceItemIdentifier", + "utf8ValueSafe", + "valuesForKeysWithDictionary", + "zone", +// Protocol: CAAnimatableValue +// Protocol: CARenderValue +// Protocol: NSObject +// Protocol: ROCKRemoteInvocationInterface +}; diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc index 5197ff63a3..f44c17d31e 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc @@ -1,140 +1,140 @@ -// 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_oneof.h> -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor) - : descriptor_(descriptor) { - variables_["enum_name"] = OneofEnumName(descriptor_); - variables_["name"] = OneofName(descriptor_); - variables_["capitalized_name"] = OneofNameCapitalized(descriptor_); - variables_["raw_index"] = StrCat(descriptor_->index()); - const Descriptor* msg_descriptor = descriptor_->containing_type(); - variables_["owning_message_class"] = ClassName(msg_descriptor); - - TProtoStringType comments; - SourceLocation location; - if (descriptor_->GetSourceLocation(&location)) { - comments = BuildCommentsString(location, true); - } else { - comments = ""; - } - variables_["comments"] = comments; -} - -OneofGenerator::~OneofGenerator() {} - -void OneofGenerator::SetOneofIndexBase(int index_base) { - int index = descriptor_->index() + index_base; - // Flip the sign to mark it as a oneof. - variables_["index"] = StrCat(-index); -} - -void OneofGenerator::GenerateCaseEnum(io::Printer* printer) { - printer->Print( - variables_, - "typedef GPB_ENUM($enum_name$) {\n"); - printer->Indent(); - printer->Print( - variables_, - "$enum_name$_GPBUnsetOneOfCase = 0,\n"); - TProtoStringType enum_name = variables_["enum_name"]; - for (int j = 0; j < descriptor_->field_count(); j++) { - const FieldDescriptor* field = descriptor_->field(j); - TProtoStringType field_name = FieldNameCapitalized(field); - printer->Print( - "$enum_name$_$field_name$ = $field_number$,\n", - "enum_name", enum_name, - "field_name", field_name, - "field_number", StrCat(field->number())); - } - printer->Outdent(); - printer->Print( - "};\n" - "\n"); -} - -void OneofGenerator::GeneratePublicCasePropertyDeclaration( - io::Printer* printer) { - printer->Print( - variables_, - "$comments$" - "@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n" - "\n"); -} - -void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) { - printer->Print( - variables_, - "/**\n" - " * Clears whatever value was set for the oneof '$name$'.\n" - " **/\n" - "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n"); -} - -void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) { - printer->Print( - variables_, - "@dynamic $name$OneOfCase;\n"); -} - -void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) { - printer->Print( - variables_, - "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n" - " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" - " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n" - " GPBClearOneof(message, oneof);\n" - "}\n"); -} - -TProtoStringType OneofGenerator::DescriptorName(void) const { - return variables_.find("name")->second; -} - -TProtoStringType OneofGenerator::HasIndexAsString(void) const { - return variables_.find("index")->second; -} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_oneof.h> +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor) + : descriptor_(descriptor) { + variables_["enum_name"] = OneofEnumName(descriptor_); + variables_["name"] = OneofName(descriptor_); + variables_["capitalized_name"] = OneofNameCapitalized(descriptor_); + variables_["raw_index"] = StrCat(descriptor_->index()); + const Descriptor* msg_descriptor = descriptor_->containing_type(); + variables_["owning_message_class"] = ClassName(msg_descriptor); + + TProtoStringType comments; + SourceLocation location; + if (descriptor_->GetSourceLocation(&location)) { + comments = BuildCommentsString(location, true); + } else { + comments = ""; + } + variables_["comments"] = comments; +} + +OneofGenerator::~OneofGenerator() {} + +void OneofGenerator::SetOneofIndexBase(int index_base) { + int index = descriptor_->index() + index_base; + // Flip the sign to mark it as a oneof. + variables_["index"] = StrCat(-index); +} + +void OneofGenerator::GenerateCaseEnum(io::Printer* printer) { + printer->Print( + variables_, + "typedef GPB_ENUM($enum_name$) {\n"); + printer->Indent(); + printer->Print( + variables_, + "$enum_name$_GPBUnsetOneOfCase = 0,\n"); + TProtoStringType enum_name = variables_["enum_name"]; + for (int j = 0; j < descriptor_->field_count(); j++) { + const FieldDescriptor* field = descriptor_->field(j); + TProtoStringType field_name = FieldNameCapitalized(field); + printer->Print( + "$enum_name$_$field_name$ = $field_number$,\n", + "enum_name", enum_name, + "field_name", field_name, + "field_number", StrCat(field->number())); + } + printer->Outdent(); + printer->Print( + "};\n" + "\n"); +} + +void OneofGenerator::GeneratePublicCasePropertyDeclaration( + io::Printer* printer) { + printer->Print( + variables_, + "$comments$" + "@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n" + "\n"); +} + +void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) { + printer->Print( + variables_, + "/**\n" + " * Clears whatever value was set for the oneof '$name$'.\n" + " **/\n" + "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n"); +} + +void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) { + printer->Print( + variables_, + "@dynamic $name$OneOfCase;\n"); +} + +void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) { + printer->Print( + variables_, + "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n" + " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n" + " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n" + " GPBClearOneof(message, oneof);\n" + "}\n"); +} + +TProtoStringType OneofGenerator::DescriptorName(void) const { + return variables_.find("name")->second; +} + +TProtoStringType OneofGenerator::HasIndexAsString(void) const { + return variables_.find("index")->second; +} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h index 4173a0325c..46d6af09ed 100644 --- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h +++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h @@ -1,76 +1,76 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ - -#include <string> -#include <set> -#include <vector> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/io/printer.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class OneofGenerator { - public: - explicit OneofGenerator(const OneofDescriptor* descriptor); - ~OneofGenerator(); - - OneofGenerator(const OneofGenerator&) = delete; - OneofGenerator& operator=(const OneofGenerator&) = delete; - - void SetOneofIndexBase(int index_base); - - void GenerateCaseEnum(io::Printer* printer); - - void GeneratePublicCasePropertyDeclaration(io::Printer* printer); - void GenerateClearFunctionDeclaration(io::Printer* printer); - - void GeneratePropertyImplementation(io::Printer* printer); - void GenerateClearFunctionImplementation(io::Printer* printer); - - TProtoStringType DescriptorName(void) const; - TProtoStringType HasIndexAsString(void) const; - - private: - const OneofDescriptor* descriptor_; - std::map<TProtoStringType, TProtoStringType> variables_; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ + +#include <string> +#include <set> +#include <vector> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/io/printer.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class OneofGenerator { + public: + explicit OneofGenerator(const OneofDescriptor* descriptor); + ~OneofGenerator(); + + OneofGenerator(const OneofGenerator&) = delete; + OneofGenerator& operator=(const OneofGenerator&) = delete; + + void SetOneofIndexBase(int index_base); + + void GenerateCaseEnum(io::Printer* printer); + + void GeneratePublicCasePropertyDeclaration(io::Printer* printer); + void GenerateClearFunctionDeclaration(io::Printer* printer); + + void GeneratePropertyImplementation(io::Printer* printer); + void GenerateClearFunctionImplementation(io::Printer* printer); + + TProtoStringType DescriptorName(void) const; + TProtoStringType HasIndexAsString(void) const; + + private: + const OneofDescriptor* descriptor_; + std::map<TProtoStringType, TProtoStringType> variables_; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__ 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 b8f4faebca..3d64c061b1 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 @@ -1,190 +1,190 @@ -// 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 <map> -#include <string> - -#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> -#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/wire_format_lite.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -using internal::WireFormat; -using internal::WireFormatLite; - -namespace { - -const char* PrimitiveTypeName(const FieldDescriptor* descriptor) { - ObjectiveCType type = GetObjectiveCType(descriptor); - switch (type) { - case OBJECTIVECTYPE_INT32: - return "int32_t"; - case OBJECTIVECTYPE_UINT32: - return "uint32_t"; - case OBJECTIVECTYPE_INT64: - return "int64_t"; - case OBJECTIVECTYPE_UINT64: - return "uint64_t"; - case OBJECTIVECTYPE_FLOAT: - return "float"; - case OBJECTIVECTYPE_DOUBLE: - return "double"; - case OBJECTIVECTYPE_BOOLEAN: - return "BOOL"; - case OBJECTIVECTYPE_STRING: - return "NSString"; - case OBJECTIVECTYPE_DATA: - return "NSData"; - case OBJECTIVECTYPE_ENUM: - return "int32_t"; - case OBJECTIVECTYPE_MESSAGE: - return NULL; // Messages go through objectivec_message_field.cc|h. - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { - ObjectiveCType type = GetObjectiveCType(descriptor); - switch (type) { - case OBJECTIVECTYPE_INT32: - return "Int32"; - case OBJECTIVECTYPE_UINT32: - return "UInt32"; - case OBJECTIVECTYPE_INT64: - return "Int64"; - case OBJECTIVECTYPE_UINT64: - return "UInt64"; - case OBJECTIVECTYPE_FLOAT: - return "Float"; - case OBJECTIVECTYPE_DOUBLE: - return "Double"; - case OBJECTIVECTYPE_BOOLEAN: - return "Bool"; - case OBJECTIVECTYPE_STRING: - return ""; // Want NSArray - case OBJECTIVECTYPE_DATA: - return ""; // Want NSArray - case OBJECTIVECTYPE_ENUM: - return "Enum"; - case OBJECTIVECTYPE_MESSAGE: - // Want NSArray (but goes through objectivec_message_field.cc|h). - return ""; - } - - // Some compilers report reaching end of function even though all cases of - // the enum are handed in the switch. - GOOGLE_LOG(FATAL) << "Can't get here."; - return NULL; -} - -void SetPrimitiveVariables(const FieldDescriptor* descriptor, - std::map<TProtoStringType, TProtoStringType>* variables) { - TProtoStringType primitive_name = PrimitiveTypeName(descriptor); - (*variables)["type"] = primitive_name; - (*variables)["storage_type"] = primitive_name; -} - -} // namespace - -PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { - SetPrimitiveVariables(descriptor, &variables_); -} - -PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} - -void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration( - io::Printer* printer) const { - if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { - // Nothing, BOOLs are stored in the has bits. - } else { - SingleFieldGenerator::GenerateFieldStorageDeclaration(printer); - } -} - -int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { - if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { - // Reserve a bit for the storage of the boolean. - return 1; - } - return 0; -} - -void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { - if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { - // Set into the offset the has bit to use for the actual value. - variables_["storage_offset_value"] = StrCat(has_base); - variables_["storage_offset_comment"] = - " // Stored in _has_storage_ to save space."; - } -} - -PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { - SetPrimitiveVariables(descriptor, &variables_); - variables_["property_storage_attribute"] = "copy"; -} - -PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} - -RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { - SetPrimitiveVariables(descriptor, &variables_); - - TProtoStringType base_name = PrimitiveArrayTypeName(descriptor); - if (base_name.length()) { - variables_["array_storage_type"] = "GPB" + base_name + "Array"; - } else { - variables_["array_storage_type"] = "NSMutableArray"; - variables_["array_property_type"] = - "NSMutableArray<" + variables_["storage_type"] + "*>"; - } -} - -RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google +// 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 <map> +#include <string> + +#include <google/protobuf/compiler/objectivec/objectivec_helpers.h> +#include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h> +#include <google/protobuf/io/printer.h> +#include <google/protobuf/stubs/strutil.h> +#include <google/protobuf/wire_format.h> +#include <google/protobuf/wire_format_lite.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +using internal::WireFormat; +using internal::WireFormatLite; + +namespace { + +const char* PrimitiveTypeName(const FieldDescriptor* descriptor) { + ObjectiveCType type = GetObjectiveCType(descriptor); + switch (type) { + case OBJECTIVECTYPE_INT32: + return "int32_t"; + case OBJECTIVECTYPE_UINT32: + return "uint32_t"; + case OBJECTIVECTYPE_INT64: + return "int64_t"; + case OBJECTIVECTYPE_UINT64: + return "uint64_t"; + case OBJECTIVECTYPE_FLOAT: + return "float"; + case OBJECTIVECTYPE_DOUBLE: + return "double"; + case OBJECTIVECTYPE_BOOLEAN: + return "BOOL"; + case OBJECTIVECTYPE_STRING: + return "NSString"; + case OBJECTIVECTYPE_DATA: + return "NSData"; + case OBJECTIVECTYPE_ENUM: + return "int32_t"; + case OBJECTIVECTYPE_MESSAGE: + return NULL; // Messages go through objectivec_message_field.cc|h. + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) { + ObjectiveCType type = GetObjectiveCType(descriptor); + switch (type) { + case OBJECTIVECTYPE_INT32: + return "Int32"; + case OBJECTIVECTYPE_UINT32: + return "UInt32"; + case OBJECTIVECTYPE_INT64: + return "Int64"; + case OBJECTIVECTYPE_UINT64: + return "UInt64"; + case OBJECTIVECTYPE_FLOAT: + return "Float"; + case OBJECTIVECTYPE_DOUBLE: + return "Double"; + case OBJECTIVECTYPE_BOOLEAN: + return "Bool"; + case OBJECTIVECTYPE_STRING: + return ""; // Want NSArray + case OBJECTIVECTYPE_DATA: + return ""; // Want NSArray + case OBJECTIVECTYPE_ENUM: + return "Enum"; + case OBJECTIVECTYPE_MESSAGE: + // Want NSArray (but goes through objectivec_message_field.cc|h). + return ""; + } + + // Some compilers report reaching end of function even though all cases of + // the enum are handed in the switch. + GOOGLE_LOG(FATAL) << "Can't get here."; + return NULL; +} + +void SetPrimitiveVariables(const FieldDescriptor* descriptor, + std::map<TProtoStringType, TProtoStringType>* variables) { + TProtoStringType primitive_name = PrimitiveTypeName(descriptor); + (*variables)["type"] = primitive_name; + (*variables)["storage_type"] = primitive_name; +} + +} // namespace + +PrimitiveFieldGenerator::PrimitiveFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : SingleFieldGenerator(descriptor, options) { + SetPrimitiveVariables(descriptor, &variables_); +} + +PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} + +void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration( + io::Printer* printer) const { + if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { + // Nothing, BOOLs are stored in the has bits. + } else { + SingleFieldGenerator::GenerateFieldStorageDeclaration(printer); + } +} + +int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const { + if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { + // Reserve a bit for the storage of the boolean. + return 1; + } + return 0; +} + +void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { + if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) { + // Set into the offset the has bit to use for the actual value. + variables_["storage_offset_value"] = StrCat(has_base); + variables_["storage_offset_comment"] = + " // Stored in _has_storage_ to save space."; + } +} + +PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : ObjCObjFieldGenerator(descriptor, options) { + SetPrimitiveVariables(descriptor, &variables_); + variables_["property_storage_attribute"] = "copy"; +} + +PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} + +RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( + const FieldDescriptor* descriptor, const Options& options) + : RepeatedFieldGenerator(descriptor, options) { + SetPrimitiveVariables(descriptor, &variables_); + + TProtoStringType base_name = PrimitiveArrayTypeName(descriptor); + if (base_name.length()) { + variables_["array_storage_type"] = "GPB" + base_name + "Array"; + } else { + variables_["array_storage_type"] = "NSMutableArray"; + variables_["array_property_type"] = + "NSMutableArray<" + variables_["storage_type"] + "*>"; + } +} + +RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google 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 642f2d6323..0e4064de72 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 @@ -1,95 +1,95 @@ -// 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. - -#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ -#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ - -#include <map> -#include <string> -#include <google/protobuf/compiler/objectivec/objectivec_field.h> - -namespace google { -namespace protobuf { -namespace compiler { -namespace objectivec { - -class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual ~PrimitiveFieldGenerator(); - - PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; - PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete; - - virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; - - virtual int ExtraRuntimeHasBitsNeeded(void) const; - virtual void SetExtraRuntimeHasBitsBase(int index_base); -}; - -class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual ~PrimitiveObjFieldGenerator(); - - PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; - PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) = - delete; -}; - -class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); - - protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); - virtual ~RepeatedPrimitiveFieldGenerator(); - - RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = - delete; - RepeatedPrimitiveFieldGenerator& operator=( - const RepeatedPrimitiveFieldGenerator&) = delete; -}; - -} // namespace objectivec -} // namespace compiler -} // namespace protobuf -} // namespace google - -#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ +// 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. + +#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ +#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ + +#include <map> +#include <string> +#include <google/protobuf/compiler/objectivec/objectivec_field.h> + +namespace google { +namespace protobuf { +namespace compiler { +namespace objectivec { + +class PrimitiveFieldGenerator : public SingleFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + protected: + PrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual ~PrimitiveFieldGenerator(); + + PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; + PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete; + + virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const; + + virtual int ExtraRuntimeHasBitsNeeded(void) const; + virtual void SetExtraRuntimeHasBitsBase(int index_base); +}; + +class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + protected: + PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual ~PrimitiveObjFieldGenerator(); + + PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; + PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) = + delete; +}; + +class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, + const Options& options); + + protected: + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, + const Options& options); + virtual ~RepeatedPrimitiveFieldGenerator(); + + RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = + delete; + RepeatedPrimitiveFieldGenerator& operator=( + const RepeatedPrimitiveFieldGenerator&) = delete; +}; + +} // namespace objectivec +} // namespace compiler +} // namespace protobuf +} // namespace google + +#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__ |