aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/protoc/src/google/protobuf/compiler/objectivec
diff options
context:
space:
mode:
authornechda <nechda@yandex-team.com>2024-08-29 23:50:27 +0300
committernechda <nechda@yandex-team.com>2024-08-30 00:05:25 +0300
commite10d6638f07a82edae3ea8197b9f5c0affcc07ea (patch)
tree571c38cec05813766a1ad290c9d51ce7ace52919 /contrib/libs/protoc/src/google/protobuf/compiler/objectivec
parente79b38f2bbbf78d295d1901d2a79f898022d5224 (diff)
downloadydb-e10d6638f07a82edae3ea8197b9f5c0affcc07ea.tar.gz
Update cpp-protobuf to 22.5
Привет!\ Этот PR переключат cpp & python библиотеки protobuf на версию 22.5 Если у вас возникли проблемы после влития этого PR: 1. Если начали падать канон тесты, то проведите их переканонизацию 2. Прочитайте <https://wiki.yandex-team.ru/users/nechda/obnovlenie-cpp-protobuf-22.5/> страничку с основными изменениями 3. Если страничка в вики не помогла, то пишите в [DEVTOOLSSUPPORT](https://st.yandex-team.ru/DEVTOOLSSUPPORT) 7fecade616c20a841b9e9af7b7998bdfc8d2807d
Diffstat (limited to 'contrib/libs/protoc/src/google/protobuf/compiler/objectivec')
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc)156
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h)15
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc)58
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h)22
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc)93
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h)20
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc)188
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h)70
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.cc736
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h)102
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc)199
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h)15
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.cc399
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.h155
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.cc255
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.h82
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.cc212
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.h74
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/map_field.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc)88
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/map_field.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h)19
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.cc631
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h)54
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc)50
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h)31
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.cc1247
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.h179
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/nsobject_methods.h227
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc681
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc2044
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.h355
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc633
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h197
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/oneof.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc)64
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/oneof.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h)25
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/options.h57
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/primitive_field.cc (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc)49
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/primitive_field.h (renamed from contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h)14
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.cc254
-rw-r--r--contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.h83
39 files changed, 5385 insertions, 4448 deletions
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc
index 39c7829576..5b23792af4 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.cc
@@ -28,23 +28,38 @@
// (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 "google/protobuf/compiler/objectivec/enum.h"
+
+#include <algorithm>
+#include <limits>
#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()
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/compiler/objectivec/text_format_decode_data.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
+namespace {
+TProtoStringType SafelyPrintIntToCode(int v) {
+ if (v == std::numeric_limits<int>::min()) {
+ // Some compilers try to parse -2147483648 as two tokens and then get spicy
+ // about the fact that +2147483648 cannot be represented as an int.
+ return y_absl::StrCat(v + 1, " - 1");
+ } else {
+ return y_absl::StrCat(v);
+ }
+}
+} // namespace
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
- : descriptor_(descriptor),
- name_(EnumName(descriptor_)) {
+ : 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.
@@ -54,7 +69,7 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
// 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;
+ y_absl::flat_hash_set<TProtoStringType> value_names;
for (int i = 0; i < descriptor_->value_count(); i++) {
const EnumValueDescriptor* value = descriptor_->value(i);
@@ -65,20 +80,15 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
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()) {
+ if (!value_names.insert(EnumValueName(value)).second) {
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) {
+void EnumGenerator::GenerateHeader(io::Printer* printer) const {
TProtoStringType enum_comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
@@ -106,45 +116,49 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
// 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->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())) {
+ if (!descriptor_->is_closed()) {
// 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_);
+ // clang-format off
+ "/**\n"
+ " * Value used if any message's field encounters a value that is not defined\n"
+ " * by this enum. The message will also have C functions to get/set the rawValue\n"
+ " * of the field.\n"
+ " **/\n"
+ "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
+ // clang-format on
+ "name", name_);
}
for (int i = 0; i < all_values_.size(); i++) {
- if (alias_values_to_skip_.find(all_values_[i]) != alias_values_to_skip_.end()) {
+ if (alias_values_to_skip_.find(all_values_[i]) !=
+ alias_values_to_skip_.end()) {
continue;
}
if (all_values_[i]->GetSourceLocation(&location)) {
- TProtoStringType comments = BuildCommentsString(location, true).c_str();
+ TProtoStringType comments = BuildCommentsString(location, true);
if (comments.length() > 0) {
if (i > 0) {
printer->Print("\n");
}
- printer->Print(comments.c_str());
+ printer->Print(comments);
}
}
- 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->Print("$name$$deprecated_attribute$ = $value$,\n", "name",
+ EnumValueName(all_values_[i]), "deprecated_attribute",
+ GetOptionalDeprecatedAttribute(all_values_[i]), "value",
+ SafelyPrintIntToCode(all_values_[i]->number()));
}
printer->Outdent();
printer->Print(
+ // clang-format off
"};\n"
"\n"
"GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
@@ -154,11 +168,12 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
" * the time this source was generated.\n"
" **/\n"
"BOOL $name$_IsValidValue(arc_i32 value);\n"
+ // clang-format on
"\n",
"name", name_);
}
-void EnumGenerator::GenerateSource(io::Printer* printer) {
+void EnumGenerator::GenerateSource(io::Printer* printer) const {
printer->Print(
"#pragma mark - Enum $name$\n"
"\n",
@@ -184,38 +199,47 @@ void EnumGenerator::GenerateSource(io::Printer* printer) {
}
printer->Print(
+ // clang-format off
"GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
" static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n"
- " if (!descriptor) {\n",
+ " if (!descriptor) {\n"
+ " GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\n",
+ // clang-format on
"name", name_);
static const int kBytesPerLine = 40; // allow for escaping
- printer->Print(
- " static const char *valueNames =");
+ 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))));
+ "\n \"$data$\"", "data",
+ EscapeTrigraphs(y_absl::CEscape(text_blob.substr(i, kBytesPerLine))));
}
printer->Print(
";\n"
" static const arc_i32 values[] = {\n");
for (int i = 0; i < all_values_.size(); i++) {
- printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
+ printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
}
printer->Print(" };\n");
if (text_format_decode_data.num_entries() == 0) {
printer->Print(
+ // clang-format off
" GPBEnumDescriptor *worker =\n"
" [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
" valueNames:valueNames\n"
" values:values\n"
" count:(arc_ui32)(sizeof(values) / sizeof(arc_i32))\n"
- " enumVerifier:$name$_IsValidValue];\n",
- "name", name_);
- } else {
- printer->Print(
+ " enumVerifier:$name$_IsValidValue\n"
+ " flags:$flags$];\n",
+ // clang-format on
+ "name", name_, "flags",
+ (descriptor_->is_closed()
+ ? "GPBEnumDescriptorInitializationFlag_IsClosed"
+ : "GPBEnumDescriptorInitializationFlag_None"));
+ } else {
+ printer->Print(
+ // clang-format off
" static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
" GPBEnumDescriptor *worker =\n"
" [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
@@ -223,36 +247,46 @@ void EnumGenerator::GenerateSource(io::Printer* printer) {
" values:values\n"
" count:(arc_ui32)(sizeof(values) / sizeof(arc_i32))\n"
" enumVerifier:$name$_IsValidValue\n"
+ " flags:$flags$\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");
+ // clang-format on
+ "name", name_, "flags",
+ (descriptor_->is_closed()
+ ? "GPBEnumDescriptorInitializationFlag_IsClosed"
+ : "GPBEnumDescriptorInitializationFlag_None"),
+ "extraTextFormatInfo", y_absl::CEscape(text_format_decode_data.Data()));
+ }
+ // clang-format off
+ printer->Print(
+ " GPBEnumDescriptor *expected = nil;\n"
+ " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n"
+ " [worker release];\n"
+ " }\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n");
+ // clang-format on
printer->Print(
+ // clang-format off
"BOOL $name$_IsValidValue(arc_i32 value__) {\n"
" switch (value__) {\n",
+ // clang-format on
"name", name_);
for (int i = 0; i < base_values_.size(); i++) {
- printer->Print(
- " case $name$:\n",
- "name", EnumValueName(base_values_[i]));
+ printer->Print(" case $name$:\n", "name",
+ EnumValueName(base_values_[i]));
}
+ // clang-format off
printer->Print(
" return YES;\n"
" default:\n"
" return NO;\n"
" }\n"
"}\n\n");
+ // clang-format on
}
} // namespace objectivec
} // namespace compiler
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.h
index 4d0404bcb3..962620feba 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum.h
@@ -32,10 +32,11 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
#include <string>
-#include <set>
#include <vector>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
+
+#include "y_absl/container/flat_hash_set.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -45,13 +46,13 @@ namespace objectivec {
class EnumGenerator {
public:
explicit EnumGenerator(const EnumDescriptor* descriptor);
- ~EnumGenerator();
+ ~EnumGenerator() = default;
EnumGenerator(const EnumGenerator&) = delete;
EnumGenerator& operator=(const EnumGenerator&) = delete;
- void GenerateHeader(io::Printer* printer);
- void GenerateSource(io::Printer* printer);
+ void GenerateHeader(io::Printer* printer) const;
+ void GenerateSource(io::Printer* printer) const;
const TProtoStringType& name() const { return name_; }
@@ -59,7 +60,7 @@ class EnumGenerator {
const EnumDescriptor* descriptor_;
std::vector<const EnumValueDescriptor*> base_values_;
std::vector<const EnumValueDescriptor*> all_values_;
- std::set<const EnumValueDescriptor*> alias_values_to_skip_;
+ y_absl::flat_hash_set<const EnumValueDescriptor*> alias_values_to_skip_;
const TProtoStringType name_;
};
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.cc
index bcecc7b373..c470c24158 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.cc
@@ -28,12 +28,14 @@
// (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 "google/protobuf/compiler/objectivec/enum_field.h"
+
#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 "y_absl/container/flat_hash_map.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -42,22 +44,24 @@ namespace objectivec {
namespace {
-void SetEnumVariables(const FieldDescriptor* descriptor,
- std::map<TProtoStringType, TProtoStringType>* variables) {
- TProtoStringType type = EnumName(descriptor->enum_type());
+void SetEnumVariables(
+ const FieldDescriptor* descriptor,
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables) {
+ const TProtoStringType type = EnumName(descriptor->enum_type());
+ const TProtoStringType enum_desc_func = y_absl::StrCat(type, "_EnumDescriptor");
(*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)["property_type"] = y_absl::StrCat("enum ", type);
}
- (*variables)["enum_verifier"] = type + "_IsValidValue";
- (*variables)["enum_desc_func"] = type + "_EnumDescriptor";
+ (*variables)["enum_verifier"] = y_absl::StrCat(type, "_IsValidValue");
+ (*variables)["enum_desc_func"] = enum_desc_func;
(*variables)["dataTypeSpecific_name"] = "enumDescFunc";
- (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"];
+ (*variables)["dataTypeSpecific_value"] = enum_desc_func;
const Descriptor* msg_descriptor = descriptor->containing_type();
(*variables)["owning_message_class"] = ClassName(msg_descriptor);
@@ -69,14 +73,13 @@ EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor)
SetEnumVariables(descriptor, &variables_);
}
-EnumFieldGenerator::~EnumFieldGenerator() {}
-
void EnumFieldGenerator::GenerateCFunctionDeclarations(
io::Printer* printer) const {
- if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+ if (descriptor_->enum_type()->is_closed()) {
return;
}
+ // clang-format off
printer->Print(
variables_,
"/**\n"
@@ -91,12 +94,16 @@ void EnumFieldGenerator::GenerateCFunctionDeclarations(
" **/\n"
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, arc_i32 value);\n"
"\n");
+ // clang-format on
}
void EnumFieldGenerator::GenerateCFunctionImplementations(
io::Printer* printer) const {
- if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return;
+ if (descriptor_->enum_type()->is_closed()) {
+ return;
+ }
+ // clang-format off
printer->Print(
variables_,
"arc_i32 $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n"
@@ -111,13 +118,14 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
" GPBSetMessageRawEnumField(message, field, value);\n"
"}\n"
"\n");
+ // clang-format on
}
void EnumFieldGenerator::DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const {
- SingleFieldGenerator::DetermineForwardDeclarations(
- fwd_decls, include_external_types);
+ SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls,
+ include_external_types);
// If it is an enum defined in a different file (and not a WKT), then we'll
// need a forward declaration for it. When it is in our file, all the enums
// are output before the message, so it will be declared before it is needed.
@@ -126,7 +134,7 @@ void EnumFieldGenerator::DetermineForwardDeclarations(
!IsProtobufLibraryBundledProtoFile(descriptor_->enum_type()->file())) {
// Enum name is already in "storage_type".
const TProtoStringType& name = variable("storage_type");
- fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
+ fwd_decls->insert(y_absl::StrCat("GPB_ENUM_FWD_DECLARE(", name, ");"));
}
}
@@ -137,14 +145,18 @@ RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
variables_["array_storage_type"] = "GPBEnumArray";
}
-RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
-
-void RepeatedEnumFieldGenerator::FinishInitialization(void) {
+void RepeatedEnumFieldGenerator::FinishInitialization() {
RepeatedFieldGenerator::FinishInitialization();
+ TProtoStringType name = variables_["name"];
+ TProtoStringType storage_type = variables_["storage_type"];
variables_["array_comment"] =
- "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
+ y_absl::StrCat("// |", name, "| contains |", storage_type, "|\n");
}
+// NOTE: RepeatedEnumFieldGenerator::DetermineForwardDeclarations isn't needed
+// because `GPBEnumArray` isn't generic (like `NSArray` would be for messages)
+// and thus doesn't reference the type in the header.
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.h
index fea75f7a84..3220df1046 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/enum_field.h
@@ -31,9 +31,10 @@
#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>
+
+#include "y_absl/container/btree_set.h"
+#include "google/protobuf/compiler/objectivec/field.h"
namespace google {
namespace protobuf {
@@ -47,28 +48,25 @@ class EnumFieldGenerator : public SingleFieldGenerator {
EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
public:
- virtual void GenerateCFunctionDeclarations(
- io::Printer* printer) const override;
- virtual void GenerateCFunctionImplementations(
- io::Printer* printer) const override;
- virtual void DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
- bool include_external_types) const override;
+ void GenerateCFunctionDeclarations(io::Printer* printer) const override;
+ void GenerateCFunctionImplementations(io::Printer* printer) const override;
+ void DetermineForwardDeclarations(y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const override;
protected:
explicit EnumFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~EnumFieldGenerator();
+ ~EnumFieldGenerator() override = default;
};
class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
public:
- virtual void FinishInitialization() override;
+ void FinishInitialization() override;
protected:
explicit RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~RepeatedEnumFieldGenerator();
+ ~RepeatedEnumFieldGenerator() override = default;
};
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.cc
index dbbce48952..4da745c9f6 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.cc
@@ -28,38 +28,39 @@
// (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/extension.h"
+
#include <iostream>
+#include <ostream>
+#include <string>
+#include <vector>
-#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>
+#include "y_absl/container/btree_set.h"
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
-ExtensionGenerator::ExtensionGenerator(const TProtoStringType& root_class_name,
+ExtensionGenerator::ExtensionGenerator(y_absl::string_view root_class_name,
const FieldDescriptor* descriptor)
: method_name_(ExtensionMethodName(descriptor)),
- root_class_and_method_name_(root_class_name + "_" + method_name_),
+ root_class_and_method_name_(
+ y_absl::StrCat(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();
- }
+ Y_ABSL_CHECK(!descriptor->is_map())
+ << "error: Extension is a map<>!"
+ << " That used to be blocked by the compiler.";
}
-ExtensionGenerator::~ExtensionGenerator() {}
-
-void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
- std::map<TProtoStringType, TProtoStringType> vars;
+void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) const {
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> vars;
vars["method_name"] = method_name_;
if (IsRetainedName(method_name_)) {
vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
@@ -74,19 +75,23 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
}
// 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");
+ vars["deprecated_attribute"] =
+ GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file());
+ // clang-format off
+ printer->Print(
+ vars,
+ "$comments$"
+ "+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n");
+ // clang-format on
}
void ExtensionGenerator::GenerateStaticVariablesInitialization(
- io::Printer* printer) {
- std::map<TProtoStringType, TProtoStringType> vars;
+ io::Printer* printer) const {
+ y_absl::flat_hash_map<y_absl::string_view, 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());
+ vars["number"] = y_absl::StrCat(descriptor_->number());
std::vector<TProtoStringType> options;
if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
@@ -111,30 +116,33 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
vars["default"] = DefaultValue(descriptor_);
}
TProtoStringType type = GetCapitalizedType(descriptor_);
- vars["extension_type"] = TProtoStringType("GPBDataType") + type;
+ vars["extension_type"] = y_absl::StrCat("GPBDataType", type);
if (objc_type == OBJECTIVECTYPE_ENUM) {
vars["enum_desc_func_name"] =
- EnumName(descriptor_->enum_type()) + "_EnumDescriptor";
+ y_absl::StrCat(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");
+ // clang-format off
+ 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");
+ // clang-format on
}
void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) {
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
TProtoStringType extended_type = ClassName(descriptor_->containing_type());
fwd_decls->insert(ObjCClassDeclaration(extended_type));
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
@@ -144,10 +152,13 @@ void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
}
}
-void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
+void ExtensionGenerator::GenerateRegistrationSource(
+ io::Printer* printer) const {
+ // clang-format off
printer->Print(
"[registry addExtension:$root_class_and_method_name$];\n",
"root_class_and_method_name", root_class_and_method_name_);
+ // clang-format on
}
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.h
index 04e59f9284..1f81d82e74 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_extension.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/extension.h
@@ -31,8 +31,11 @@
#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>
+#include <string>
+
+#include "y_absl/container/btree_set.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -41,17 +44,18 @@ namespace objectivec {
class ExtensionGenerator {
public:
- ExtensionGenerator(const TProtoStringType& root_class_name,
+ ExtensionGenerator(y_absl::string_view root_class_name,
const FieldDescriptor* descriptor);
- ~ExtensionGenerator();
+ ~ExtensionGenerator() = default;
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);
+ void GenerateMembersHeader(io::Printer* printer) const;
+ void GenerateStaticVariablesInitialization(io::Printer* printer) const;
+ void GenerateRegistrationSource(io::Printer* printer) const;
+ void DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const;
private:
TProtoStringType method_name_;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc
index e73a664db1..e72185e794 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.cc
@@ -28,16 +28,24 @@
// (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/field.h"
-#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/stubs/strutil.h>
+#include <iostream>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/log/absl_check.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/enum_field.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/map_field.h"
+#include "google/protobuf/compiler/objectivec/message_field.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/compiler/objectivec/primitive_field.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -46,8 +54,9 @@ namespace objectivec {
namespace {
-void SetCommonFieldVariables(const FieldDescriptor* descriptor,
- std::map<TProtoStringType, TProtoStringType>* variables) {
+void SetCommonFieldVariables(
+ const FieldDescriptor* descriptor,
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables) {
TProtoStringType camel_case_name = FieldName(descriptor);
TProtoStringType raw_field_name;
if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
@@ -73,10 +82,11 @@ void SetCommonFieldVariables(const FieldDescriptor* 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());
+ y_absl::StrCat(classname, "_FieldNumber_", capitalized_name);
+ (*variables)["field_number"] = y_absl::StrCat(descriptor->number());
(*variables)["field_type"] = GetCapitalizedType(descriptor);
- (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
+ (*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");
@@ -89,6 +99,9 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
field_flags.push_back("GPBFieldHasEnumDescriptor");
+ if (descriptor->enum_type()->is_closed()) {
+ field_flags.push_back("GPBFieldClosedEnum");
+ }
}
// It will clear on a zero value if...
// - not repeated/map
@@ -107,18 +120,63 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["dataTypeSpecific_name"] = "clazz";
(*variables)["dataTypeSpecific_value"] = "Nil";
- (*variables)["storage_offset_value"] =
- "(arc_ui32)offsetof(" + classname + "__storage_, " + camel_case_name + ")";
+ (*variables)["storage_offset_value"] = y_absl::StrCat(
+ "(arc_ui32)offsetof(", classname, "__storage_, ", camel_case_name, ")");
(*variables)["storage_offset_comment"] = "";
// Clear some common things so they can be set just when needed.
(*variables)["storage_attribute"] = "";
}
+bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
+ // Repeated fields don't have defaults.
+ if (field->is_repeated()) {
+ return false;
+ }
+
+ // As much as checking field->has_default_value() seems useful, it isn't
+ // because of enums. proto2 syntax allows the first item in an enum (the
+ // default) to be non zero. So checking field->has_default_value() would
+ // result in missing this non zero default. See MessageWithOneBasedEnum in
+ // objectivec/Tests/unittest_objc.proto for a test Message to confirm this.
+
+ // Some proto file set the default to the zero value, so make sure the value
+ // isn't the zero case.
+ switch (field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return field->default_value_int32() != 0;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return field->default_value_uint32() != 0U;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return field->default_value_int64() != 0LL;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return field->default_value_uint64() != 0ULL;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return field->default_value_double() != 0.0;
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return field->default_value_float() != 0.0f;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool();
+ case FieldDescriptor::CPPTYPE_STRING: {
+ const TProtoStringType& default_string = field->default_value_string();
+ return default_string.length() != 0;
+ }
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return field->default_value_enum()->number() != 0;
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ return false;
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return false;
+}
+
} // namespace
FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
- FieldGenerator* result = NULL;
+ FieldGenerator* result = nullptr;
if (field->is_repeated()) {
switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: {
@@ -163,16 +221,11 @@ FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor)
SetCommonFieldVariables(descriptor, &variables_);
}
-FieldGenerator::~FieldGenerator() {}
-
void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
- printer->Print(
- variables_,
- "$field_number_name$ = $field_number$,\n");
+ printer->Print(variables_, "$field_number_name$ = $field_number$,\n");
}
-void FieldGenerator::GenerateCFunctionDeclarations(
- io::Printer* printer) const {
+void FieldGenerator::GenerateCFunctionDeclarations(io::Printer* printer) const {
// Nothing
}
@@ -182,20 +235,21 @@ void FieldGenerator::GenerateCFunctionImplementations(
}
void FieldGenerator::DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const {
// Nothing
}
void FieldGenerator::DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const {
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
// Nothing
}
-void FieldGenerator::GenerateFieldDescription(
- io::Printer* printer, bool include_default) const {
+void FieldGenerator::GenerateFieldDescription(io::Printer* printer,
+ bool include_default) const {
// Printed in the same order as the structure decl.
if (include_default) {
+ // clang-format off
printer->Print(
variables_,
"{\n"
@@ -208,7 +262,9 @@ void FieldGenerator::GenerateFieldDescription(
" .core.flags = $fieldflags$,\n"
" .core.dataType = GPBDataType$field_type$,\n"
"},\n");
+ // clang-format on
} else {
+ // clang-format off
printer->Print(
variables_,
"{\n"
@@ -220,43 +276,37 @@ void FieldGenerator::GenerateFieldDescription(
" .flags = $fieldflags$,\n"
" .dataType = GPBDataType$field_type$,\n"
"},\n");
+ // clang-format on
}
}
void FieldGenerator::SetRuntimeHasBit(int has_index) {
- variables_["has_index"] = StrCat(has_index);
+ variables_["has_index"] = y_absl::StrCat(has_index);
}
-void FieldGenerator::SetNoHasBit(void) {
- variables_["has_index"] = "GPBNoHasBit";
-}
+void FieldGenerator::SetNoHasBit() { variables_["has_index"] = "GPBNoHasBit"; }
-int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
- return 0;
-}
+int FieldGenerator::ExtraRuntimeHasBitsNeeded() 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();
+ Y_ABSL_LOG(FATAL)
+ << "Error: should have overridden SetExtraRuntimeHasBitsBase().";
}
void FieldGenerator::SetOneofIndexBase(int index_base) {
const OneofDescriptor* oneof = descriptor_->real_containing_oneof();
- if (oneof != NULL) {
+ if (oneof != nullptr) {
int index = oneof->index() + index_base;
// Flip the sign to mark it as a oneof.
- variables_["has_index"] = StrCat(-index);
+ variables_["has_index"] = y_absl::StrCat(-index);
}
}
-bool FieldGenerator::WantsHasProperty(void) const {
+bool FieldGenerator::WantsHasProperty() const {
return descriptor_->has_presence() && !descriptor_->real_containing_oneof();
}
-void FieldGenerator::FinishInitialization(void) {
+void FieldGenerator::FinishInitialization() {
// If "property_type" wasn't set, make it "storage_type".
if ((variables_.find("property_type") == variables_.end()) &&
(variables_.find("storage_type") != variables_.end())) {
@@ -269,8 +319,6 @@ SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor)
// Nothing
}
-SingleFieldGenerator::~SingleFieldGenerator() {}
-
void SingleFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const {
printer->Print(variables_, "$storage_type$ $name$;\n");
@@ -279,15 +327,19 @@ void SingleFieldGenerator::GenerateFieldStorageDeclaration(
void SingleFieldGenerator::GeneratePropertyDeclaration(
io::Printer* printer) const {
printer->Print(variables_, "$comments$");
+ // clang-format off
printer->Print(
variables_,
- "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
- "\n");
+ "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n");
+ // clang-format on
if (WantsHasProperty()) {
+ // clang-format off
printer->Print(
variables_,
"@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ // clang-format on
}
+ printer->Print("\n");
}
void SingleFieldGenerator::GeneratePropertyImplementation(
@@ -299,7 +351,7 @@ void SingleFieldGenerator::GeneratePropertyImplementation(
}
}
-bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
+bool SingleFieldGenerator::RuntimeUsesHasBit() const {
if (descriptor_->real_containing_oneof()) {
// The oneof tracks what is set instead.
return false;
@@ -315,8 +367,6 @@ ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor)
}
}
-ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
-
void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const {
printer->Print(variables_, "$storage_type$ *$name$;\n");
@@ -324,26 +374,30 @@ void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
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
+ // it uses pointers and deals with Objective-C's rules around storage name
// conventions (init*, new*, etc.)
printer->Print(variables_, "$comments$");
+ // clang-format off
printer->Print(
variables_,
"@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
+ // clang-format on
if (WantsHasProperty()) {
+ // clang-format off
printer->Print(
variables_,
"/** Test to see if @c $name$ has been set. */\n"
"@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ // clang-format on
}
if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
printer->Print(variables_,
- "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ "- ($property_type$ *)$name$ "
+ "GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
}
printer->Print("\n");
}
@@ -355,9 +409,7 @@ RepeatedFieldGenerator::RepeatedFieldGenerator(
variables_["array_comment"] = "";
}
-RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
-
-void RepeatedFieldGenerator::FinishInitialization(void) {
+void RepeatedFieldGenerator::FinishInitialization() {
FieldGenerator::FinishInitialization();
if (variables_.find("array_property_type") == variables_.end()) {
variables_["array_property_type"] = variable("array_storage_type");
@@ -376,30 +428,33 @@ void RepeatedFieldGenerator::GeneratePropertyImplementation(
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
+ // dealing with needing Objective-C's rules around storage name conventions
// (init*, new*, etc.)
+ // clang-format off
printer->Print(
variables_,
"$comments$"
"$array_comment$"
"@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
- "/** The number of items in @c $name$ without causing the array to be created. */\n"
+ "/** The number of items in @c $name$ without causing the container to be created. */\n"
"@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
+ // clang-format on
if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
+ // clang-format off
printer->Print(variables_,
"- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ // clang-format on
}
printer->Print("\n");
}
-bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
+bool RepeatedFieldGenerator::RuntimeUsesHasBit() const {
return false; // The array (or map/dict) having anything is what is used.
}
@@ -409,8 +464,7 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
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)));
+ field_generators_[i].reset(FieldGenerator::Make(descriptor->field(i)));
}
for (int i = 0; i < descriptor->extension_count(); i++) {
extension_generators_[i].reset(
@@ -418,11 +472,9 @@ FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
}
}
-FieldGeneratorMap::~FieldGeneratorMap() {}
-
const FieldGenerator& FieldGeneratorMap::get(
const FieldDescriptor* field) const {
- GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ Y_ABSL_CHECK_EQ(field->containing_type(), descriptor_);
return *field_generators_[field->index()];
}
@@ -430,7 +482,7 @@ const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
return *extension_generators_[index];
}
-int FieldGeneratorMap::CalculateHasBits(void) {
+int FieldGeneratorMap::CalculateHasBits() {
int total_bits = 0;
for (int i = 0; i < descriptor_->field_count(); i++) {
if (field_generators_[i]->RuntimeUsesHasBit()) {
@@ -454,7 +506,7 @@ void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
}
}
-bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const {
+bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault() const {
for (int i = 0; i < descriptor_->field_count(); i++) {
if (HasNonZeroDefaultValue(descriptor_->field(i))) {
return true;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.h
index 3e968946fa..0450065133 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/field.h
@@ -31,10 +31,15 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
-#include <map>
+#include <memory>
#include <string>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
+#include <vector>
+
+#include "y_absl/container/btree_set.h"
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/strings/match.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -45,7 +50,7 @@ class FieldGenerator {
public:
static FieldGenerator* Make(const FieldDescriptor* field);
- virtual ~FieldGenerator();
+ virtual ~FieldGenerator() = default;
FieldGenerator(const FieldGenerator&) = delete;
FieldGenerator& operator=(const FieldGenerator&) = delete;
@@ -64,21 +69,21 @@ class FieldGenerator {
// Exposed for subclasses, should always call it on the parent class also.
virtual void DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const;
virtual void DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const;
+ y_absl::btree_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 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;
+ virtual bool RuntimeUsesHasBit() const = 0;
void SetRuntimeHasBit(int has_index);
- void SetNoHasBit(void);
- virtual int ExtraRuntimeHasBitsNeeded(void) const;
+ void SetNoHasBit();
+ virtual int ExtraRuntimeHasBitsNeeded() const;
virtual void SetExtraRuntimeHasBitsBase(int index_base);
void SetOneofIndexBase(int index_base);
@@ -88,8 +93,7 @@ class FieldGenerator {
bool needs_textformat_name_support() const {
const TProtoStringType& field_flags = variable("fieldflags");
- return field_flags.find("GPBFieldTextFormatNameCustom") !=
- TProtoStringType::npos;
+ return y_absl::StrContains(field_flags, "GPBFieldTextFormatNameCustom");
}
TProtoStringType generated_objc_name() const { return variable("name"); }
TProtoStringType raw_field_name() const { return variable("raw_field_name"); }
@@ -97,26 +101,26 @@ class FieldGenerator {
protected:
explicit FieldGenerator(const FieldDescriptor* descriptor);
- virtual void FinishInitialization(void);
- bool WantsHasProperty(void) const;
+ virtual void FinishInitialization();
+ bool WantsHasProperty() const;
const FieldDescriptor* descriptor_;
- std::map<TProtoStringType, TProtoStringType> variables_;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> variables_;
};
class SingleFieldGenerator : public FieldGenerator {
public:
- virtual ~SingleFieldGenerator();
+ ~SingleFieldGenerator() override = default;
SingleFieldGenerator(const SingleFieldGenerator&) = delete;
SingleFieldGenerator& operator=(const SingleFieldGenerator&) = delete;
- virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
- virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+ void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ void GeneratePropertyDeclaration(io::Printer* printer) const override;
- virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+ void GeneratePropertyImplementation(io::Printer* printer) const override;
- virtual bool RuntimeUsesHasBit(void) const override;
+ bool RuntimeUsesHasBit() const override;
protected:
explicit SingleFieldGenerator(const FieldDescriptor* descriptor);
@@ -125,13 +129,13 @@ class SingleFieldGenerator : public FieldGenerator {
// Subclass with common support for when the field ends up as an ObjC Object.
class ObjCObjFieldGenerator : public SingleFieldGenerator {
public:
- virtual ~ObjCObjFieldGenerator();
+ ~ObjCObjFieldGenerator() override = default;
ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete;
ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete;
- virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
- virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+ void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ void GeneratePropertyDeclaration(io::Printer* printer) const override;
protected:
explicit ObjCObjFieldGenerator(const FieldDescriptor* descriptor);
@@ -139,28 +143,28 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator {
class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
public:
- virtual ~RepeatedFieldGenerator();
+ ~RepeatedFieldGenerator() override = default;
RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete;
RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete;
- virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
- virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+ void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ void GeneratePropertyDeclaration(io::Printer* printer) const override;
- virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+ void GeneratePropertyImplementation(io::Printer* printer) const override;
- virtual bool RuntimeUsesHasBit(void) const override;
+ bool RuntimeUsesHasBit() const override;
protected:
explicit RepeatedFieldGenerator(const FieldDescriptor* descriptor);
- virtual void FinishInitialization(void) override;
+ void FinishInitialization() override;
};
// Convenience class which constructs FieldGenerators for a Descriptor.
class FieldGeneratorMap {
public:
explicit FieldGeneratorMap(const Descriptor* descriptor);
- ~FieldGeneratorMap();
+ ~FieldGeneratorMap() = default;
FieldGeneratorMap(const FieldGeneratorMap&) = delete;
FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete;
@@ -169,12 +173,12 @@ class FieldGeneratorMap {
const FieldGenerator& get_extension(int index) const;
// Assigns the has bits and returns the number of bits needed.
- int CalculateHasBits(void);
+ int CalculateHasBits();
void SetOneofIndexBase(int index_base);
// Check if any field of this message has a non zero default.
- bool DoesAnyFieldHaveNonZeroDefault(void) const;
+ bool DoesAnyFieldHaveNonZeroDefault() const;
private:
const Descriptor* descriptor_;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.cc
new file mode 100644
index 0000000000..06be7c9cec
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.cc
@@ -0,0 +1,736 @@
+// 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/file.h"
+
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <iterator>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "y_absl/container/btree_set.h"
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/strings/str_cat.h"
+#include "y_absl/strings/str_join.h"
+#include "google/protobuf/compiler/objectivec/enum.h"
+#include "google/protobuf/compiler/objectivec/extension.h"
+#include "google/protobuf/compiler/objectivec/import_writer.h"
+#include "google/protobuf/compiler/objectivec/message.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.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 {
+
+namespace {
+
+// This is also found in GPBBootstrap.h, and needs to be kept in sync.
+const arc_i32 GOOGLE_PROTOBUF_OBJC_VERSION = 30007;
+
+const char* kHeaderExtension = ".pbobjc.h";
+
+// 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 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;
+}
+
+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;
+}
+
+struct FileDescriptorsOrderedByName {
+ inline bool operator()(const FileDescriptor* a,
+ const FileDescriptor* b) const {
+ return a->name() < b->name();
+ }
+};
+
+void MakeDescriptors(
+ const Descriptor* descriptor, const TProtoStringType& file_description_name,
+ std::vector<std::unique_ptr<EnumGenerator>>* enum_generators,
+ std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators,
+ std::vector<std::unique_ptr<MessageGenerator>>* message_generators) {
+ for (int i = 0; i < descriptor->enum_type_count(); i++) {
+ enum_generators->emplace_back(
+ std::make_unique<EnumGenerator>(descriptor->enum_type(i)));
+ }
+ for (int i = 0; i < descriptor->nested_type_count(); i++) {
+ message_generators->emplace_back(std::make_unique<MessageGenerator>(
+ file_description_name, descriptor->nested_type(i)));
+ message_generators->back()->AddExtensionGenerators(extension_generators);
+ MakeDescriptors(descriptor->nested_type(i), file_description_name,
+ enum_generators, extension_generators, message_generators);
+ }
+}
+
+} // namespace
+
+const FileGenerator::CommonState::MinDepsEntry&
+FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
+ const FileDescriptor* file) {
+ auto it = deps_info_cache.find(file);
+ if (it != deps_info_cache.end()) {
+ return it->second;
+ }
+
+ y_absl::flat_hash_set<const FileDescriptor*> min_deps_collector;
+ y_absl::flat_hash_set<const FileDescriptor*> transitive_deps_collector;
+ y_absl::flat_hash_set<const FileDescriptor*> to_prune;
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ MinDepsEntry dep_info =
+ CollectMinimalFileDepsContainingExtensionsInternal(dep);
+
+ // Everything the dep covered, this file will also cover.
+ transitive_deps_collector.insert(dep_info.transitive_deps.begin(),
+ dep_info.transitive_deps.end());
+ // Prune everything from the dep's covered list in case another dep lists it
+ // as a min dep.
+ to_prune.insert(dep_info.transitive_deps.begin(),
+ dep_info.transitive_deps.end());
+
+ // Does the dep have any extensions...
+ if (dep_info.has_extensions) {
+ // Yes -> Add this file, prune its min_deps and add them to the covered
+ // deps.
+ min_deps_collector.insert(dep);
+ to_prune.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
+ transitive_deps_collector.insert(dep_info.min_deps.begin(),
+ dep_info.min_deps.end());
+ } else {
+ // No -> Just use its min_deps.
+ min_deps_collector.insert(dep_info.min_deps.begin(),
+ dep_info.min_deps.end());
+ }
+ }
+
+ const bool file_has_exts = FileContainsExtensions(file);
+
+ // Fast path: if nothing to prune or there was only one dep, the prune work is
+ // a waste, skip it.
+ if (to_prune.empty() || file->dependency_count() == 1) {
+ return deps_info_cache
+ .insert(
+ {file,
+ {file_has_exts, min_deps_collector, transitive_deps_collector}})
+ .first->second;
+ }
+
+ y_absl::flat_hash_set<const FileDescriptor*> min_deps;
+ std::copy_if(min_deps_collector.begin(), min_deps_collector.end(),
+ std::inserter(min_deps, min_deps.begin()),
+ [&](const FileDescriptor* value) {
+ return to_prune.find(value) == to_prune.end();
+ });
+ return deps_info_cache
+ .insert({file, {file_has_exts, min_deps, transitive_deps_collector}})
+ .first->second;
+}
+
+// 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).
+std::vector<const FileDescriptor*>
+FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions(
+ const FileDescriptor* file) {
+ y_absl::flat_hash_set<const FileDescriptor*> min_deps =
+ CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps;
+ // Sort the list since pointer order isn't stable across runs.
+ std::vector<const FileDescriptor*> result(min_deps.begin(), min_deps.end());
+ std::sort(result.begin(), result.end(), FileDescriptorsOrderedByName());
+ return result;
+}
+
+FileGenerator::FileGenerator(const FileDescriptor* file,
+ const GenerationOptions& generation_options,
+ CommonState& common_state)
+ : file_(file),
+ generation_options_(generation_options),
+ common_state_(&common_state),
+ root_class_name_(FileClassName(file)),
+ file_description_name_(FileClassName(file) + "_FileDescription"),
+ is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_.emplace_back(
+ std::make_unique<EnumGenerator>(file_->enum_type(i)));
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_.push_back(std::make_unique<ExtensionGenerator>(
+ root_class_name_, file_->extension(i)));
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_.emplace_back(std::make_unique<MessageGenerator>(
+ file_description_name_, file_->message_type(i)));
+ message_generators_.back()->AddExtensionGenerators(&extension_generators_);
+ MakeDescriptors(file_->message_type(i), file_description_name_,
+ &enum_generators_, &extension_generators_,
+ &message_generators_);
+ }
+}
+
+void FileGenerator::GenerateHeader(io::Printer* p) const {
+ GenerateFile(p, GeneratedFileType::kHeader, [&] {
+ p->Print("CF_EXTERN_C_BEGIN\n\n");
+
+ y_absl::btree_set<TProtoStringType> fwd_decls;
+ for (const auto& generator : message_generators_) {
+ generator->DetermineForwardDeclarations(&fwd_decls,
+ /* include_external_types = */
+ HeadersUseForwardDeclarations());
+ }
+ if (!fwd_decls.empty()) {
+ p->Print("$fwd_decls$\n\n", "fwd_decls", y_absl::StrJoin(fwd_decls, "\n"));
+ }
+
+ p->Print("NS_ASSUME_NONNULL_BEGIN\n\n");
+
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateHeader(p);
+ }
+
+ // For extensions to chain together, the Root gets created even if there
+ // are no extensions.
+ p->Print(
+ // clang-format off
+ "#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",
+ // clang-format on
+ "root_class_name", root_class_name_);
+
+ // The dynamic methods block is only needed if there are extensions that are
+ // file level scoped (not message scoped). The first
+ // file_->extension_count() of extension_generators_ are the file scoped
+ // ones.
+ if (file_->extension_count()) {
+ p->Print("@interface $root_class_name$ (DynamicMethods)\n",
+ "root_class_name", root_class_name_);
+
+ for (int i = 0; i < file_->extension_count(); i++) {
+ extension_generators_[i]->GenerateMembersHeader(p);
+ }
+
+ p->Print("@end\n\n");
+ } // file_->extension_count()
+
+ for (const auto& generator : message_generators_) {
+ generator->GenerateMessageHeader(p);
+ }
+
+ // clang-format off
+ p->Print(
+ "NS_ASSUME_NONNULL_END\n"
+ "\n"
+ "CF_EXTERN_C_END\n");
+ // clang-format on
+ });
+}
+
+void FileGenerator::GenerateSource(io::Printer* p) const {
+ std::vector<const FileDescriptor*> deps_with_extensions =
+ common_state_->CollectMinimalFileDepsContainingExtensions(file_);
+ GeneratedFileOptions file_options;
+
+ // 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 (auto& dep : deps_with_extensions) {
+ if (!IsDirectDependency(dep, file_)) {
+ file_options.extra_files_to_import.push_back(dep);
+ }
+ }
+
+ y_absl::btree_set<TProtoStringType> fwd_decls;
+ for (const auto& generator : message_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+ }
+ for (const auto& generator : extension_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+ }
+
+ // 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.
+ for (const auto& generator : message_generators_) {
+ if (generator->IncludesOneOfDefinition()) {
+ file_options.ignored_warnings.push_back("direct-ivar-access");
+ break;
+ }
+ }
+ if (!fwd_decls.empty()) {
+ file_options.ignored_warnings.push_back("dollar-in-identifier-extension");
+ }
+
+ // Enum implementation uses atomic in the generated code, so add
+ // the system import as needed.
+ if (!enum_generators_.empty()) {
+ file_options.extra_system_headers.push_back("stdatomic.h");
+ }
+
+ GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
+ if (!fwd_decls.empty()) {
+ p->Print(
+ // clang-format off
+ "#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"
+ "$fwd_decls$\n"
+ "\n",
+ // clang-format on
+ "fwd_decls", y_absl::StrJoin(fwd_decls, "\n"));
+ }
+
+ PrintRootImplementation(p, deps_with_extensions);
+ PrintFileDescription(p);
+
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateSource(p);
+ }
+ for (const auto& generator : message_generators_) {
+ generator->GenerateSource(p);
+ }
+ });
+}
+
+void FileGenerator::GenerateGlobalSource(io::Printer* p) const {
+ std::vector<const FileDescriptor*> deps_with_extensions =
+ common_state_->CollectMinimalFileDepsContainingExtensions(file_);
+ GeneratedFileOptions file_options;
+
+ // 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 (auto& dep : deps_with_extensions) {
+ if (!IsDirectDependency(dep, file_)) {
+ file_options.extra_files_to_import.push_back(dep);
+ }
+ }
+
+ y_absl::btree_set<TProtoStringType> fwd_decls;
+ for (const auto& generator : extension_generators_) {
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+ }
+
+ if (!fwd_decls.empty()) {
+ file_options.ignored_warnings.push_back("dollar-in-identifier-extension");
+ }
+
+ GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
+ if (!fwd_decls.empty()) {
+ p->Print(
+ // clang-format off
+ "#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"
+ "$fwd_decls$\n"
+ "\n",
+ // clang-format on
+ "fwd_decls", y_absl::StrJoin(fwd_decls, "\n"));
+ }
+
+ PrintRootImplementation(p, deps_with_extensions);
+ });
+}
+
+void FileGenerator::GenerateSourceForEnums(io::Printer* p) const {
+ // Enum implementation uses atomic in the generated code.
+ GeneratedFileOptions file_options;
+ file_options.extra_system_headers.push_back("stdatomic.h");
+
+ GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
+ for (const auto& generator : enum_generators_) {
+ generator->GenerateSource(p);
+ }
+ });
+}
+
+void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) const {
+ const auto& generator = message_generators_[idx];
+
+ y_absl::btree_set<TProtoStringType> fwd_decls;
+ generator->DetermineObjectiveCClassDefinitions(&fwd_decls);
+
+ GeneratedFileOptions file_options;
+ // 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.
+ if (generator->IncludesOneOfDefinition()) {
+ file_options.ignored_warnings.push_back("direct-ivar-access");
+ }
+
+ GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
+ if (!fwd_decls.empty()) {
+ p->Print(
+ // clang-format off
+ "#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"
+ "$fwd_decls$\n"
+ "\n",
+ // clang-format on
+ "fwd_decls", y_absl::StrJoin(fwd_decls, "\n"));
+ }
+
+ PrintFileDescription(p);
+ generator->GenerateSource(p);
+ });
+}
+
+void FileGenerator::GenerateFile(io::Printer* p, GeneratedFileType file_type,
+ const GeneratedFileOptions& file_options,
+ std::function<void()> body) const {
+ ImportWriter import_writer(
+ generation_options_.generate_for_named_framework,
+ generation_options_.named_framework_to_proto_path_mappings_path,
+ generation_options_.runtime_import_prefix,
+ /* for_bundled_proto = */ is_bundled_proto_);
+ const TProtoStringType header_extension(kHeaderExtension);
+
+ switch (file_type) {
+ case GeneratedFileType::kHeader:
+ // Generated files bundled with the library get minimal imports,
+ // everything else gets the wrapper so everything is usable.
+ if (is_bundled_proto_) {
+ import_writer.AddRuntimeImport("GPBDescriptor.h");
+ import_writer.AddRuntimeImport("GPBMessage.h");
+ import_writer.AddRuntimeImport("GPBRootObject.h");
+ } else {
+ import_writer.AddRuntimeImport("GPBProtocolBuffers.h");
+ }
+ if (HeadersUseForwardDeclarations()) {
+ // #import any headers for "public imports" in the proto file.
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ import_writer.AddFile(file_->public_dependency(i), header_extension);
+ }
+ } else {
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ import_writer.AddFile(file_->dependency(i), header_extension);
+ }
+ }
+ break;
+ case GeneratedFileType::kSource:
+ import_writer.AddRuntimeImport("GPBProtocolBuffers_RuntimeSupport.h");
+ import_writer.AddFile(file_, header_extension);
+ if (HeadersUseForwardDeclarations()) {
+ // #import the headers for anything that a plain dependency of this
+ // proto file (that means they were just an include, not a "public"
+ // include).
+ y_absl::flat_hash_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);
+ if (!public_import_names.contains(dep->name())) {
+ import_writer.AddFile(dep, header_extension);
+ }
+ }
+ }
+ break;
+ }
+
+ for (const auto& dep : file_options.extra_files_to_import) {
+ import_writer.AddFile(dep, header_extension);
+ }
+
+ p->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// $clangfmt$ off\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name(), "clangfmt", "clang-format");
+
+ import_writer.PrintRuntimeImports(
+ p, /* default_cpp_symbol = */ !is_bundled_proto_);
+
+ p->Print("\n");
+
+ // 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
+ // compile time (so checking against the headers being used to compile).
+ p->Print(
+ // clang-format off
+ "#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",
+ // clang-format on
+ "google_protobuf_objc_version",
+ y_absl::StrCat(GOOGLE_PROTOBUF_OBJC_VERSION));
+
+ if (!file_options.extra_system_headers.empty()) {
+ for (const auto& system_header : file_options.extra_system_headers) {
+ p->Print("#import <$header$>\n", "header", system_header);
+ }
+ p->Print("\n");
+ }
+
+ import_writer.PrintFileImports(p);
+
+ // clang-format off
+ p->Print(
+ "// @@protoc_insertion_point(imports)\n"
+ "\n"
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
+ // clang-format on
+ for (const auto& warning : file_options.ignored_warnings) {
+ p->Print("#pragma clang diagnostic ignored \"-W$warning$\"\n", "warning",
+ warning);
+ }
+ p->Print("\n");
+
+ body();
+
+ p->Print(
+ "\n"
+ "#pragma clang diagnostic pop\n"
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n"
+ "// $clangfmt$ on\n",
+ "clangfmt", "clang-format");
+}
+
+void FileGenerator::PrintRootImplementation(
+ io::Printer* p,
+ const std::vector<const FileDescriptor*>& deps_with_extensions) const {
+ p->Print(
+ // clang-format off
+ "#pragma mark - $root_class_name$\n"
+ "\n"
+ "@implementation $root_class_name$\n"
+ "\n",
+ // clang-format on
+ "root_class_name", root_class_name_);
+
+ // If there were any extensions or this file has any dependencies, output a
+ // registry to override to create the file specific registry.
+ if (extension_generators_.empty() && deps_with_extensions.empty()) {
+ if (file_->dependency_count() == 0) {
+ // clang-format off
+ p->Print(
+ "// No extensions in the file and no imports, so no need to generate\n"
+ "// +extensionRegistry.\n");
+ // clang-format on
+ } else {
+ // clang-format off
+ p->Print(
+ "// No extensions in the file and none of the imports (direct or indirect)\n"
+ "// defined extensions, so no need to generate +extensionRegistry.\n");
+ // clang-format on
+ }
+ } else {
+ PrintRootExtensionRegistryImplementation(p, deps_with_extensions);
+ }
+
+ p->Print("\n@end\n\n");
+}
+
+void FileGenerator::PrintRootExtensionRegistryImplementation(
+ io::Printer* p,
+ const std::vector<const FileDescriptor*>& deps_with_extensions) const {
+ // clang-format off
+ p->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");
+ // clang-format on
+
+ p->Indent();
+ p->Indent();
+
+ if (!extension_generators_.empty()) {
+ p->Print("static GPBExtensionDescription descriptions[] = {\n");
+ p->Indent();
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateStaticVariablesInitialization(p);
+ }
+ p->Outdent();
+ // clang-format off
+ p->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");
+ // clang-format on
+ }
+
+ if (deps_with_extensions.empty()) {
+ // clang-format off
+ p->Print(
+ "// None of the imports (direct or indirect) defined extensions, so no need to add\n"
+ "// them to this registry.\n");
+ // clang-format on
+ } else {
+ // clang-format off
+ p->Print(
+ "// Merge in the imports (direct or indirect) that defined extensions.\n");
+ // clang-format on
+ for (const auto& dep : deps_with_extensions) {
+ const TProtoStringType root_class_name(FileClassName((dep)));
+ p->Print("[registry addExtensions:[$dependency$ extensionRegistry]];\n",
+ "dependency", root_class_name);
+ }
+ }
+
+ p->Outdent();
+ p->Outdent();
+
+ // clang-format off
+ p->Print(
+ " }\n"
+ " return registry;\n"
+ "}\n");
+ // clang-format on
+}
+
+void FileGenerator::PrintFileDescription(io::Printer* p) const {
+ // File descriptor only needed if there are messages to use it.
+ if (message_generators_.empty()) {
+ return;
+ }
+
+ const TProtoStringType objc_prefix(FileClassPrefix(file_));
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> vars;
+ vars["file_description_name"] = file_description_name_;
+ vars["package_value"] = file_->package().empty()
+ ? "NULL"
+ : y_absl::StrCat("\"", file_->package(), "\"");
+ 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;
+ }
+ if (objc_prefix.empty() && !file_->options().has_objc_class_prefix()) {
+ vars["prefix_value"] = "NULL";
+ } else {
+ vars["prefix_value"] = y_absl::StrCat("\"", objc_prefix, "\"");
+ }
+
+ // clang-format off
+ p->Print(
+ vars,
+ "static GPBFileDescription $file_description_name$ = {\n"
+ " .package = $package_value$,\n"
+ " .prefix = $prefix_value$,\n"
+ " .syntax = $syntax$\n"
+ "};\n"
+ "\n");
+ // clang-format on
+}
+
+} // 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/file.h
index de37930eb3..e83c27c2ec 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/file.h
@@ -31,80 +31,108 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
-#include <map>
-#include <set>
+#include <functional>
+#include <memory>
#include <string>
#include <vector>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/container/flat_hash_set.h"
+#include "google/protobuf/compiler/objectivec/enum.h"
+#include "google/protobuf/compiler/objectivec/extension.h"
+#include "google/protobuf/compiler/objectivec/message.h"
+#include "google/protobuf/compiler/objectivec/options.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:
- struct GenerationOptions {
- GenerationOptions()
- // TODO(thomasvl): Eventually flip this default to false for better
- // interop with Swift if proto usages span modules made from ObjC sources.
- : headers_use_forward_declarations(true) {}
- TProtoStringType generate_for_named_framework;
- TProtoStringType named_framework_to_proto_path_mappings_path;
- TProtoStringType runtime_import_prefix;
- bool headers_use_forward_declarations;
- };
-
// Wrapper for some common state that is shared between file generations to
// improve performance when more than one file is generated at a time.
struct CommonState {
- CommonState();
+ CommonState() = default;
- const std::vector<const FileDescriptor*>
+ std::vector<const FileDescriptor*>
CollectMinimalFileDepsContainingExtensions(const FileDescriptor* file);
private:
struct MinDepsEntry {
bool has_extensions;
- std::set<const FileDescriptor*> min_deps;
- // `covered_deps` are the transtive deps of `min_deps_w_exts` that also
- // have extensions.
- std::set<const FileDescriptor*> covered_deps;
+ // The minimal dependencies that cover all the dependencies with
+ // extensions.
+ y_absl::flat_hash_set<const FileDescriptor*> min_deps;
+ y_absl::flat_hash_set<const FileDescriptor*> transitive_deps;
};
- const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(const FileDescriptor* file);
- std::map<const FileDescriptor*, MinDepsEntry> deps_info_cache_;
+ const MinDepsEntry& CollectMinimalFileDepsContainingExtensionsInternal(
+ const FileDescriptor* file);
+ y_absl::flat_hash_map<const FileDescriptor*, MinDepsEntry> deps_info_cache;
};
FileGenerator(const FileDescriptor* file,
const GenerationOptions& generation_options,
CommonState& common_state);
- ~FileGenerator();
+ ~FileGenerator() = default;
FileGenerator(const FileGenerator&) = delete;
FileGenerator& operator=(const FileGenerator&) = delete;
- void GenerateSource(io::Printer* printer);
- void GenerateHeader(io::Printer* printer);
+ void GenerateHeader(io::Printer* p) const;
+ void GenerateSource(io::Printer* p) const;
+
+ int NumEnums() const { return enum_generators_.size(); }
+ int NumMessages() const { return message_generators_.size(); }
+
+ void GenerateGlobalSource(io::Printer* p) const;
+ void GenerateSourceForMessage(int idx, io::Printer* p) const;
+ void GenerateSourceForEnums(io::Printer* p) const;
private:
+ enum class GeneratedFileType : int { kHeader, kSource };
+ struct GeneratedFileOptions {
+ std::vector<TProtoStringType> ignored_warnings;
+ std::vector<const FileDescriptor*> extra_files_to_import;
+ std::vector<TProtoStringType> extra_system_headers;
+ };
+
+ void GenerateFile(io::Printer* p, GeneratedFileType file_type,
+ const GeneratedFileOptions& file_options,
+ std::function<void()> body) const;
+ void GenerateFile(io::Printer* p, GeneratedFileType file_type,
+ std::function<void()> body) const {
+ GeneratedFileOptions file_options;
+ GenerateFile(p, file_type, file_options, body);
+ }
+
+ void PrintRootImplementation(
+ io::Printer* p,
+ const std::vector<const FileDescriptor*>& deps_with_extensions) const;
+ void PrintRootExtensionRegistryImplementation(
+ io::Printer* p,
+ const std::vector<const FileDescriptor*>& deps_with_extensions) const;
+ void PrintFileDescription(io::Printer* p) const;
+
+ bool HeadersUseForwardDeclarations() const {
+ // The bundled protos (WKTs) don't make use of forward declarations.
+ return !is_bundled_proto_ &&
+ generation_options_.headers_use_forward_declarations;
+ }
+
const FileDescriptor* file_;
const GenerationOptions& generation_options_;
- CommonState& common_state_;
- TProtoStringType root_class_name_;
- bool is_bundled_proto_;
+ mutable CommonState* common_state_;
+ const TProtoStringType root_class_name_;
+ const TProtoStringType file_description_name_;
+ const bool is_bundled_proto_;
std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+ // The first file_->extension_count() are the extensions at file level scope.
std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
-
- void PrintFileRuntimePreamble(
- io::Printer* printer,
- const std::vector<TProtoStringType>& headers_to_import) const;
};
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.cc
index 586cdb025b..31c99dba67 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.cc
@@ -28,16 +28,24 @@
// (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/generator.h"
+
#include <fstream>
#include <iostream>
+#include <memory>
#include <string>
-#include <unordered_set>
-#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>
+#include <utility>
+#include <vector>
+
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/str_cat.h"
+#include "y_absl/strings/str_split.h"
+#include "y_absl/strings/strip.h"
+#include "google/protobuf/compiler/objectivec/file.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/io/printer.h"
+#include "google/protobuf/io/zero_copy_stream.h"
namespace google {
namespace protobuf {
@@ -47,16 +55,17 @@ namespace objectivec {
namespace {
// Convert a string with "yes"/"no" (case insensitive) to a boolean, returning
-// true/false for if the input string was a valid value. If the input string is
-// invalid, `result` is unchanged.
+// true/false for if the input string was a valid value. The empty string is
+// also treated as a true value. If the input string is invalid, `result` is
+// unchanged.
bool StringToBool(const TProtoStringType& value, bool* result) {
TProtoStringType upper_value(value);
- UpperString(&upper_value);
+ y_absl::AsciiStrToUpper(&upper_value);
if (upper_value == "NO") {
*result = false;
return true;
}
- if (upper_value == "YES") {
+ if (upper_value == "YES" || upper_value.empty()) {
*result = true;
return true;
}
@@ -64,15 +73,13 @@ bool StringToBool(const TProtoStringType& value, bool* result) {
return false;
}
-} // namespace
+TProtoStringType NumberedObjCMFileName(y_absl::string_view basename, int number) {
+ return y_absl::StrCat(basename, ".out/", number, ".pbobjc.m");
+}
-ObjectiveCGenerator::ObjectiveCGenerator() {}
+} // namespace
-ObjectiveCGenerator::~ObjectiveCGenerator() {}
-
-bool ObjectiveCGenerator::HasGenerateAll() const {
- return true;
-}
+bool ObjectiveCGenerator::HasGenerateAll() const { return true; }
bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
const TProtoStringType& parameter,
@@ -92,14 +99,15 @@ bool ObjectiveCGenerator::GenerateAll(
// 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
+ // e.g. protoc ...
+ // --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
Options validation_options;
- FileGenerator::GenerationOptions generation_options;
+ GenerationOptions generation_options;
std::vector<std::pair<TProtoStringType, TProtoStringType> > options;
ParseGeneratorParameter(parameter, &options);
- for (int i = 0; i < options.size(); i++) {
+ for (size_t 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
@@ -122,8 +130,8 @@ bool ObjectiveCGenerator::GenerateAll(
// 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)) {
+ for (y_absl::string_view split_piece :
+ y_absl::StrSplit(options[i].second, ';', y_absl::SkipEmpty())) {
validation_options.expected_prefixes_suppressions.push_back(
TProtoStringType(split_piece));
}
@@ -137,7 +145,9 @@ bool ObjectiveCGenerator::GenerateAll(
// Default is "no".
if (!StringToBool(options[i].second,
&validation_options.prefixes_must_be_registered)) {
- *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second;
+ *error = y_absl::StrCat(
+ "error: Unknown value for prefixes_must_be_registered: ",
+ options[i].second);
return false;
}
} else if (options[i].first == "require_prefixes") {
@@ -149,7 +159,8 @@ bool ObjectiveCGenerator::GenerateAll(
// Default is "no".
if (!StringToBool(options[i].second,
&validation_options.require_prefixes)) {
- *error = "error: Unknown value for require_prefixes: " + options[i].second;
+ *error = y_absl::StrCat("error: Unknown value for require_prefixes: ",
+ options[i].second);
return false;
}
} else if (options[i].first == "generate_for_named_framework") {
@@ -162,7 +173,8 @@ bool ObjectiveCGenerator::GenerateAll(
// 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") {
+ } 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
@@ -183,17 +195,20 @@ bool ObjectiveCGenerator::GenerateAll(
// 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;
+ 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, "/");
+ generation_options.runtime_import_prefix =
+ TProtoStringType(y_absl::StripSuffix(options[i].second, "/"));
} else if (options[i].first == "package_to_prefix_mappings_path") {
// Path to use for when loading the objc class prefix mappings to use.
- // The `objc_class_prefix` file option is always honored first if one is present.
- // This option also has precedent over the use_package_as_prefix option.
+ // The `objc_class_prefix` file option is always honored first if one is
+ // present. This option also has precedent over the use_package_as_prefix
+ // option.
//
// The format of the file is:
// - An entry is a line of "package=prefix".
@@ -215,7 +230,8 @@ bool ObjectiveCGenerator::GenerateAll(
if (StringToBool(options[i].second, &value)) {
SetUseProtoPackageAsDefaultPrefix(value);
} else {
- *error = "error: Unknown use_package_as_prefix: " + options[i].second;
+ *error = y_absl::StrCat("error: Unknown use_package_as_prefix: ",
+ options[i].second);
return false;
}
} else if (options[i].first == "proto_package_prefix_exceptions_path") {
@@ -230,25 +246,54 @@ bool ObjectiveCGenerator::GenerateAll(
// - A comment can go on a line after a expected package/prefix pair.
// (i.e. - "some.proto.package # comment")
SetProtoPackagePrefixExceptionList(options[i].second);
+ } else if (options[i].first == "package_as_prefix_forced_prefix") {
+ // String to use as the prefix when deriving a prefix from the package
+ // name. So this only applies when use_package_as_prefix is also used.
+ SetForcedPackagePrefix(options[i].second);
} else if (options[i].first == "headers_use_forward_declarations") {
if (!StringToBool(options[i].second,
&generation_options.headers_use_forward_declarations)) {
- *error = "error: Unknown value for headers_use_forward_declarations: " + options[i].second;
+ *error = y_absl::StrCat(
+ "error: Unknown value for headers_use_forward_declarations: ",
+ options[i].second);
+ return false;
+ }
+ } else if (options[i].first == "experimental_multi_source_generation") {
+ // This is an experimental option, and could be removed or change at any
+ // time; it is not documented in the README.md for that reason.
+ //
+ // Enables a mode where each ObjC class (messages and roots) generates to
+ // a unique .m file; this is to explore impacts on code size when not
+ // compiling/linking with `-ObjC` as then only linker visible needs should
+ // be pulled into the builds.
+ if (!StringToBool(
+ options[i].second,
+ &generation_options.experimental_multi_source_generation)) {
+ *error = y_absl::StrCat(
+ "error: Unknown value for experimental_multi_source_generation: ",
+ options[i].second);
return false;
}
} else {
- *error = "error: Unknown generator option: " + options[i].first;
+ *error =
+ y_absl::StrCat("error: Unknown generator option: ", options[i].first);
return false;
}
}
+ // Multi source generation forces off the use of fwd decls in favor of
+ // imports.
+ if (generation_options.experimental_multi_source_generation) {
+ generation_options.headers_use_forward_declarations = false;
+ }
+
// -----------------------------------------------------------------
// These are not official generation options and could be removed/changed in
// the future and doing that won't count as a breaking change.
- bool headers_only = getenv("GPB_OBJC_HEADERS_ONLY") != NULL;
- std::unordered_set<TProtoStringType> skip_impls;
- if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != NULL) {
+ bool headers_only = getenv("GPB_OBJC_HEADERS_ONLY") != nullptr;
+ y_absl::flat_hash_set<TProtoStringType> skip_impls;
+ if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != nullptr) {
std::ifstream skip_file(getenv("GPB_OBJC_SKIP_IMPLS_FILE"));
if (skip_file.is_open()) {
std::string line;
@@ -270,27 +315,83 @@ bool ObjectiveCGenerator::GenerateAll(
}
FileGenerator::CommonState state;
- for (int i = 0; i < files.size(); i++) {
- const FileDescriptor* file = files[i];
- FileGenerator file_generator(file, generation_options, state);
+ for (const auto& file : files) {
+ const FileGenerator file_generator(file, generation_options, state);
TProtoStringType filepath = FilePath(file);
// Generate header.
{
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- context->Open(filepath + ".pbobjc.h"));
- io::Printer printer(output.get(), '$');
+ auto output =
+ y_absl::WrapUnique(context->Open(y_absl::StrCat(filepath, ".pbobjc.h")));
+ io::Printer printer(output.get());
file_generator.GenerateHeader(&printer);
+ if (printer.failed()) {
+ *error = y_absl::StrCat("error: internal error generating a header: ",
+ file->name());
+ return false;
+ }
}
- // Generate m file.
+ // Generate m file(s).
if (!headers_only && skip_impls.count(file->name()) == 0) {
- std::unique_ptr<io::ZeroCopyOutputStream> output(
- context->Open(filepath + ".pbobjc.m"));
- io::Printer printer(output.get(), '$');
- file_generator.GenerateSource(&printer);
- }
- }
+ if (generation_options.experimental_multi_source_generation) {
+ int file_number = 0;
+
+ // Generate the Root and FileDescriptor (if needed).
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(NumberedObjCMFileName(filepath, file_number++)));
+ io::Printer printer(output.get());
+ file_generator.GenerateGlobalSource(&printer);
+ if (printer.failed()) {
+ *error = y_absl::StrCat(
+ "error: internal error generating an implementation:",
+ file->name());
+ return false;
+ }
+ }
+
+ // Enums only generate C functions, so they can all go in one file as
+ // dead stripping anything not used.
+ if (file_generator.NumEnums() > 0) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(NumberedObjCMFileName(filepath, file_number++)));
+ io::Printer printer(output.get());
+ file_generator.GenerateSourceForEnums(&printer);
+ if (printer.failed()) {
+ *error = y_absl::StrCat(
+ "error: internal error generating an enum implementation(s):",
+ file->name());
+ return false;
+ }
+ }
+
+ for (int i = 0; i < file_generator.NumMessages(); ++i) {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(NumberedObjCMFileName(filepath, file_number++)));
+ io::Printer printer(output.get());
+ file_generator.GenerateSourceForMessage(i, &printer);
+ if (printer.failed()) {
+ *error = y_absl::StrCat(
+ "error: internal error generating an message implementation:",
+ file->name(), "::", i);
+ return false;
+ }
+ }
+ } else {
+ auto output = y_absl::WrapUnique(
+ context->Open(y_absl::StrCat(filepath, ".pbobjc.m")));
+ io::Printer printer(output.get());
+ file_generator.GenerateSource(&printer);
+ if (printer.failed()) {
+ *error = y_absl::StrCat(
+ "error: internal error generating an implementation:",
+ file->name());
+ return false;
+ }
+ }
+ } // if (!headers_only && skip_impls.count(file->name()) == 0)
+ } // for(file : files)
return true;
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.h
index cdaac67c3b..34767e45a6 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_generator.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/generator.h
@@ -34,10 +34,13 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
#include <string>
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/descriptor.h>
+#include <vector>
-#include <google/protobuf/port_def.inc>
+#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/descriptor.h"
+
+// Must be included last
+#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
@@ -50,8 +53,8 @@ namespace objectivec {
// CodeGenerator with the CommandLineInterface in your main() function.
class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
public:
- ObjectiveCGenerator();
- ~ObjectiveCGenerator();
+ ObjectiveCGenerator() = default;
+ ~ObjectiveCGenerator() override = default;
ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;
@@ -74,6 +77,6 @@ class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
} // namespace protobuf
} // namespace google
-#include <google/protobuf/port_undef.inc>
+#include "google/protobuf/port_undef.inc"
#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.cc
new file mode 100644
index 0000000000..4d90adeb7d
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.cc
@@ -0,0 +1,399 @@
+// 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/helpers.h"
+
+#include <string>
+#include <vector>
+
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/match.h"
+#include "y_absl/strings/str_replace.h"
+#include "y_absl/strings/str_split.h"
+#include "y_absl/strings/string_view.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/io/strtod.h"
+#include "google/protobuf/stubs/common.h"
+#include <google/protobuf/stubs/port.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 {
+
+TProtoStringType EscapeTrigraphs(y_absl::string_view to_escape) {
+ return y_absl::StrReplaceAll(to_escape, {{"?", "\\?"}});
+}
+
+namespace {
+
+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:
+ Y_ABSL_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:
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return TProtoStringType();
+ }
+}
+
+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 &&
+ (y_absl::StrContains(val, '.') || y_absl::StrContains(val, 'e') ||
+ y_absl::StrContains(val, 'E'))) {
+ return y_absl::StrCat(val, "f");
+ }
+ return val;
+ }
+}
+
+} // namespace
+
+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.
+ Y_ABSL_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.
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return OBJECTIVECTYPE_INT32;
+}
+
+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.
+ Y_ABSL_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 y_absl::StrCat(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return y_absl::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 y_absl::StrCat(field->default_value_int64(), "LL");
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return y_absl::StrCat(field->default_value_uint64(), "ULL");
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return HandleExtremeFloatingPoint(
+ io::SimpleDtoa(field->default_value_double()), false);
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return HandleExtremeFloatingPoint(
+ io::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();
+ y_absl::string_view 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.
+ arc_ui32 length = ghtonl(default_string.length());
+ TProtoStringType bytes((const char*)&length, sizeof(length));
+ y_absl::StrAppend(&bytes, default_string);
+ return y_absl::StrCat("(NSData*)\"",
+ EscapeTrigraphs(y_absl::CEscape(bytes)), "\"");
+ } else {
+ return y_absl::StrCat(
+ "@\"", EscapeTrigraphs(y_absl::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.
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return TProtoStringType();
+}
+
+TProtoStringType BuildFlagsString(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 =
+ y_absl::StrCat("(", 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 ObjCClass(y_absl::string_view class_name) {
+ return y_absl::StrCat("GPBObjCClass(", class_name, ")");
+}
+
+TProtoStringType ObjCClassDeclaration(y_absl::string_view class_name) {
+ return y_absl::StrCat("GPBObjCClassDeclaration(", class_name, ");");
+}
+
+TProtoStringType BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line) {
+ y_absl::string_view comments = location.leading_comments.empty()
+ ? location.trailing_comments
+ : location.leading_comments;
+ std::vector<y_absl::string_view> lines;
+ lines = y_absl::StrSplit(comments, '\n', y_absl::AllowEmpty());
+ 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";
+ y_absl::StrAppend(&final_comments, "/**\n");
+ epilogue = " **/\n";
+ add_leading_space = true;
+ }
+
+ for (size_t i = 0; i < lines.size(); i++) {
+ TProtoStringType line = y_absl::StrReplaceAll(
+ y_absl::StripPrefix(lines[i], " "),
+ {// HeaderDoc and appledoc use '\' and '@' for markers; escape them.
+ {"\\", "\\\\"},
+ {"@", "\\@"},
+ // Decouple / from * to not have inline comments inside comments.
+ {"/*", "/\\*"},
+ {"*/", "*\\/"}});
+ line = prefix + line;
+ y_absl::StripAsciiWhitespace(&line);
+ // If not a one line, need to add the first space before *, as
+ // y_absl::StripAsciiWhitespace would have removed it.
+ line = y_absl::StrCat(add_leading_space ? " " : "", line);
+ y_absl::StrAppend(&final_comments, line, suffix);
+ }
+ return y_absl::StrCat(final_comments, epilogue);
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.h
new file mode 100644
index 0000000000..73f67e13d7
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/helpers.h
@@ -0,0 +1,155 @@
+// 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"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// Escape C++ trigraphs by escaping question marks to "\?".
+TProtoStringType EscapeTrigraphs(y_absl::string_view to_escape);
+
+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
+};
+
+TProtoStringType GetCapitalizedType(const FieldDescriptor* field);
+
+ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type);
+
+inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
+ return GetObjectiveCType(field->type());
+}
+
+inline 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;
+ }
+}
+
+inline bool IsReferenceType(const FieldDescriptor* field) {
+ return !IsPrimitiveType(field);
+}
+
+TProtoStringType GPBGenericValueFieldName(const FieldDescriptor* field);
+TProtoStringType DefaultValue(const FieldDescriptor* field);
+
+TProtoStringType BuildFlagsString(FlagType type,
+ const std::vector<TProtoStringType>& strings);
+
+// Returns a symbol that can be used in C code to refer to an Objective-C
+// class without initializing the class.
+TProtoStringType ObjCClass(y_absl::string_view class_name);
+
+// Declares an Objective-C class without initializing the class so that it can
+// be refrerred to by ObjCClass.
+TProtoStringType ObjCClassDeclaration(y_absl::string_view class_name);
+
+// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
+// file.
+TProtoStringType BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line);
+
+template <class TDescriptor>
+TProtoStringType GetOptionalDeprecatedAttribute(const TDescriptor* descriptor,
+ const FileDescriptor* file = nullptr,
+ 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 = y_absl::StrCat(sourceFile->name(), " is deprecated.");
+ } else {
+ message = y_absl::StrCat(descriptor->full_name(), " is deprecated (see ",
+ sourceFile->name(), ").");
+ }
+
+ return y_absl::StrCat(preSpace ? " " : "", "GPB_DEPRECATED_MSG(\"", message,
+ "\")", postNewline ? "\n" : "");
+ } else {
+ return "";
+ }
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.cc
new file mode 100644
index 0000000000..de6f6ab66c
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.cc
@@ -0,0 +1,255 @@
+// 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/import_writer.h"
+
+#include <iostream>
+#include <ostream>
+#include <string>
+#include <vector>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/log/absl_check.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/match.h"
+#include "google/protobuf/compiler/objectivec/line_consumer.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/io/printer.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 {
+
+namespace {
+
+class ProtoFrameworkCollector : public LineConsumer {
+ public:
+ explicit ProtoFrameworkCollector(
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType>*
+ inout_proto_file_to_framework_name)
+ : map_(inout_proto_file_to_framework_name) {}
+
+ bool ConsumeLine(y_absl::string_view line, TProtoStringType* out_error) override;
+
+ private:
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType>* map_;
+};
+
+bool ProtoFrameworkCollector::ConsumeLine(y_absl::string_view line,
+ TProtoStringType* out_error) {
+ int offset = line.find(':');
+ if (offset == y_absl::string_view::npos) {
+ *out_error = y_absl::StrCat(
+ "Framework/proto file mapping line without colon sign: '", line, "'.");
+ return false;
+ }
+ y_absl::string_view framework_name =
+ y_absl::StripAsciiWhitespace(line.substr(0, offset));
+ y_absl::string_view proto_file_list =
+ y_absl::StripAsciiWhitespace(line.substr(offset + 1));
+
+ int start = 0;
+ while (start < proto_file_list.length()) {
+ offset = proto_file_list.find(',', start);
+ if (offset == y_absl::string_view::npos) {
+ offset = proto_file_list.length();
+ }
+
+ y_absl::string_view proto_file = y_absl::StripAsciiWhitespace(
+ proto_file_list.substr(start, offset - start));
+ if (!proto_file.empty()) {
+ auto existing_entry = map_->find(proto_file);
+ if (existing_entry != map_->end()) {
+ std::cerr << "warning: duplicate proto file reference, replacing "
+ "framework entry for '"
+ << proto_file << "' with '" << framework_name << "' (was '"
+ << existing_entry->second << "')." << std::endl;
+ std::cerr.flush();
+ }
+
+ if (y_absl::StrContains(proto_file, ' ')) {
+ std::cerr << "note: framework mapping file had a proto file with a "
+ "space in, hopefully that isn't a missing comma: '"
+ << proto_file << "'" << std::endl;
+ std::cerr.flush();
+ }
+
+ (*map_)[proto_file] = TProtoStringType(framework_name);
+ }
+
+ start = offset + 1;
+ }
+
+ return true;
+}
+
+} // namespace
+
+ImportWriter::ImportWriter(
+ const TProtoStringType& generate_for_named_framework,
+ const TProtoStringType& named_framework_to_proto_path_mappings_path,
+ const TProtoStringType& runtime_import_prefix, bool for_bundled_proto)
+ : 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),
+ for_bundled_proto_(for_bundled_proto),
+ need_to_parse_mapping_file_(true) {}
+
+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 (for_bundled_proto_) {
+ protobuf_imports_.emplace_back(
+ y_absl::StrCat("GPB", FilePathBasename(file), header_extension));
+ }
+ return;
+ }
+
+ // Lazy parse any mappings.
+ if (need_to_parse_mapping_file_) {
+ ParseFrameworkMappings();
+ }
+
+ auto proto_lookup = proto_file_to_framework_name_.find(file->name());
+ if (proto_lookup != proto_file_to_framework_name_.end()) {
+ other_framework_imports_.emplace_back(y_absl::StrCat(
+ proto_lookup->second, "/", FilePathBasename(file), header_extension));
+ return;
+ }
+
+ if (!generate_for_named_framework_.empty()) {
+ other_framework_imports_.push_back(
+ y_absl::StrCat(generate_for_named_framework_, "/", FilePathBasename(file),
+ header_extension));
+ return;
+ }
+
+ other_imports_.push_back(FilePath(file) + header_extension);
+}
+
+void ImportWriter::AddRuntimeImport(const TProtoStringType& header_name) {
+ protobuf_imports_.push_back(header_name);
+}
+
+void ImportWriter::PrintFileImports(io::Printer* p) const {
+ if (!other_framework_imports_.empty()) {
+ for (const auto& header : other_framework_imports_) {
+ p->Print("#import <$header$>\n", "header", header);
+ }
+ }
+
+ if (!other_imports_.empty()) {
+ if (!other_framework_imports_.empty()) {
+ p->Print("\n");
+ }
+
+ for (const auto& header : other_imports_) {
+ p->Print("#import \"$header$\"\n", "header", header);
+ }
+ }
+}
+
+void ImportWriter::PrintRuntimeImports(io::Printer* p,
+ bool default_cpp_symbol) const {
+ // Given an override, use that.
+ if (!runtime_import_prefix_.empty()) {
+ for (const auto& header : protobuf_imports_) {
+ p->Print("#import \"$import_prefix$/$header$\"\n", "header", header,
+ "import_prefix", runtime_import_prefix_);
+ }
+ return;
+ }
+
+ // If bundled, no need to do the framework support below.
+ if (for_bundled_proto_) {
+ Y_ABSL_DCHECK(!default_cpp_symbol);
+ for (const auto& header : protobuf_imports_) {
+ p->Print("#import \"$header$\"\n", "header", header);
+ }
+ return;
+ }
+
+ const TProtoStringType cpp_symbol(
+ ProtobufFrameworkImportSymbol(ProtobufLibraryFrameworkName));
+
+ if (default_cpp_symbol) {
+ p->Print(
+ // clang-format off
+ "// 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",
+ // clang-format on
+ "cpp_symbol", cpp_symbol);
+ }
+
+ p->Print("#if $cpp_symbol$\n", "cpp_symbol", cpp_symbol);
+ for (const auto& header : protobuf_imports_) {
+ p->Print(" #import <$framework_name$/$header$>\n", "framework_name",
+ ProtobufLibraryFrameworkName, "header", header);
+ }
+ p->Print("#else\n");
+ for (const auto& header : protobuf_imports_) {
+ p->Print(" #import \"$header$\"\n", "header", header);
+ }
+ p->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();
+ }
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.h
new file mode 100644
index 0000000000..d4ed37d3a8
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/import_writer.h
@@ -0,0 +1,82 @@
+// 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_IMPORT_WRITER_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__
+
+#include <string>
+#include <vector>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// Helper class for parsing framework import mappings and generating
+// import statements.
+class ImportWriter {
+ public:
+ ImportWriter(const TProtoStringType& generate_for_named_framework,
+ const TProtoStringType& named_framework_to_proto_path_mappings_path,
+ const TProtoStringType& runtime_import_prefix,
+ bool for_bundled_proto);
+ ~ImportWriter() = default;
+
+ void AddFile(const FileDescriptor* file, const TProtoStringType& header_extension);
+ void AddRuntimeImport(const TProtoStringType& header_name);
+
+ void PrintFileImports(io::Printer* p) const;
+ void PrintRuntimeImports(io::Printer* p, bool default_cpp_symbol) const;
+
+ private:
+ void ParseFrameworkMappings();
+
+ const TProtoStringType generate_for_named_framework_;
+ const TProtoStringType named_framework_to_proto_path_mappings_path_;
+ const TProtoStringType runtime_import_prefix_;
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType> proto_file_to_framework_name_;
+ bool for_bundled_proto_;
+ 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
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_IMPORT_WRITER_H__
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.cc
new file mode 100644
index 0000000000..f47be8186e
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.cc
@@ -0,0 +1,212 @@
+// 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 <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#include <climits>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/line_consumer.h"
+#include "google/protobuf/io/zero_copy_stream_impl.h"
+
+#ifdef _WIN32
+#include "google/protobuf/io/io_win32.h"
+#endif
+
+// 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 // !_WIN32
+using ::open;
+#endif // _WIN32
+} // namespace posix
+
+namespace {
+
+bool ascii_isnewline(char c) { return c == '\n' || c == '\r'; }
+
+bool ReadLine(y_absl::string_view* input, y_absl::string_view* line) {
+ for (int len = 0; len < input->size(); ++len) {
+ if (ascii_isnewline((*input)[len])) {
+ *line = y_absl::string_view(input->data(), len);
+ ++len; // advance over the newline
+ *input = y_absl::string_view(input->data() + len, input->size() - len);
+ return true;
+ }
+ }
+ return false; // Ran out of input with no newline.
+}
+
+void RemoveComment(y_absl::string_view* input) {
+ int offset = input->find('#');
+ if (offset != y_absl::string_view::npos) {
+ input->remove_suffix(input->length() - offset);
+ }
+}
+
+class Parser {
+ public:
+ explicit Parser(LineConsumer* line_consumer)
+ : line_consumer_(line_consumer), line_(0) {}
+
+ // Feeds in some input, parse what it can, returning success/failure. Calling
+ // again after an error is undefined.
+ bool ParseChunk(y_absl::string_view chunk, TProtoStringType* out_error);
+
+ // Should be called to finish parsing (after all input has been provided via
+ // successful calls to ParseChunk(), calling after a ParseChunk() failure is
+ // undefined). Returns success/failure.
+ bool Finish(TProtoStringType* out_error);
+
+ int last_line() const { return line_; }
+
+ private:
+ LineConsumer* line_consumer_;
+ int line_;
+ TProtoStringType leftover_;
+};
+
+bool Parser::ParseChunk(y_absl::string_view chunk, TProtoStringType* out_error) {
+ y_absl::string_view full_chunk;
+ if (!leftover_.empty()) {
+ leftover_ += TProtoStringType(chunk);
+ full_chunk = y_absl::string_view(leftover_);
+ } else {
+ full_chunk = chunk;
+ }
+
+ y_absl::string_view line;
+ while (ReadLine(&full_chunk, &line)) {
+ ++line_;
+ RemoveComment(&line);
+ line = y_absl::StripAsciiWhitespace(line);
+ if (!line.empty() && !line_consumer_->ConsumeLine(line, out_error)) {
+ if (out_error->empty()) {
+ *out_error = "ConsumeLine failed without setting an error.";
+ }
+ leftover_.clear();
+ return false;
+ }
+ }
+
+ if (full_chunk.empty()) {
+ leftover_.clear();
+ } else {
+ leftover_ = TProtoStringType(full_chunk);
+ }
+ return true;
+}
+
+bool Parser::Finish(TProtoStringType* out_error) {
+ // If there is still something to go, flush it with a newline.
+ if (!leftover_.empty() && !ParseChunk("\n", out_error)) {
+ return false;
+ }
+ // This really should never fail if ParseChunk succeeded, but check to be
+ // sure.
+ if (!leftover_.empty()) {
+ *out_error = "ParseSimple Internal error: finished with pending data.";
+ return false;
+ }
+ return true;
+}
+
+} // namespace
+
+bool ParseSimpleFile(y_absl::string_view path, LineConsumer* line_consumer,
+ TProtoStringType* out_error) {
+ int fd;
+ do {
+ fd = posix::open(TProtoStringType(path).c_str(), O_RDONLY);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ *out_error =
+ y_absl::StrCat("error: Unable to open \"", path, "\", ", strerror(errno));
+ return false;
+ }
+ io::FileInputStream file_stream(fd);
+ file_stream.SetCloseOnDelete(true);
+
+ return ParseSimpleStream(file_stream, path, line_consumer, out_error);
+}
+
+bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+ y_absl::string_view stream_name,
+ LineConsumer* line_consumer, TProtoStringType* out_error) {
+ TProtoStringType local_error;
+ Parser parser(line_consumer);
+ const void* buf;
+ int buf_len;
+ while (input_stream.Next(&buf, &buf_len)) {
+ if (buf_len == 0) {
+ continue;
+ }
+
+ if (!parser.ParseChunk(
+ y_absl::string_view(static_cast<const char*>(buf), buf_len),
+ &local_error)) {
+ *out_error = y_absl::StrCat("error: ", stream_name, " Line ",
+ parser.last_line(), ", ", local_error);
+ return false;
+ }
+ }
+ if (!parser.Finish(&local_error)) {
+ *out_error = y_absl::StrCat("error: ", stream_name, " Line ",
+ parser.last_line(), ", ", local_error);
+ return false;
+ }
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.h
new file mode 100644
index 0000000000..668fdb1d12
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/line_consumer.h
@@ -0,0 +1,74 @@
+// 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_LINE_CONSUMER_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_LINE_CONSUMER_H__
+
+#include <string>
+#include <vector>
+
+#include "google/protobuf/io/zero_copy_stream.h"
+
+// Must be included last
+#include "google/protobuf/port_def.inc"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// TODO(b/250947994): PROTOC_EXPORT is only used to allow the CMake build to
+// find/link these in the unittest, this is not public api.
+
+// Helper for parsing simple files.
+class PROTOC_EXPORT LineConsumer {
+ public:
+ LineConsumer() = default;
+ virtual ~LineConsumer() = default;
+ virtual bool ConsumeLine(y_absl::string_view line, TProtoStringType* out_error) = 0;
+};
+
+bool PROTOC_EXPORT ParseSimpleFile(y_absl::string_view path,
+ LineConsumer* line_consumer,
+ TProtoStringType* out_error);
+
+bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+ y_absl::string_view stream_name,
+ LineConsumer* line_consumer,
+ TProtoStringType* out_error);
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include "google/protobuf/port_undef.inc"
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_LINE_CONSUMER_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/map_field.cc
index 933f0ce73d..96b777027c 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/map_field.cc
@@ -28,12 +28,16 @@
// (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 "google/protobuf/compiler/objectivec/map_field.h"
+
#include <string>
+#include <vector>
-#include <google/protobuf/compiler/objectivec/objectivec_map_field.h>
-#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
-#include <google/protobuf/io/printer.h>
+#include "y_absl/container/btree_set.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/match.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
namespace google {
namespace protobuf {
@@ -75,16 +79,15 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
// 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;
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return nullptr;
}
} // namespace
MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
: RepeatedFieldGenerator(descriptor) {
- const FieldDescriptor* key_descriptor =
- descriptor->message_type()->map_key();
+ 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));
@@ -96,21 +99,24 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
// Build custom field flags.
std::vector<TProtoStringType> field_flags;
- field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
+ field_flags.push_back(
+ y_absl::StrCat("GPBFieldMapKey", GetCapitalizedType(key_descriptor)));
// Pull over the current text format custom name values that was calculated.
- if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") !=
- TProtoStringType::npos) {
+ if (y_absl::StrContains(variables_["fieldflags"],
+ "GPBFieldTextFormatNameCustom")) {
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) {
+ if (y_absl::StrContains(value_field_flags, "GPBFieldHasDefaultValue")) {
field_flags.push_back("GPBFieldHasDefaultValue");
}
- if (value_field_flags.find("GPBFieldHasEnumDescriptor") !=
- TProtoStringType::npos) {
+ if (y_absl::StrContains(value_field_flags, "GPBFieldHasEnumDescriptor")) {
field_flags.push_back("GPBFieldHasEnumDescriptor");
+ if (y_absl::StrContains(value_field_flags, "GPBFieldClosedEnum")) {
+ field_flags.push_back("GPBFieldClosedEnum");
+ }
}
variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
@@ -124,18 +130,17 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
value_is_object_type) {
variables_["array_storage_type"] = "NSMutableDictionary";
variables_["array_property_type"] =
- "NSMutableDictionary<NSString*, " +
- value_field_generator_->variable("storage_type") + "*>";
+ y_absl::StrCat("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";
+ TProtoStringType class_name =
+ y_absl::StrCat("GPB", MapEntryTypeName(key_descriptor, true),
+ MapEntryTypeName(value_descriptor, false), "Dictionary");
variables_["array_storage_type"] = class_name;
if (value_is_object_type) {
variables_["array_property_type"] =
- class_name + "<" +
- value_field_generator_->variable("storage_type") + "*>";
+ y_absl::StrCat(class_name, "<",
+ value_field_generator_->variable("storage_type"), "*>");
}
}
@@ -145,48 +150,57 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor)
value_field_generator_->variable("dataTypeSpecific_value");
}
-MapFieldGenerator::~MapFieldGenerator() {}
-
-void MapFieldGenerator::FinishInitialization(void) {
+void MapFieldGenerator::FinishInitialization() {
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()->map_value();
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) {
+ TProtoStringType name = variables_["name"];
variables_["array_comment"] =
- "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n";
+ y_absl::StrCat("// |", name, "| values are |",
+ value_field_generator_->variable("storage_type"), "|\n");
}
}
void MapFieldGenerator::DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const {
- RepeatedFieldGenerator::DetermineForwardDeclarations(
- fwd_decls, include_external_types);
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,
+ include_external_types);
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->map_value();
+ // NOTE: Maps with values of enums don't have to worry about adding the
+ // forward declaration because `GPB*EnumDictionary` isn't generic to the
+ // specific enum (like say `NSDictionary<String, MyMessage>`) and thus doesn't
+ // reference the type in the header.
+ if (GetObjectiveCType(value_descriptor) != OBJECTIVECTYPE_MESSAGE) {
+ return;
+ }
+
+ const Descriptor* value_msg_descriptor = value_descriptor->message_type();
+
// Within a file there is no requirement on the order of the messages, so
// local references need a forward declaration. External files (not WKTs),
// need one when requested.
- if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE &&
- ((include_external_types &&
- !IsProtobufLibraryBundledProtoFile(value_descriptor->file())) ||
- descriptor_->file() == value_descriptor->file())) {
+ if ((include_external_types &&
+ !IsProtobufLibraryBundledProtoFile(value_msg_descriptor->file())) ||
+ descriptor_->file() == value_msg_descriptor->file()) {
const TProtoStringType& value_storage_type =
value_field_generator_->variable("storage_type");
- fwd_decls->insert("@class " + value_storage_type);
+ fwd_decls->insert(y_absl::StrCat("@class ", value_storage_type, ";"));
}
}
void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const {
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
// Class name is already in "storage_type".
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->map_value();
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
- fwd_decls->insert(ObjCClassDeclaration(
- value_field_generator_->variable("storage_type")));
+ fwd_decls->insert(
+ ObjCClassDeclaration(value_field_generator_->variable("storage_type")));
}
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/map_field.h
index a75aa961d8..d3ceb070d3 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_map_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/map_field.h
@@ -31,9 +31,11 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
-#include <map>
+#include <memory>
#include <string>
-#include <google/protobuf/compiler/objectivec/objectivec_field.h>
+
+#include "y_absl/container/btree_set.h"
+#include "google/protobuf/compiler/objectivec/field.h"
namespace google {
namespace protobuf {
@@ -44,20 +46,19 @@ class MapFieldGenerator : public RepeatedFieldGenerator {
friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field);
public:
- virtual void FinishInitialization(void) override;
+ void FinishInitialization() override;
MapFieldGenerator(const MapFieldGenerator&) = delete;
MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
protected:
explicit MapFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~MapFieldGenerator();
+ ~MapFieldGenerator() override = default;
- virtual void DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const override;
- virtual void DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
- bool include_external_types) const override;
+ void DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const override;
+ void DetermineForwardDeclarations(y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const override;
private:
std::unique_ptr<FieldGenerator> value_field_generator_;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.cc
new file mode 100644
index 0000000000..089314d361
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.cc
@@ -0,0 +1,631 @@
+// 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/message.h"
+
+#include <algorithm>
+#include <iostream>
+#include <memory>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/extension.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/compiler/objectivec/oneof.h"
+#include "google/protobuf/compiler/objectivec/text_format_decode_data.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/descriptor.pb.h"
+#include "google/protobuf/io/printer.h"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+bool IsMapEntryMessage(const Descriptor* descriptor) {
+ return descriptor->options().map_entry();
+}
+
+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.
+ Y_ABSL_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;
+ }
+};
+
+// This is a reduced case of Descriptor::ExtensionRange with just start and end.
+struct SimpleExtensionRange {
+ SimpleExtensionRange(int start, int end) : start(start), end(end){};
+ int start; // inclusive
+ int end; // exclusive
+
+ // Descriptors expose extension ranges in the order they were defined in the
+ // file, but this reorders and merges the ranges that are contiguous (i.e. -
+ // [(21,30),(10,20)] -> [(10,30)])
+ static std::vector<SimpleExtensionRange> Normalize(
+ const Descriptor* 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());
+
+ std::vector<SimpleExtensionRange> result;
+ result.reserve(sorted_extensions.size());
+ for (const auto ext : sorted_extensions) {
+ if (!result.empty() && result.back().end == ext->start) {
+ result.back().end = ext->end;
+ } else {
+ result.emplace_back(ext->start, ext->end);
+ }
+ }
+ return result;
+ }
+};
+
+// 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& file_description_name,
+ const Descriptor* descriptor)
+ : file_description_name_(file_description_name),
+ descriptor_(descriptor),
+ field_generators_(descriptor),
+ class_name_(ClassName(descriptor_)),
+ deprecated_attribute_(GetOptionalDeprecatedAttribute(
+ descriptor, descriptor->file(), false, true)) {
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ oneof_generators_.push_back(
+ std::make_unique<OneofGenerator>(descriptor_->oneof_decl(i)));
+ }
+
+ // 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();
+
+ sizeof_has_storage_ = sizeof_has_storage;
+}
+
+void MessageGenerator::AddExtensionGenerators(
+ std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators->push_back(std::make_unique<ExtensionGenerator>(
+ class_name_, descriptor_->extension(i)));
+ extension_generators_.push_back(extension_generators->back().get());
+ }
+}
+
+void MessageGenerator::DetermineForwardDeclarations(
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const {
+ if (IsMapEntryMessage(descriptor_)) {
+ return;
+ }
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+ field_generators_.get(fieldDescriptor)
+ .DetermineForwardDeclarations(fwd_decls, include_external_types);
+ }
+}
+
+void MessageGenerator::DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
+ if (!IsMapEntryMessage(descriptor_)) {
+ // Forward declare this class, as a linker symbol, so the symbol can be used
+ // to reference the class instead of calling +class later.
+ fwd_decls->insert(ObjCClassDeclaration(class_name_));
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+ field_generators_.get(fieldDescriptor)
+ .DetermineObjectiveCClassDefinitions(fwd_decls);
+ }
+ }
+
+ const Descriptor* containing_descriptor = descriptor_->containing_type();
+ if (containing_descriptor != nullptr) {
+ TProtoStringType containing_class = ClassName(containing_descriptor);
+ fwd_decls->insert(ObjCClassDeclaration(containing_class));
+ }
+}
+
+void MessageGenerator::GenerateMessageHeader(io::Printer* printer) const {
+ // This a a map entry message, just recurse and do nothing directly.
+ if (IsMapEntryMessage(descriptor_)) {
+ return;
+ }
+
+ printer->Print(
+ // clang-format off
+ "#pragma mark - $classname$\n"
+ "\n",
+ // clang-format on
+ "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(
+ // clang-format off
+ "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n",
+ // clang-format on
+ "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");
+ }
+}
+
+void MessageGenerator::GenerateSource(io::Printer* printer) const {
+ if (IsMapEntryMessage(descriptor_)) {
+ return;
+ }
+ printer->Print(
+ // clang-format off
+ "#pragma mark - $classname$\n"
+ "\n",
+ // clang-format on
+ "classname", class_name_);
+
+ if (!deprecated_attribute_.empty()) {
+ // No warnings when compiling the impl of this deprecated class.
+ // clang-format off
+ printer->Print(
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n"
+ "\n");
+ // clang-format on
+ }
+
+ 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<SimpleExtensionRange> sorted_extensions(
+ SimpleExtensionRange::Normalize(descriptor_));
+
+ printer->Print(
+ // clang-format off
+ "\n"
+ "typedef struct $classname$__storage_ {\n"
+ " arc_ui32 _has_storage_[$sizeof_has_storage$];\n",
+ // clang-format on
+ "classname", class_name_, "sizeof_has_storage",
+ y_absl::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_);
+
+ // clang-format off
+ 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");
+ // clang-format on
+
+ // If the message scopes extensions, trigger the root class
+ // +initialize/+extensionRegistry as that is where the runtime support for
+ // extensions lives.
+ if (descriptor_->extension_count() > 0) {
+ // clang-format off
+ printer->Print(
+ " // Start up the root class to support the scoped extensions.\n"
+ " __unused Class rootStartup = [$root_class_name$ class];\n",
+ "root_class_name", FileClassName(descriptor_->file()));
+ // clang-format on
+ } else {
+ // The Root class has a debug runtime check, so if not starting that
+ // up, add the check.
+ printer->Print(" GPB_DEBUG_CHECK_RUNTIME_VERSIONS();\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();
+ }
+
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> vars;
+ vars["classname"] = class_name_;
+ vars["message_name"] = descriptor_->name();
+ vars["class_reference"] = ObjCClass(class_name_);
+ vars["file_description_name"] = file_description_name_;
+ vars["fields"] = has_fields ? "fields" : "NULL";
+ if (has_fields) {
+ vars["fields_count"] = y_absl::StrCat("(arc_ui32)(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");
+ init_flags.push_back(
+ "GPBDescriptorInitializationFlag_ClosedEnumSupportKnown");
+ 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);
+
+ // clang-format off
+ printer->Print(
+ vars,
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:$class_reference$\n"
+ " messageName:@\"$message_name$\"\n"
+ " fileDescription:&$file_description_name$\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " flags:$init_flags$];\n");
+ // clang-format on
+ 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(
+ // clang-format off
+ " };\n"
+ " [localDescriptor setupOneofs:oneofs\n"
+ " count:(arc_ui32)(sizeof(oneofs) / sizeof(char*))\n"
+ " firstHasIndex:$first_has_index$];\n",
+ // clang-format on
+ "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());
+ // clang-format off
+ printer->Print(
+ "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
+ " static const char *extraTextFormatInfo =");
+ // clang-format on
+ 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(y_absl::CEscape(
+ text_format_data_str.substr(i, kBytesPerLine))));
+ }
+ // clang-format off
+ printer->Print(
+ ";\n"
+ " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
+ "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
+ // clang-format on
+ }
+ if (!sorted_extensions.empty()) {
+ printer->Print(" static const GPBExtensionRange ranges[] = {\n");
+ for (const auto& extension_range : sorted_extensions) {
+ printer->Print(" { .start = $start$, .end = $end$ },\n", "start",
+ y_absl::StrCat(extension_range.start), "end",
+ y_absl::StrCat(extension_range.end));
+ }
+ // clang-format off
+ printer->Print(
+ " };\n"
+ " [localDescriptor setupExtensionRanges:ranges\n"
+ " count:(arc_ui32)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
+ // clang-format on
+ }
+ if (descriptor_->containing_type() != nullptr) {
+ TProtoStringType containing_class = ClassName(descriptor_->containing_type());
+ TProtoStringType parent_class_ref = ObjCClass(containing_class);
+ printer->Print(
+ // clang-format off
+ " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
+ // clang-format on
+ "parent_class_ref", parent_class_ref);
+ }
+ // clang-format off
+ 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");
+ // clang-format on
+
+ if (!deprecated_attribute_.empty()) {
+ // clang-format off
+ printer->Print(
+ "#pragma clang diagnostic pop\n"
+ "\n");
+ // clang-format on
+ }
+
+ 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);
+ }
+}
+
+} // 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/message.h
index 71eec0d0c7..c4698371b7 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message.h
@@ -31,13 +31,16 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
+#include <cstddef>
+#include <memory>
#include <string>
-#include <set>
#include <vector>
-#include <google/protobuf/compiler/objectivec/objectivec_field.h>
-#include <google/protobuf/compiler/objectivec/objectivec_oneof.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
+
+#include "y_absl/container/btree_set.h"
+#include "google/protobuf/compiler/objectivec/field.h"
+#include "google/protobuf/compiler/objectivec/oneof.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -45,50 +48,39 @@ namespace compiler {
namespace objectivec {
class ExtensionGenerator;
-class EnumGenerator;
class MessageGenerator {
public:
- MessageGenerator(const TProtoStringType& root_classname,
+ MessageGenerator(const TProtoStringType& file_description_name,
const Descriptor* descriptor);
- ~MessageGenerator();
+ ~MessageGenerator() = default;
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,
- bool include_external_types);
+ void AddExtensionGenerators(
+ std::vector<std::unique_ptr<ExtensionGenerator>>* extension_generators);
+
+ void GenerateMessageHeader(io::Printer* printer) const;
+ void GenerateSource(io::Printer* printer) const;
+ void DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const;
+ void DetermineForwardDeclarations(y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const;
// Checks if the message or a nested message includes a oneof definition.
- bool IncludesOneOfDefinition() const;
+ bool IncludesOneOfDefinition() const { return !oneof_generators_.empty(); }
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 TProtoStringType file_description_name_;
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<const ExtensionGenerator*> extension_generators_;
std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_;
+ size_t sizeof_has_storage_;
};
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.cc
index 8ae073a12a..5156b4f21f 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.cc
@@ -28,12 +28,14 @@
// (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 "google/protobuf/compiler/objectivec/message_field.h"
+
#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 "y_absl/container/btree_set.h"
+#include "y_absl/container/flat_hash_map.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
namespace google {
namespace protobuf {
@@ -42,8 +44,9 @@ namespace objectivec {
namespace {
-void SetMessageVariables(const FieldDescriptor* descriptor,
- std::map<TProtoStringType, TProtoStringType>* variables) {
+void SetMessageVariables(
+ const FieldDescriptor* descriptor,
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables) {
const TProtoStringType& message_type = ClassName(descriptor->message_type());
const TProtoStringType& containing_class =
ClassName(descriptor->containing_type());
@@ -62,26 +65,24 @@ MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor)
SetMessageVariables(descriptor, &variables_);
}
-MessageFieldGenerator::~MessageFieldGenerator() {}
-
void MessageFieldGenerator::DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const {
- ObjCObjFieldGenerator::DetermineForwardDeclarations(
- fwd_decls, include_external_types);
+ ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls,
+ include_external_types);
// Within a file there is no requirement on the order of the messages, so
// local references need a forward declaration. External files (not WKTs),
// need one when requested.
- if ((include_external_types &&
- !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) ||
+ if ((include_external_types && !IsProtobufLibraryBundledProtoFile(
+ descriptor_->message_type()->file())) ||
descriptor_->file() == descriptor_->message_type()->file()) {
// Class name is already in "storage_type".
- fwd_decls->insert("@class " + variable("storage_type"));
+ fwd_decls->insert(y_absl::StrCat("@class ", variable("storage_type"), ";"));
}
}
void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const {
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}
@@ -89,31 +90,30 @@ RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
const FieldDescriptor* descriptor)
: RepeatedFieldGenerator(descriptor) {
SetMessageVariables(descriptor, &variables_);
+ TProtoStringType storage_type = variables_["storage_type"];
variables_["array_storage_type"] = "NSMutableArray";
variables_["array_property_type"] =
- "NSMutableArray<" + variables_["storage_type"] + "*>";
+ y_absl::StrCat("NSMutableArray<", storage_type, "*>");
}
-RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
-
void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
+ y_absl::btree_set<TProtoStringType>* fwd_decls,
bool include_external_types) const {
- RepeatedFieldGenerator::DetermineForwardDeclarations(
- fwd_decls, include_external_types);
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls,
+ include_external_types);
// Within a file there is no requirement on the order of the messages, so
// local references need a forward declaration. External files (not WKTs),
// need one when requested.
- if ((include_external_types &&
- !IsProtobufLibraryBundledProtoFile(descriptor_->message_type()->file())) ||
+ if ((include_external_types && !IsProtobufLibraryBundledProtoFile(
+ descriptor_->message_type()->file())) ||
descriptor_->file() == descriptor_->message_type()->file()) {
// Class name is already in "storage_type".
- fwd_decls->insert("@class " + variable("storage_type"));
+ fwd_decls->insert(y_absl::StrCat("@class ", variable("storage_type"), ";"));
}
}
void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const {
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const {
fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.h
index 50ddb633cc..303b69a7c6 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/message_field.h
@@ -31,9 +31,10 @@
#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>
+
+#include "y_absl/container/btree_set.h"
+#include "google/protobuf/compiler/objectivec/field.h"
namespace google {
namespace protobuf {
@@ -45,18 +46,16 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator {
protected:
explicit MessageFieldGenerator(const FieldDescriptor* descriptor);
+ ~MessageFieldGenerator() override = default;
MessageFieldGenerator(const MessageFieldGenerator&) = delete;
MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
- virtual ~MessageFieldGenerator();
-
public:
- virtual void DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
- bool include_external_types) const override;
- virtual void DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const override;
+ void DetermineForwardDeclarations(y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const override;
+ void DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const override;
};
class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
@@ -64,17 +63,17 @@ class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
protected:
explicit RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~RepeatedMessageFieldGenerator();
+ ~RepeatedMessageFieldGenerator() override = default;
RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
- RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete;
+ RepeatedMessageFieldGenerator operator=(
+ const RepeatedMessageFieldGenerator&) = delete;
public:
- virtual void DetermineForwardDeclarations(
- std::set<TProtoStringType>* fwd_decls,
- bool include_external_types) const override;
- virtual void DetermineObjectiveCClassDefinitions(
- std::set<TProtoStringType>* fwd_decls) const override;
+ void DetermineForwardDeclarations(y_absl::btree_set<TProtoStringType>* fwd_decls,
+ bool include_external_types) const override;
+ void DetermineObjectiveCClassDefinitions(
+ y_absl::btree_set<TProtoStringType>* fwd_decls) const override;
};
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.cc
new file mode 100644
index 0000000000..3a3ee8ffd0
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.cc
@@ -0,0 +1,1247 @@
+// 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/names.h"
+
+#include <algorithm>
+#include <climits>
+#include <fstream>
+#include <iostream>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "y_absl/container/flat_hash_set.h"
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/str_cat.h"
+#include "y_absl/strings/str_split.h"
+#include "google/protobuf/compiler/code_generator.h"
+#include "google/protobuf/compiler/objectivec/line_consumer.h"
+#include "google/protobuf/compiler/objectivec/nsobject_methods.h"
+#include "google/protobuf/descriptor.pb.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 {
+
+namespace {
+
+bool BoolFromEnvVar(const char* env_var, bool default_value) {
+ const char* value = getenv(env_var);
+ if (value) {
+ return TProtoStringType("YES") == y_absl::AsciiStrToUpper(value);
+ }
+ return default_value;
+}
+
+class SimpleLineCollector : public LineConsumer {
+ public:
+ explicit SimpleLineCollector(y_absl::flat_hash_set<TProtoStringType>* inout_set)
+ : set_(inout_set) {}
+
+ bool ConsumeLine(y_absl::string_view line, TProtoStringType* out_error) override {
+ set_->insert(TProtoStringType(line));
+ return true;
+ }
+
+ private:
+ y_absl::flat_hash_set<TProtoStringType>* set_;
+};
+
+class PackageToPrefixesCollector : public LineConsumer {
+ public:
+ PackageToPrefixesCollector(y_absl::string_view usage,
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType>*
+ inout_package_to_prefix_map)
+ : usage_(usage), prefix_map_(inout_package_to_prefix_map) {}
+
+ bool ConsumeLine(y_absl::string_view line, TProtoStringType* out_error) override;
+
+ private:
+ const TProtoStringType usage_;
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType>* prefix_map_;
+};
+
+class PrefixModeStorage {
+ public:
+ PrefixModeStorage();
+
+ y_absl::string_view package_to_prefix_mappings_path() const {
+ return package_to_prefix_mappings_path_;
+ }
+ void set_package_to_prefix_mappings_path(y_absl::string_view path) {
+ package_to_prefix_mappings_path_ = TProtoStringType(path);
+ package_to_prefix_map_.clear();
+ }
+
+ y_absl::string_view prefix_from_proto_package_mappings(
+ const FileDescriptor* file);
+
+ bool use_package_name() const { return use_package_name_; }
+ void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; }
+
+ y_absl::string_view exception_path() const { return exception_path_; }
+ void set_exception_path(y_absl::string_view path) {
+ exception_path_ = TProtoStringType(path);
+ exceptions_.clear();
+ }
+
+ bool is_package_exempted(y_absl::string_view package);
+
+ // When using a proto package as the prefix, this should be added as the
+ // prefix in front of it.
+ y_absl::string_view forced_package_prefix() const { return forced_prefix_; }
+ void set_forced_package_prefix(y_absl::string_view prefix) {
+ forced_prefix_ = TProtoStringType(prefix);
+ }
+
+ private:
+ bool use_package_name_;
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType> package_to_prefix_map_;
+ TProtoStringType package_to_prefix_mappings_path_;
+ TProtoStringType exception_path_;
+ TProtoStringType forced_prefix_;
+ y_absl::flat_hash_set<TProtoStringType> exceptions_;
+};
+
+PrefixModeStorage::PrefixModeStorage() {
+ // Even thought there are generation options, have an env back door since some
+ // of these helpers could be used in other plugins.
+
+ use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false);
+
+ const char* exception_path =
+ getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH");
+ if (exception_path) {
+ exception_path_ = exception_path;
+ }
+
+ const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX");
+ if (prefix) {
+ forced_prefix_ = prefix;
+ }
+}
+
+constexpr y_absl::string_view kNoPackagePrefix = "no_package:";
+
+y_absl::string_view PrefixModeStorage::prefix_from_proto_package_mappings(
+ const FileDescriptor* file) {
+ if (!file) {
+ return "";
+ }
+
+ if (package_to_prefix_map_.empty() &&
+ !package_to_prefix_mappings_path_.empty()) {
+ TProtoStringType error_str;
+ // Re use the same collector as we use for expected_prefixes_path since the
+ // file format is the same.
+ PackageToPrefixesCollector collector("Package to prefixes",
+ &package_to_prefix_map_);
+ if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector,
+ &error_str)) {
+ if (error_str.empty()) {
+ error_str = y_absl::StrCat("protoc:0: warning: Failed to parse ",
+ "prefix to proto package mappings file: ",
+ package_to_prefix_mappings_path_);
+ }
+ std::cerr << error_str << std::endl;
+ std::cerr.flush();
+ package_to_prefix_map_.clear();
+ }
+ }
+
+ const TProtoStringType package = file->package();
+ // For files without packages, the can be registered as "no_package:PATH",
+ // allowing the expected prefixes file.
+ const TProtoStringType lookup_key =
+ package.empty() ? y_absl::StrCat(kNoPackagePrefix, file->name()) : package;
+
+ auto prefix_lookup = package_to_prefix_map_.find(lookup_key);
+
+ if (prefix_lookup != package_to_prefix_map_.end()) {
+ return prefix_lookup->second;
+ }
+
+ return "";
+}
+
+bool PrefixModeStorage::is_package_exempted(y_absl::string_view package) {
+ if (exceptions_.empty() && !exception_path_.empty()) {
+ TProtoStringType error_str;
+ SimpleLineCollector collector(&exceptions_);
+ if (!ParseSimpleFile(exception_path_, &collector, &error_str)) {
+ if (error_str.empty()) {
+ error_str = TProtoStringType("protoc:0: warning: Failed to parse") +
+ TProtoStringType(" package prefix exceptions file: ") +
+ exception_path_;
+ }
+ std::cerr << error_str << std::endl;
+ std::cerr.flush();
+ exceptions_.clear();
+ }
+
+ // If the file was empty put something in it so it doesn't get reloaded over
+ // and over.
+ if (exceptions_.empty()) {
+ exceptions_.insert("<not a real package>");
+ }
+ }
+
+ return exceptions_.contains(package);
+}
+
+PrefixModeStorage& g_prefix_mode = *new PrefixModeStorage();
+
+} // namespace
+
+y_absl::string_view GetPackageToPrefixMappingsPath() {
+ return g_prefix_mode.package_to_prefix_mappings_path();
+}
+
+void SetPackageToPrefixMappingsPath(y_absl::string_view file_path) {
+ g_prefix_mode.set_package_to_prefix_mappings_path(file_path);
+}
+
+bool UseProtoPackageAsDefaultPrefix() {
+ return g_prefix_mode.use_package_name();
+}
+
+void SetUseProtoPackageAsDefaultPrefix(bool on_or_off) {
+ g_prefix_mode.set_use_package_name(on_or_off);
+}
+
+y_absl::string_view GetProtoPackagePrefixExceptionList() {
+ return g_prefix_mode.exception_path();
+}
+
+void SetProtoPackagePrefixExceptionList(y_absl::string_view file_path) {
+ g_prefix_mode.set_exception_path(file_path);
+}
+
+y_absl::string_view GetForcedPackagePrefix() {
+ return g_prefix_mode.forced_package_prefix();
+}
+
+void SetForcedPackagePrefix(y_absl::string_view prefix) {
+ g_prefix_mode.set_forced_package_prefix(prefix);
+}
+
+namespace {
+
+const char* const kUpperSegmentsList[] = {"url", "http", "https"};
+
+const y_absl::flat_hash_set<y_absl::string_view>& UpperSegments() {
+ static const auto* words = [] {
+ auto* words = new y_absl::flat_hash_set<y_absl::string_view>();
+
+ for (const auto word : kUpperSegmentsList) {
+ words->emplace(word);
+ }
+ return words;
+ }();
+ return *words;
+}
+
+// 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(y_absl::string_view 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 (y_absl::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 (y_absl::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 (y_absl::ascii_isupper(c)) {
+ if (!last_char_was_upper) {
+ values.push_back(current);
+ current = "";
+ }
+ current += y_absl::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 (auto& value : values) {
+ bool all_upper = UpperSegments().contains(value);
+ if (all_upper && (result.length() == 0)) {
+ first_segment_forces_upper = true;
+ }
+ if (all_upper) {
+ y_absl::AsciiStrToUpper(&value);
+ } else {
+ value[0] = y_absl::ascii_toupper(value[0]);
+ }
+ result += value;
+ }
+ if ((result.length() != 0) && !first_capitalized &&
+ !first_segment_forces_upper) {
+ result[0] = y_absl::ascii_tolower(result[0]);
+ }
+ return result;
+}
+
+const char* const kReservedWordList[] = {
+ // Note NSObject Methods:
+ // These are brought in from 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",
+};
+
+const y_absl::flat_hash_set<y_absl::string_view>& ReservedWords() {
+ static const auto* words = [] {
+ auto* words = new y_absl::flat_hash_set<y_absl::string_view>();
+
+ for (const auto word : kReservedWordList) {
+ words->emplace(word);
+ }
+ return words;
+ }();
+ return *words;
+}
+
+const y_absl::flat_hash_set<y_absl::string_view>& NSObjectMethods() {
+ static const auto* words = [] {
+ auto* words = new y_absl::flat_hash_set<y_absl::string_view>();
+
+ for (const auto word : kNSObjectMethodsList) {
+ words->emplace(word);
+ }
+ return words;
+ }();
+ return *words;
+}
+
+// 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(y_absl::string_view input) {
+ if (input.length() > 2) {
+ if (input.at(0) == '_') {
+ if (isupper(input.at(1)) || input.at(1) == '_') {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+TProtoStringType SanitizeNameForObjC(y_absl::string_view prefix,
+ y_absl::string_view input,
+ y_absl::string_view extension,
+ TProtoStringType* out_suffix_added) {
+ 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 (y_absl::StartsWith(input, prefix)) {
+ if (input.length() == prefix.length() ||
+ !y_absl::ascii_isupper(input[prefix.length()])) {
+ sanitized = y_absl::StrCat(prefix, input);
+ } else {
+ sanitized = TProtoStringType(input);
+ }
+ } else {
+ sanitized = y_absl::StrCat(prefix, input);
+ }
+ if (IsReservedCIdentifier(sanitized) || ReservedWords().contains(sanitized) ||
+ NSObjectMethods().contains(sanitized)) {
+ if (out_suffix_added) *out_suffix_added = TProtoStringType(extension);
+ return y_absl::StrCat(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(y_absl::string_view path, TProtoStringType* directory,
+ TProtoStringType* basename) {
+ y_absl::string_view::size_type last_slash = path.rfind('/');
+ if (last_slash == y_absl::string_view::npos) {
+ if (directory) {
+ *directory = "";
+ }
+ if (basename) {
+ *basename = TProtoStringType(path);
+ }
+ } else {
+ if (directory) {
+ *directory = TProtoStringType(path.substr(0, last_slash));
+ }
+ if (basename) {
+ *basename = TProtoStringType(path.substr(last_slash + 1));
+ }
+ }
+}
+
+bool IsSpecialNamePrefix(y_absl::string_view name,
+ const std::vector<TProtoStringType>& special_names) {
+ for (const auto& special_name : special_names) {
+ const size_t length = special_name.length();
+ if (name.compare(0, length, special_name) == 0) {
+ if (name.length() > length) {
+ // If name is longer than the special_name that it matches the next
+ // character must be not lower case (newton vs newTon vs new_ton).
+ return !y_absl::ascii_islower(name[length]);
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void MaybeUnQuote(y_absl::string_view* input) {
+ if ((input->length() >= 2) &&
+ ((*input->data() == '\'' || *input->data() == '"')) &&
+ ((*input)[input->length() - 1] == *input->data())) {
+ input->remove_prefix(1);
+ input->remove_suffix(1);
+ }
+}
+
+} // namespace
+
+bool IsRetainedName(y_absl::string_view name) {
+ // List of prefixes from
+ // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
+ static const std::vector<TProtoStringType>* retained_names =
+ new std::vector<TProtoStringType>({"new", "alloc", "copy", "mutableCopy"});
+ return IsSpecialNamePrefix(name, *retained_names);
+}
+
+bool IsInitName(y_absl::string_view name) {
+ static const std::vector<TProtoStringType>* init_names =
+ new std::vector<TProtoStringType>({"init"});
+ return IsSpecialNamePrefix(name, *init_names);
+}
+
+bool IsCreateName(y_absl::string_view name) {
+ // List of segments from
+ // https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029
+ static const std::vector<TProtoStringType>* create_names =
+ new std::vector<TProtoStringType>({"Create", "Copy"});
+
+ for (const auto& create_name : *create_names) {
+ const size_t length = create_name.length();
+ size_t pos = name.find(create_name);
+ if (pos != TProtoStringType::npos) {
+ // The above docs don't actually call out anything about the characters
+ // before the special words. So it's not clear if something like
+ // "FOOCreate" would or would not match the "The Create Rule", but by not
+ // checking, and claiming it does match, then callers will annotate with
+ // `cf_returns_not_retained` which will ensure things work as desired.
+ //
+ // The footnote here is the docs do have a passing reference to "NoCopy",
+ // but again, not looking for that and just returning `true` will cause
+ // callers to annotate the api as not being a Create Rule function.
+
+ // If name is longer than the create_names[i] that it matches the next
+ // character must be not lower case (Copyright vs CopyFoo vs Copy_Foo).
+ if (name.length() > pos + length) {
+ return !y_absl::ascii_islower(name[pos + length]);
+ } else {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+TProtoStringType BaseFileName(const FileDescriptor* file) {
+ TProtoStringType basename;
+ PathSplit(file->name(), nullptr, &basename);
+ return basename;
+}
+
+TProtoStringType FileClassPrefix(const FileDescriptor* file) {
+ // Always honor the file option.
+ if (file->options().has_objc_class_prefix()) {
+ return file->options().objc_class_prefix();
+ }
+
+ // If package prefix is specified in an prefix to proto mappings file then use
+ // that.
+ y_absl::string_view objc_class_prefix =
+ g_prefix_mode.prefix_from_proto_package_mappings(file);
+ if (!objc_class_prefix.empty()) {
+ return TProtoStringType(objc_class_prefix);
+ }
+
+ // If package prefix isn't enabled, done.
+ if (!g_prefix_mode.use_package_name()) {
+ return "";
+ }
+
+ // If the package is in the exceptions list, done.
+ if (g_prefix_mode.is_package_exempted(file->package())) {
+ return "";
+ }
+
+ // Transform the package into a prefix: use the dot segments as part,
+ // camelcase each one and then join them with underscores, and add an
+ // underscore at the end.
+ TProtoStringType result;
+ const std::vector<TProtoStringType> segments =
+ y_absl::StrSplit(file->package(), '.', y_absl::SkipEmpty());
+ for (const auto& segment : segments) {
+ const TProtoStringType part = UnderscoresToCamelCase(segment, true);
+ if (part.empty()) {
+ continue;
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ result.append(part);
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ return y_absl::StrCat(g_prefix_mode.forced_package_prefix(), result);
+}
+
+TProtoStringType FilePath(const FileDescriptor* file) {
+ TProtoStringType output;
+ TProtoStringType basename;
+ TProtoStringType directory;
+ PathSplit(file->name(), &directory, &basename);
+ if (directory.length() > 0) {
+ output = y_absl::StrCat(directory, "/");
+ }
+ basename = StripProto(basename);
+
+ // CamelCase to be more ObjC friendly.
+ basename = UnderscoresToCamelCase(basename, true);
+
+ return y_absl::StrCat(output, basename);
+}
+
+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 = y_absl::StrCat(
+ 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", nullptr);
+}
+
+TProtoStringType ClassNameWorker(const Descriptor* descriptor) {
+ TProtoStringType name;
+ if (descriptor->containing_type() != nullptr) {
+ return y_absl::StrCat(ClassNameWorker(descriptor->containing_type()), "_",
+ descriptor->name());
+ }
+ return y_absl::StrCat(name, descriptor->name());
+}
+
+TProtoStringType ClassNameWorker(const EnumDescriptor* descriptor) {
+ TProtoStringType name;
+ if (descriptor->containing_type() != nullptr) {
+ return y_absl::StrCat(ClassNameWorker(descriptor->containing_type()), "_",
+ descriptor->name());
+ }
+ return y_absl::StrCat(name, descriptor->name());
+}
+
+TProtoStringType ClassName(const Descriptor* descriptor) {
+ return ClassName(descriptor, nullptr);
+}
+
+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", nullptr);
+}
+
+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 = y_absl::StrCat(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", nullptr);
+}
+
+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 = y_absl::StrCat(class_name, "_");
+ const TProtoStringType long_name = EnumValueName(descriptor);
+ return TProtoStringType(y_absl::StripPrefix(long_name, long_name_prefix));
+}
+
+TProtoStringType UnCamelCaseEnumShortName(y_absl::string_view name) {
+ TProtoStringType result;
+ for (int i = 0; i < name.size(); i++) {
+ char c = name[i];
+ if (i > 0 && y_absl::ascii_isupper(c)) {
+ result += '_';
+ }
+ result += y_absl::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", nullptr);
+}
+
+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.
+ y_absl::StrAppend(&result, "Array");
+ } else {
+ // If it wasn't repeated, but ends in "Array", force on the _p suffix.
+ if (y_absl::EndsWith(result, "Array")) {
+ y_absl::StrAppend(&result, "_p");
+ }
+ }
+ return SanitizeNameForObjC("", result, "_p", nullptr);
+}
+
+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] = y_absl::ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+TProtoStringType OneofEnumName(const OneofDescriptor* descriptor) {
+ const Descriptor* fieldDescriptor = descriptor->containing_type();
+ TProtoStringType name = y_absl::StrCat(
+ ClassName(fieldDescriptor), "_",
+ 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] = y_absl::ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+TProtoStringType UnCamelCaseFieldName(y_absl::string_view name,
+ const FieldDescriptor* field) {
+ y_absl::string_view worker(name);
+ if (y_absl::EndsWith(worker, "_p")) {
+ worker = y_absl::StripSuffix(worker, "_p");
+ }
+ if (field->is_repeated() && y_absl::EndsWith(worker, "Array")) {
+ worker = y_absl::StripSuffix(worker, "Array");
+ }
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ if (worker.length() > 0) {
+ if (y_absl::ascii_islower(worker[0])) {
+ TProtoStringType copy(worker);
+ copy[0] = y_absl::ascii_toupper(worker[0]);
+ return copy;
+ }
+ }
+ return TProtoStringType(worker);
+ } else {
+ TProtoStringType result;
+ for (int i = 0; i < worker.size(); i++) {
+ char c = worker[i];
+ if (y_absl::ascii_isupper(c)) {
+ if (i > 0) {
+ result += '_';
+ }
+ result += y_absl::ascii_tolower(c);
+ } else {
+ result += c;
+ }
+ }
+ return result;
+ }
+}
+
+// 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(y_absl::string_view framework_name) {
+ // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
+ return y_absl::StrCat("GPB_USE_", y_absl::AsciiStrToUpper(framework_name),
+ "_FRAMEWORK_IMPORTS");
+}
+
+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;
+}
+
+namespace {
+
+bool PackageToPrefixesCollector::ConsumeLine(y_absl::string_view line,
+ TProtoStringType* out_error) {
+ int offset = line.find('=');
+ if (offset == y_absl::string_view::npos) {
+ *out_error =
+ y_absl::StrCat(usage_, " file line without equal sign: '", line, "'.");
+ return false;
+ }
+ y_absl::string_view package =
+ y_absl::StripAsciiWhitespace(line.substr(0, offset));
+ y_absl::string_view prefix =
+ y_absl::StripAsciiWhitespace(line.substr(offset + 1));
+ MaybeUnQuote(&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_)[package] = TProtoStringType(prefix);
+ return true;
+}
+
+bool LoadExpectedPackagePrefixes(
+ y_absl::string_view expected_prefixes_path,
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType>* prefix_map,
+ TProtoStringType* out_error) {
+ if (expected_prefixes_path.empty()) {
+ return true;
+ }
+
+ PackageToPrefixesCollector collector("Expected prefixes", prefix_map);
+ return ParseSimpleFile(expected_prefixes_path, &collector, out_error);
+}
+
+bool ValidateObjCClassPrefix(
+ const FileDescriptor* file, y_absl::string_view expected_prefixes_path,
+ const y_absl::flat_hash_map<TProtoStringType, TProtoStringType>&
+ expected_package_prefixes,
+ bool prefixes_must_be_registered, bool require_prefixes,
+ TProtoStringType* out_error) {
+ // Reminder: An explicit prefix option of "" is valid in case the default
+ // prefixing is set to use the proto package and a file needs to be generated
+ // without any prefix at all (for legacy reasons).
+
+ bool has_prefix = file->options().has_objc_class_prefix();
+ bool have_expected_prefix_file = !expected_prefixes_path.empty();
+
+ const TProtoStringType prefix = file->options().objc_class_prefix();
+ const TProtoStringType package = file->package();
+ // For files without packages, the can be registered as "no_package:PATH",
+ // allowing the expected prefixes file.
+ const TProtoStringType lookup_key =
+ package.empty() ? y_absl::StrCat(kNoPackagePrefix, file->name()) : package;
+
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for warnings.
+
+ // Check: Error - See if there was an expected prefix for the package and
+ // report if it doesn't match (wrong or missing).
+ auto package_match = expected_package_prefixes.find(lookup_key);
+ if (package_match != expected_package_prefixes.end()) {
+ // There was an entry, and...
+ if (has_prefix && package_match->second == prefix) {
+ // ...it matches. All good, out of here!
+ return true;
+ } else {
+ // ...it didn't match!
+ *out_error =
+ y_absl::StrCat("error: Expected 'option objc_class_prefix = \"",
+ package_match->second, "\";'");
+ if (!package.empty()) {
+ y_absl::StrAppend(out_error, " for package '", package, "'");
+ }
+ y_absl::StrAppend(out_error, " in '", file->name(), "'");
+ if (has_prefix) {
+ y_absl::StrAppend(out_error, "; but found '", prefix, "' instead");
+ }
+ y_absl::StrAppend(out_error, ".");
+ return false;
+ }
+ }
+
+ // If there was no prefix option, we're done at this point.
+ if (!has_prefix) {
+ if (require_prefixes) {
+ *out_error = y_absl::StrCat("error: '", file->name(),
+ "' does not have a required 'option"
+ " objc_class_prefix'.");
+ return false;
+ }
+ return true;
+ }
+
+ // When the prefix is non empty, check it against the expected entries.
+ if (!prefix.empty() && have_expected_prefix_file) {
+ // For a non empty prefix, look for any other package that uses the prefix.
+ TProtoStringType other_package_for_prefix;
+ for (auto i = expected_package_prefixes.begin();
+ i != expected_package_prefixes.end(); ++i) {
+ if (i->second == prefix) {
+ other_package_for_prefix = i->first;
+ // Stop on the first real package listing, if it was a no_package file
+ // specific entry, keep looking to try and find a package one.
+ if (!y_absl::StartsWith(other_package_for_prefix, kNoPackagePrefix)) {
+ break;
+ }
+ }
+ }
+
+ // 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 = y_absl::StrCat("error: Found 'option objc_class_prefix = \"",
+ prefix, "\";' in '", file->name(),
+ "'; that prefix is already used for ");
+ if (y_absl::StartsWith(other_package_for_prefix, kNoPackagePrefix)) {
+ y_absl::StrAppend(
+ out_error, "file '",
+ y_absl::StripPrefix(other_package_for_prefix, kNoPackagePrefix),
+ "'.");
+ } else {
+ y_absl::StrAppend(out_error, "'package ", other_package_for_prefix,
+ ";'.");
+ }
+ y_absl::StrAppend(out_error, " It can only be reused by adding '",
+ lookup_key, " = ", prefix,
+ "' to the expected prefixes file (",
+ expected_prefixes_path, ").");
+ return false; // Only report first usage of the prefix.
+ }
+ } // !prefix.empty() && have_expected_prefix_file
+
+ // Check: Warning - Make sure the prefix is is a reasonable value according
+ // to Apple's rules (the checks above implicitly whitelist anything that
+ // doesn't meet these rules).
+ if (!prefix.empty() && !y_absl::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.empty() && 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();
+ }
+
+ // Check: Error/Warning - If the given package/prefix pair wasn't expected,
+ // issue a error/warning to added to the file.
+ if (have_expected_prefix_file) {
+ if (prefixes_must_be_registered) {
+ *out_error = y_absl::StrCat(
+ "error: '", file->name(), "' has 'option objc_class_prefix = \"",
+ prefix, "\";', but it is not registered. Add '", lookup_key, " = ",
+ (prefix.empty() ? "\"\"" : prefix),
+ "' to the expected prefixes file (", expected_prefixes_path, ").");
+ return false;
+ }
+
+ std::cerr
+ << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
+ << prefix << "\";' in '" << file->name() << "'; consider adding '"
+ << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix)
+ << "' to the expected prefixes file (" << expected_prefixes_path << ")."
+ << std::endl;
+ std::cerr.flush();
+ }
+
+ return true;
+}
+
+} // namespace
+
+Options::Options() {
+ // While there are generator options, also support env variables to help with
+ // build systems where it isn't as easy to hook in for add the generation
+ // options when invoking protoc.
+ const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
+ if (file_path) {
+ expected_prefixes_path = file_path;
+ }
+ const char* suppressions =
+ getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
+ if (suppressions) {
+ expected_prefixes_suppressions =
+ y_absl::StrSplit(suppressions, ';', y_absl::SkipEmpty());
+ }
+ prefixes_must_be_registered =
+ BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false);
+ require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false);
+}
+
+bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
+ TProtoStringType* out_error) {
+ // Options's ctor load from the environment.
+ Options options;
+ return ValidateObjCClassPrefixes(files, options, out_error);
+}
+
+bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
+ const Options& validation_options,
+ TProtoStringType* out_error) {
+ // Allow a '-' as the path for the expected prefixes to completely disable
+ // even the most basic of checks.
+ if (validation_options.expected_prefixes_path == "-") {
+ return true;
+ }
+
+ // Load the expected package prefixes, if available, to validate against.
+ y_absl::flat_hash_map<TProtoStringType, TProtoStringType> expected_package_prefixes;
+ if (!LoadExpectedPackagePrefixes(validation_options.expected_prefixes_path,
+ &expected_package_prefixes, out_error)) {
+ return false;
+ }
+
+ for (auto file : files) {
+ bool should_skip =
+ (std::find(validation_options.expected_prefixes_suppressions.begin(),
+ validation_options.expected_prefixes_suppressions.end(),
+ file->name()) !=
+ validation_options.expected_prefixes_suppressions.end());
+ if (should_skip) {
+ continue;
+ }
+
+ bool is_valid =
+ ValidateObjCClassPrefix(file, validation_options.expected_prefixes_path,
+ expected_package_prefixes,
+ validation_options.prefixes_must_be_registered,
+ validation_options.require_prefixes, out_error);
+ if (!is_valid) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.h
new file mode 100644
index 0000000000..3ee2cd8e90
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/names.h
@@ -0,0 +1,179 @@
+// 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_NAMES_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_NAMES_H__
+
+#include <string>
+#include <vector>
+
+#include "google/protobuf/descriptor.h"
+
+// Must be included last
+#include "google/protobuf/port_def.inc"
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// Get/Set the path to a file to load for objc class prefix lookups.
+PROTOC_EXPORT y_absl::string_view GetPackageToPrefixMappingsPath();
+PROTOC_EXPORT void SetPackageToPrefixMappingsPath(y_absl::string_view file_path);
+// Get/Set if the proto package should be used to make the default prefix for
+// symbols. This will then impact most of the type naming apis below. It is done
+// as a global to not break any other generator reusing the methods since they
+// are exported.
+PROTOC_EXPORT bool UseProtoPackageAsDefaultPrefix();
+PROTOC_EXPORT void SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
+// Get/Set the path to a file to load as exceptions when
+// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there
+// should be no exceptions.
+PROTOC_EXPORT y_absl::string_view GetProtoPackagePrefixExceptionList();
+PROTOC_EXPORT void SetProtoPackagePrefixExceptionList(
+ y_absl::string_view file_path);
+// Get/Set a prefix to add before the prefix generated from the package name.
+// This is only used when UseProtoPackageAsDefaultPrefix() is True.
+PROTOC_EXPORT y_absl::string_view GetForcedPackagePrefix();
+PROTOC_EXPORT void SetForcedPackagePrefix(y_absl::string_view prefix);
+
+// Returns true if the name requires a ns_returns_not_retained attribute applied
+// to it.
+PROTOC_EXPORT bool IsRetainedName(y_absl::string_view name);
+
+// Returns true if the name starts with "init" and will need to have special
+// handling under ARC.
+PROTOC_EXPORT bool IsInitName(y_absl::string_view name);
+
+// Returns true if the name requires a cf_returns_not_retained attribute applied
+// to it.
+PROTOC_EXPORT bool IsCreateName(y_absl::string_view name);
+
+// Gets the objc_class_prefix or the prefix made from the proto package.
+PROTOC_EXPORT TProtoStringType 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.
+PROTOC_EXPORT TProtoStringType FilePath(const FileDescriptor* file);
+
+// Just like FilePath(), but without the directory part.
+PROTOC_EXPORT TProtoStringType 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
+PROTOC_EXPORT TProtoStringType FileClassName(const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+PROTOC_EXPORT TProtoStringType ClassName(const Descriptor* descriptor);
+PROTOC_EXPORT TProtoStringType ClassName(const Descriptor* descriptor,
+ TProtoStringType* out_suffix_added);
+PROTOC_EXPORT TProtoStringType EnumName(const EnumDescriptor* descriptor);
+
+// Returns the fully-qualified name of the enum value corresponding to the
+// the descriptor.
+PROTOC_EXPORT TProtoStringType EnumValueName(const EnumValueDescriptor* descriptor);
+
+// Returns the name of the enum value corresponding to the descriptor.
+PROTOC_EXPORT TProtoStringType EnumValueShortName(
+ const EnumValueDescriptor* descriptor);
+
+// Reverse what an enum does.
+PROTOC_EXPORT TProtoStringType UnCamelCaseEnumShortName(y_absl::string_view name);
+
+// Returns the name to use for the extension (used as the method off the file's
+// Root class).
+PROTOC_EXPORT TProtoStringType ExtensionMethodName(
+ const FieldDescriptor* descriptor);
+
+// Returns the transformed field name.
+PROTOC_EXPORT TProtoStringType FieldName(const FieldDescriptor* field);
+PROTOC_EXPORT TProtoStringType FieldNameCapitalized(const FieldDescriptor* field);
+
+// Returns the transformed oneof name.
+PROTOC_EXPORT TProtoStringType OneofEnumName(const OneofDescriptor* descriptor);
+PROTOC_EXPORT TProtoStringType OneofName(const OneofDescriptor* descriptor);
+PROTOC_EXPORT TProtoStringType OneofNameCapitalized(
+ const OneofDescriptor* descriptor);
+
+// Reverse of the above.
+PROTOC_EXPORT TProtoStringType UnCamelCaseFieldName(y_absl::string_view name,
+ const FieldDescriptor* field);
+
+// 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.
+PROTOC_EXPORT TProtoStringType ProtobufFrameworkImportSymbol(
+ y_absl::string_view framework_name);
+
+// ---------------------------------------------------------------------------
+
+// These aren't really "naming" related, but can be useful for something
+// building on top of ObjC Protos to be able to share the knowledge/enforcement.
+
+// Checks if the file is one of the proto's bundled with the library.
+PROTOC_EXPORT bool IsProtobufLibraryBundledProtoFile(
+ const FileDescriptor* file);
+
+// Generator Prefix Validation Options (see generator.cc for a
+// description of each):
+struct Options {
+ Options();
+ TProtoStringType expected_prefixes_path;
+ std::vector<TProtoStringType> expected_prefixes_suppressions;
+ bool prefixes_must_be_registered;
+ bool require_prefixes;
+};
+
+// 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.
+PROTOC_EXPORT bool ValidateObjCClassPrefixes(
+ const std::vector<const FileDescriptor*>& files,
+ const Options& validation_options, TProtoStringType* out_error);
+// Same was the other ValidateObjCClassPrefixes() calls, but the options all
+// come from the environment variables.
+PROTOC_EXPORT bool ValidateObjCClassPrefixes(
+ const std::vector<const FileDescriptor*>& files, TProtoStringType* out_error);
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include "google/protobuf/port_undef.inc"
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_NAMES_H__
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/nsobject_methods.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/nsobject_methods.h
new file mode 100644
index 0000000000..7a1b9ef2cd
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/nsobject_methods.h
@@ -0,0 +1,227 @@
+// 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.
+
+// 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_file.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc
deleted file mode 100644
index e1bb09f996..0000000000
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ /dev/null
@@ -1,681 +0,0 @@
-// 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_helpers.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 arc_i32 GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
-
-const char* kHeaderExtension = ".pbobjc.h";
-
-TProtoStringType BundledFileName(const FileDescriptor* file) {
- return "GPB" + FilePathBasename(file) + kHeaderExtension;
-}
-
-// Checks if a message contains any enums definitions (on the message or
-// a nested message under it).
-bool MessageContainsEnums(const Descriptor* message) {
- 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;
-}
-
-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;
-}
-
-struct FileDescriptorsOrderedByName {
- inline bool operator()(const FileDescriptor* a,
- const FileDescriptor* b) const {
- return a->name() < b->name();
- }
-};
-
-} // namespace
-
-FileGenerator::CommonState::CommonState() { }
-
-const FileGenerator::CommonState::MinDepsEntry&
-FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensionsInternal(
- const FileDescriptor* file) {
- auto it = deps_info_cache_.find(file);
- if (it != deps_info_cache_.end()) {
- return it->second;
- }
-
- std::set<const FileDescriptor*> min_deps_collector;
- std::set<const FileDescriptor*> covered_deps_collector;
- std::set<const FileDescriptor*> to_prune;
- for (int i = 0; i < file->dependency_count(); i++) {
- const FileDescriptor* dep = file->dependency(i);
- MinDepsEntry dep_info =
- CollectMinimalFileDepsContainingExtensionsInternal(dep);
-
- // Everything the dep covered, this file will also cover.
- covered_deps_collector.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end());
- // Prune everything from the dep's covered list in case another dep lists it
- // as a min dep.
- to_prune.insert(dep_info.covered_deps.begin(), dep_info.covered_deps.end());
-
- // Does the dep have any extensions...
- if (dep_info.has_extensions) {
- // Yes -> Add this file, prune its min_deps and add them to the covered deps.
- min_deps_collector.insert(dep);
- to_prune.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
- covered_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
- } else {
- // No -> Just use its min_deps.
- min_deps_collector.insert(dep_info.min_deps.begin(), dep_info.min_deps.end());
- }
- }
-
- const bool file_has_exts = FileContainsExtensions(file);
-
- // Fast path: if nothing to prune or there was only one dep, the prune work is
- // a waste, skip it.
- if (to_prune.empty() || file->dependency_count() == 1) {
- return deps_info_cache_.insert(
- {file, {file_has_exts, min_deps_collector, covered_deps_collector}}).first->second;
- }
-
- std::set<const FileDescriptor*> min_deps;
- std::copy_if(min_deps_collector.begin(), min_deps_collector.end(),
- std::inserter(min_deps, min_deps.end()),
- [&](const FileDescriptor* value){
- return to_prune.find(value) == to_prune.end();
- });
- return deps_info_cache_.insert(
- {file, {file_has_exts, min_deps, covered_deps_collector}}).first->second;
-}
-
-// 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).
-const std::vector<const FileDescriptor*>
-FileGenerator::CommonState::CollectMinimalFileDepsContainingExtensions(
- const FileDescriptor* file) {
- std::set<const FileDescriptor*> min_deps =
- CollectMinimalFileDepsContainingExtensionsInternal(file).min_deps;
- // Sort the list since pointer order isn't stable across runs.
- std::vector<const FileDescriptor*> result(min_deps.begin(), min_deps.end());
- std::sort(result.begin(), result.end(), FileDescriptorsOrderedByName());
- return result;
-}
-
-FileGenerator::FileGenerator(const FileDescriptor* file,
- const GenerationOptions& generation_options,
- CommonState& common_state)
- : file_(file),
- generation_options_(generation_options),
- common_state_(common_state),
- root_class_name_(FileClassName(file)),
- is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) {
- for (int i = 0; i < file_->enum_type_count(); i++) {
- EnumGenerator* generator = new EnumGenerator(file_->enum_type(i));
- enum_generators_.emplace_back(generator);
- }
- for (int i = 0; i < file_->message_type_count(); i++) {
- MessageGenerator* generator =
- new MessageGenerator(root_class_name_, file_->message_type(i));
- 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");
- for (int i = 0; i < file_->dependency_count(); i++) {
- const TProtoStringType header_name = BundledFileName(file_->dependency(i));
- headers.push_back(header_name);
- }
- } else {
- headers.push_back("GPBProtocolBuffers.h");
- }
- 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));
-
- // The bundled protos (WKTs) don't use of forward declarations.
- bool headers_use_forward_declarations =
- generation_options_.headers_use_forward_declarations && !is_bundled_proto_;
-
- {
- ImportWriter import_writer(
- generation_options_.generate_for_named_framework,
- generation_options_.named_framework_to_proto_path_mappings_path,
- generation_options_.runtime_import_prefix,
- /* include_wkt_imports = */ false);
- const TProtoStringType header_extension(kHeaderExtension);
- if (headers_use_forward_declarations) {
- // #import any headers for "public imports" in the proto file.
- for (int i = 0; i < file_->public_dependency_count(); i++) {
- import_writer.AddFile(file_->public_dependency(i), header_extension);
- }
- } else {
- for (int i = 0; i < file_->dependency_count(); i++) {
- import_writer.AddFile(file_->dependency(i), header_extension);
- }
- }
- import_writer.Print(printer);
- }
-
- // 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,
- /* include_external_types = */ headers_use_forward_declarations);
- }
- 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");
- if (is_bundled_proto_) {
- headers.push_back(BundledFileName(file_));
- }
- PrintFileRuntimePreamble(printer, headers);
-
- // Enums use atomic in the generated code, so add the system import as needed.
- if (FileContainsEnums(file_)) {
- printer->Print(
- "#import <stdatomic.h>\n"
- "\n");
- }
-
- std::vector<const FileDescriptor*> deps_with_extensions =
- common_state_.CollectMinimalFileDepsContainingExtensions(file_);
-
- // The bundled protos (WKTs) don't use of forward declarations.
- bool headers_use_forward_declarations =
- generation_options_.headers_use_forward_declarations && !is_bundled_proto_;
-
- {
- ImportWriter import_writer(
- generation_options_.generate_for_named_framework,
- generation_options_.named_framework_to_proto_path_mappings_path,
- generation_options_.runtime_import_prefix,
- /* include_wkt_imports = */ false);
- const TProtoStringType header_extension(kHeaderExtension);
-
- // #import the header for this proto file.
- import_writer.AddFile(file_, header_extension);
-
- if (headers_use_forward_declarations) {
- // #import the headers for anything that a plain dependency of this proto
- // file (that means they were just an include, not a "public" include).
- std::set<TProtoStringType> public_import_names;
- for (int i = 0; i < file_->public_dependency_count(); i++) {
- public_import_names.insert(file_->public_dependency(i)->name());
- }
- for (int i = 0; i < file_->dependency_count(); i++) {
- const FileDescriptor *dep = file_->dependency(i);
- bool public_import = (public_import_names.count(dep->name()) != 0);
- if (!public_import) {
- import_writer.AddFile(dep, header_extension);
- }
- }
- }
-
- // 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());
-
- if (is_bundled_proto_) {
- // This is basically a clone of ImportWriter::PrintRuntimeImports() but
- // without the CPP symbol gate, since within the bundled files, that isn't
- // needed.
- TProtoStringType import_prefix = generation_options_.runtime_import_prefix;
- if (!import_prefix.empty()) {
- import_prefix += "/";
- }
- for (const auto& header : headers_to_import) {
- printer->Print(
- "#import \"$import_prefix$$header$\"\n",
- "import_prefix", import_prefix,
- "header", header);
- }
- } else {
- ImportWriter::PrintRuntimeImports(
- printer, headers_to_import, generation_options_.runtime_import_prefix, true);
- }
-
- printer->Print("\n");
-}
-
-} // namespace objectivec
-} // namespace compiler
-} // namespace protobuf
-} // namespace google
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
deleted file mode 100644
index 5122fa46c0..0000000000
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ /dev/null
@@ -1,2044 +0,0 @@
-// 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
-
-namespace {
-
-bool BoolFromEnvVar(const char* env_var, bool default_value) {
- const char* value = getenv(env_var);
- if (value) {
- return TProtoStringType("YES") == ToUpper(value);
- }
- return default_value;
-}
-
-class SimpleLineCollector : public LineConsumer {
- public:
- SimpleLineCollector(std::unordered_set<TProtoStringType>* inout_set)
- : set_(inout_set) {}
-
- virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override {
- set_->insert(TProtoStringType(line));
- return true;
- }
-
- private:
- std::unordered_set<TProtoStringType>* set_;
-};
-
-class PackageToPrefixesCollector : public LineConsumer {
- public:
- PackageToPrefixesCollector(const TProtoStringType &usage,
- std::map<TProtoStringType, TProtoStringType>* inout_package_to_prefix_map)
- : usage_(usage), prefix_map_(inout_package_to_prefix_map) {}
-
- virtual bool ConsumeLine(const StringPiece& line, TProtoStringType* out_error) override;
-
- private:
- const TProtoStringType usage_;
- std::map<TProtoStringType, TProtoStringType>* prefix_map_;
-};
-
-class PrefixModeStorage {
- public:
- PrefixModeStorage();
-
- const TProtoStringType package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; }
- void set_package_to_prefix_mappings_path(const TProtoStringType& path) {
- package_to_prefix_mappings_path_ = path;
- package_to_prefix_map_.clear();
- }
-
- TProtoStringType prefix_from_proto_package_mappings(const FileDescriptor* file);
-
- bool use_package_name() const { return use_package_name_; }
- void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; }
-
- const TProtoStringType exception_path() const { return exception_path_; }
- void set_exception_path(const TProtoStringType& path) {
- exception_path_ = path;
- exceptions_.clear();
- }
-
- bool is_package_exempted(const TProtoStringType& package);
-
- // When using a proto package as the prefix, this should be added as the
- // prefix in front of it.
- const TProtoStringType& forced_package_prefix() const { return forced_prefix_; }
-
- private:
- bool use_package_name_;
- std::map<TProtoStringType, TProtoStringType> package_to_prefix_map_;
- TProtoStringType package_to_prefix_mappings_path_;
- TProtoStringType exception_path_;
- TProtoStringType forced_prefix_;
- std::unordered_set<TProtoStringType> exceptions_;
-};
-
-PrefixModeStorage::PrefixModeStorage() {
- // Even thought there are generation options, have an env back door since some
- // of these helpers could be used in other plugins.
-
- use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false);
-
- const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH");
- if (exception_path) {
- exception_path_ = exception_path;
- }
-
- // This one is a not expected to be common, so it doesn't get a generation
- // option, just the env var.
- const char* prefix = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX_PREFIX");
- if (prefix) {
- forced_prefix_ = prefix;
- }
-}
-
-TProtoStringType PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) {
- if (!file) {
- return "";
- }
-
- if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) {
- TProtoStringType error_str;
- // Re use the same collector as we use for expected_prefixes_path since the file
- // format is the same.
- PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_);
- if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) {
- if (error_str.empty()) {
- error_str = TProtoStringType("protoc:0: warning: Failed to parse")
- + TProtoStringType(" prefix to proto package mappings file: ")
- + package_to_prefix_mappings_path_;
- }
- std::cerr << error_str << std::endl;
- std::cerr.flush();
- package_to_prefix_map_.clear();
- }
- }
-
- const TProtoStringType package = file->package();
- // For files without packages, the can be registered as "no_package:PATH",
- // allowing the expected prefixes file.
- static const TProtoStringType no_package_prefix("no_package:");
- const TProtoStringType lookup_key = package.empty() ? no_package_prefix + file->name() : package;
-
- std::map<TProtoStringType, TProtoStringType>::const_iterator prefix_lookup =
- package_to_prefix_map_.find(lookup_key);
-
- if (prefix_lookup != package_to_prefix_map_.end()) {
- return prefix_lookup->second;
- }
-
- return "";
-}
-
-bool PrefixModeStorage::is_package_exempted(const TProtoStringType& package) {
- if (exceptions_.empty() && !exception_path_.empty()) {
- TProtoStringType error_str;
- SimpleLineCollector collector(&exceptions_);
- if (!ParseSimpleFile(exception_path_, &collector, &error_str)) {
- if (error_str.empty()) {
- error_str = TProtoStringType("protoc:0: warning: Failed to parse")
- + TProtoStringType(" package prefix exceptions file: ")
- + exception_path_;
- }
- std::cerr << error_str << std::endl;
- std::cerr.flush();
- exceptions_.clear();
- }
-
- // If the file was empty put something in it so it doesn't get reloaded over
- // and over.
- if (exceptions_.empty()) {
- exceptions_.insert("<not a real package>");
- }
- }
-
- return exceptions_.count(package) != 0;
-}
-
-PrefixModeStorage g_prefix_mode;
-
-} // namespace
-
-TProtoStringType GetPackageToPrefixMappingsPath() {
- return g_prefix_mode.package_to_prefix_mappings_path();
-}
-
-void SetPackageToPrefixMappingsPath(const TProtoStringType& file_path) {
- g_prefix_mode.set_package_to_prefix_mappings_path(file_path);
-}
-
-bool UseProtoPackageAsDefaultPrefix() {
- return g_prefix_mode.use_package_name();
-}
-
-void SetUseProtoPackageAsDefaultPrefix(bool on_or_off) {
- g_prefix_mode.set_use_package_name(on_or_off);
-}
-
-TProtoStringType GetProtoPackagePrefixExceptionList() {
- return g_prefix_mode.exception_path();
-}
-
-void SetProtoPackagePrefixExceptionList(const TProtoStringType& file_path) {
- g_prefix_mode.set_exception_path(file_path);
-}
-
-Options::Options() {
- // While there are generator options, also support env variables to help with
- // build systems where it isn't as easy to hook in for add the generation
- // options when invoking protoc.
- const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
- if (file_path) {
- expected_prefixes_path = file_path;
- }
- const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
- if (suppressions) {
- expected_prefixes_suppressions =
- Split(suppressions, ";", true);
- }
- prefixes_must_be_registered =
- BoolFromEnvVar("GPB_OBJC_PREFIXES_MUST_BE_REGISTERED", false);
- require_prefixes = BoolFromEnvVar("GPB_OBJC_REQUIRE_PREFIXES", false);
-}
-
-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();
- }
-}
-
-void MaybeUnQuote(StringPiece* input) {
- if ((input->length() >= 2) &&
- ((*input->data() == '\'' || *input->data() == '"')) &&
- ((*input)[input->length() - 1] == *input->data())) {
- input->remove_prefix(1);
- input->remove_suffix(1);
- }
-}
-
-} // 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) {
- // Always honor the file option.
- if (file->options().has_objc_class_prefix()) {
- return file->options().objc_class_prefix();
- }
-
- // If package prefix is specified in an prefix to proto mappings file then use that.
- TProtoStringType objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file);
- if (!objc_class_prefix.empty()) {
- return objc_class_prefix;
- }
-
- // If package prefix isn't enabled, done.
- if (!g_prefix_mode.use_package_name()) {
- return "";
- }
-
- // If the package is in the exceptions list, done.
- if (g_prefix_mode.is_package_exempted(file->package())) {
- return "";
- }
-
- // Transform the package into a prefix: use the dot segments as part,
- // camelcase each one and then join them with underscores, and add an
- // underscore at the end.
- TProtoStringType result;
- const std::vector<TProtoStringType> segments = Split(file->package(), ".", true);
- for (const auto& segment : segments) {
- const TProtoStringType part = UnderscoresToCamelCase(segment, true);
- if (part.empty()) {
- continue;
- }
- if (!result.empty()) {
- result.append("_");
- }
- result.append(part);
- }
- if (!result.empty()) {
- result.append("_");
- }
- return g_prefix_mode.forced_package_prefix() + 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.
- arc_ui32 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 {
-
-bool PackageToPrefixesCollector::ConsumeLine(
- const StringPiece& line, TProtoStringType* out_error) {
- int offset = line.find('=');
- if (offset == StringPiece::npos) {
- *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'.";
- return false;
- }
- StringPiece package = line.substr(0, offset);
- StringPiece prefix = line.substr(offset + 1);
- TrimWhitespace(&package);
- TrimWhitespace(&prefix);
- MaybeUnQuote(&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 TProtoStringType& expected_prefixes_path,
- std::map<TProtoStringType, TProtoStringType>* prefix_map,
- TProtoStringType* out_error) {
- if (expected_prefixes_path.empty()) {
- return true;
- }
-
- PackageToPrefixesCollector collector("Expected prefixes", prefix_map);
- return ParseSimpleFile(
- expected_prefixes_path, &collector, out_error);
-}
-
-bool ValidateObjCClassPrefix(
- const FileDescriptor* file, const TProtoStringType& expected_prefixes_path,
- const std::map<TProtoStringType, TProtoStringType>& expected_package_prefixes,
- bool prefixes_must_be_registered, bool require_prefixes,
- TProtoStringType* out_error) {
- // Reminder: An explicit prefix option of "" is valid in case the default
- // prefixing is set to use the proto package and a file needs to be generated
- // without any prefix at all (for legacy reasons).
-
- bool has_prefix = file->options().has_objc_class_prefix();
- bool have_expected_prefix_file = !expected_prefixes_path.empty();
-
- const TProtoStringType prefix = file->options().objc_class_prefix();
- const TProtoStringType package = file->package();
- // For files without packages, the can be registered as "no_package:PATH",
- // allowing the expected prefixes file.
- static const TProtoStringType no_package_prefix("no_package:");
- const TProtoStringType lookup_key =
- package.empty() ? no_package_prefix + file->name() : package;
-
- // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
- // error cases, so it seems to be ok to use as a back door for warnings.
-
- // 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(lookup_key);
- if (package_match != expected_package_prefixes.end()) {
- // There was an entry, and...
- if (has_prefix && 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 + "\";'";
- if (!package.empty()) {
- *out_error += " for package '" + package + "'";
- }
- *out_error += " in '" + file->name() + "'";
- if (has_prefix) {
- *out_error += "; but found '" + prefix + "' instead";
- }
- *out_error += ".";
- return false;
- }
- }
-
- // If there was no prefix option, we're done at this point.
- if (!has_prefix) {
- if (require_prefixes) {
- *out_error =
- "error: '" + file->name() + "' does not have a required 'option" +
- " objc_class_prefix'.";
- return false;
- }
- return true;
- }
-
- // When the prefix is non empty, check it against the expected entries.
- if (!prefix.empty() && have_expected_prefix_file) {
- // For a non empty prefix, look for any other package that uses the 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;
- // Stop on the first real package listing, if it was a no_package file
- // specific entry, keep looking to try and find a package one.
- if (!HasPrefixString(other_package_for_prefix, no_package_prefix)) {
- break;
- }
- }
- }
-
- // 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 ";
- if (HasPrefixString(other_package_for_prefix, no_package_prefix)) {
- *out_error += "file '" +
- StripPrefixString(other_package_for_prefix, no_package_prefix) +
- "'.";
- } else {
- *out_error += "'package " + other_package_for_prefix + ";'.";
- }
- *out_error +=
- " It can only be reused by adding '" + lookup_key + " = " + prefix +
- "' to the expected prefixes file (" + expected_prefixes_path + ").";
- return false; // Only report first usage of the prefix.
- }
- } // !prefix.empty() && have_expected_prefix_file
-
- // Check: Warning - Make sure the prefix is is a reasonable value according
- // to Apple's rules (the checks above implicitly whitelist anything that
- // doesn't meet these rules).
- if (!prefix.empty() && !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.empty() && 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();
- }
-
- // Check: Error/Warning - If the given package/prefix pair wasn't expected,
- // issue a error/warning to added to the file.
- if (have_expected_prefix_file) {
- if (prefixes_must_be_registered) {
- *out_error =
- "error: '" + file->name() + "' has 'option objc_class_prefix = \"" +
- prefix + "\";', but it is not registered. Add '" + lookup_key + " = " +
- (prefix.empty() ? "\"\"" : prefix) +
- "' to the expected prefixes file (" + expected_prefixes_path + ").";
- return false;
- }
-
- std::cerr
- << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
- << prefix << "\";' in '" << file->name() << "'; consider adding '"
- << lookup_key << " = " << (prefix.empty() ? "\"\"" : prefix)
- << "' to the expected prefixes file (" << expected_prefixes_path
- << ")." << std::endl;
- std::cerr.flush();
- }
-
- return true;
-}
-
-} // namespace
-
-bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
- TProtoStringType* out_error) {
- // Options's ctor load from the environment.
- Options options;
- return ValidateObjCClassPrefixes(files, options, out_error);
-}
-
-bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
- const Options& generation_options,
- TProtoStringType* out_error) {
- // Allow a '-' as the path for the expected prefixes to completely disable
- // even the most basic of checks.
- if (generation_options.expected_prefixes_path == "-") {
- return true;
- }
-
- // Load the expected package prefixes, if available, to validate against.
- std::map<TProtoStringType, TProtoStringType> expected_package_prefixes;
- if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path,
- &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,
- generation_options.prefixes_must_be_registered,
- generation_options.require_prefixes,
- out_error);
- if (!is_valid) {
- return false;
- }
- }
- return true;
-}
-
-TextFormatDecodeData::TextFormatDecodeData() { }
-
-TextFormatDecodeData::~TextFormatDecodeData() { }
-
-void TextFormatDecodeData::AddString(arc_i32 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_t kAddUnderscore = 0x80;
-
- static constexpr uint8_t kOpAsIs = 0x00;
- static constexpr uint8_t kOpFirstUpper = 0x40;
- static constexpr uint8_t kOpFirstLower = 0x20;
- static constexpr uint8_t kOpAllUpper = 0x60;
-
- static constexpr int kMaxSegmentLen = 0x1f;
-
- void AddChar(const char desired) {
- ++segment_len_;
- is_all_upper_ &= ascii_isupper(desired);
- }
-
- void Push() {
- uint8_t 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_t 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) {}
-
- // Feeds in some input, parse what it can, returning success/failure. Calling
- // again after an error is undefined.
- bool ParseChunk(StringPiece chunk, TProtoStringType* out_error);
-
- // Should be called to finish parsing (after all input has been provided via
- // successful calls to ParseChunk(), calling after a ParseChunk() failure is
- // undefined). Returns success/failure.
- bool Finish(TProtoStringType* out_error);
-
- int last_line() const { return line_; }
-
- private:
- LineConsumer* line_consumer_;
- int line_;
- TProtoStringType leftover_;
-};
-
-bool Parser::ParseChunk(StringPiece chunk, TProtoStringType* out_error) {
- StringPiece full_chunk;
- if (!leftover_.empty()) {
- leftover_ += TProtoStringType(chunk);
- full_chunk = StringPiece(leftover_);
- } else {
- full_chunk = chunk;
- }
-
- StringPiece line;
- while (ReadLine(&full_chunk, &line)) {
- ++line_;
- RemoveComment(&line);
- TrimWhitespace(&line);
- if (!line.empty() && !line_consumer_->ConsumeLine(line, out_error)) {
- if (out_error->empty()) {
- *out_error = "ConsumeLine failed without setting an error.";
- }
- leftover_.clear();
- return false;
- }
- }
-
- if (full_chunk.empty()) {
- leftover_.clear();
- } else {
- leftover_ = TProtoStringType(full_chunk);
- }
- return true;
-}
-
-bool Parser::Finish(TProtoStringType* out_error) {
- // If there is still something to go, flush it with a newline.
- if (!leftover_.empty() && !ParseChunk("\n", out_error)) {
- return false;
- }
- // This really should never fail if ParseChunk succeeded, but check to be sure.
- if (!leftover_.empty()) {
- *out_error = "ParseSimple Internal error: finished with pending data.";
- return false;
- }
- return true;
-}
-
-TProtoStringType FullErrorString(const TProtoStringType& name, int line_num, const TProtoStringType& msg) {
- return TProtoStringType("error: ") + name + " Line " + StrCat(line_num) + ", " + msg;
-}
-
-} // 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);
-
- return ParseSimpleStream(file_stream, path, line_consumer, out_error);
-}
-
-bool ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
- const TProtoStringType& stream_name,
- LineConsumer* line_consumer,
- TProtoStringType* out_error) {
- TProtoStringType local_error;
- Parser parser(line_consumer);
- const void* buf;
- int buf_len;
- while (input_stream.Next(&buf, &buf_len)) {
- if (buf_len == 0) {
- continue;
- }
-
- if (!parser.ParseChunk(StringPiece(static_cast<const char*>(buf), buf_len),
- &local_error)) {
- *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
- return false;
- }
- }
- if (!parser.Finish(&local_error)) {
- *out_error = FullErrorString(stream_name, parser.last_line(), local_error);
- return false;
- }
- return true;
-}
-
-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 afbf34b7ad..038fde5926 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,353 +1,2 @@
-// 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/io/zero_copy_stream.h>
-
-#include <google/protobuf/port_def.inc>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace objectivec {
-
-// Get/Set the path to a file to load for objc class prefix lookups.
-TProtoStringType PROTOC_EXPORT GetPackageToPrefixMappingsPath();
-void PROTOC_EXPORT SetPackageToPrefixMappingsPath(
- const TProtoStringType& file_path);
-// Get/Set if the proto package should be used to make the default prefix for
-// symbols. This will then impact most of the type naming apis below. It is done
-// as a global to not break any other generator reusing the methods since they
-// are exported.
-bool PROTOC_EXPORT UseProtoPackageAsDefaultPrefix();
-void PROTOC_EXPORT SetUseProtoPackageAsDefaultPrefix(bool on_or_off);
-// Get/Set the path to a file to load as exceptions when
-// `UseProtoPackageAsDefaultPrefix()` is `true`. An empty string means there
-// should be no exceptions.
-TProtoStringType PROTOC_EXPORT GetProtoPackagePrefixExceptionList();
-void PROTOC_EXPORT SetProtoPackagePrefixExceptionList(
- const TProtoStringType& file_path);
-
-// Generator Prefix Validation Options (see objectivec_generator.cc for a
-// description of each):
-struct Options {
- Options();
- TProtoStringType expected_prefixes_path;
- std::vector<TProtoStringType> expected_prefixes_suppressions;
- bool prefixes_must_be_registered;
- bool require_prefixes;
-};
-
-// 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 or the prefix made from the proto package.
-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& validation_options, TProtoStringType* out_error);
-// Same was the other ValidateObjCClassPrefixes() calls, but the options all
-// come from the environment variables.
-bool PROTOC_EXPORT ValidateObjCClassPrefixes(
- const std::vector<const FileDescriptor*>& files, TProtoStringType* out_error);
-
-// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
-// the input into the expected output.
-class PROTOC_EXPORT TextFormatDecodeData {
- public:
- TextFormatDecodeData();
- ~TextFormatDecodeData();
-
- TextFormatDecodeData(const TextFormatDecodeData&) = delete;
- TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
-
- void AddString(arc_i32 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<arc_i32, 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);
-
-bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
- const TProtoStringType& stream_name,
- 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) override;
-
- 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__
+#include "helpers.h"
+#include "names.h" \ No newline at end of file
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
deleted file mode 100644
index bf73592e56..0000000000
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ /dev/null
@@ -1,633 +0,0 @@
-// 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/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)
- : root_classname_(root_classname),
- descriptor_(descriptor),
- field_generators_(descriptor),
- 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));
- 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,
- bool include_external_types) {
- if (!IsMapEntryMessage(descriptor_)) {
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
- field_generators_.get(fieldDescriptor)
- .DetermineForwardDeclarations(fwd_decls, include_external_types);
- }
- }
-
- for (const auto& generator : nested_message_generators_) {
- generator->DetermineForwardDeclarations(fwd_decls, include_external_types);
- }
-}
-
-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"
- " arc_ui32 _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"] =
- "(arc_ui32)(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:(arc_ui32)(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:(arc_ui32)(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_nsobject_methods.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
deleted file mode 100644
index 163304665c..0000000000
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
+++ /dev/null
@@ -1,197 +0,0 @@
-// 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/oneof.cc
index 5197ff63a3..aa534d32f7 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/oneof.cc
@@ -28,13 +28,14 @@
// (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 "google/protobuf/compiler/objectivec/oneof.h"
+
#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>
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/compiler/objectivec/names.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -46,7 +47,7 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
variables_["enum_name"] = OneofEnumName(descriptor_);
variables_["name"] = OneofName(descriptor_);
variables_["capitalized_name"] = OneofNameCapitalized(descriptor_);
- variables_["raw_index"] = StrCat(descriptor_->index());
+ variables_["raw_index"] = y_absl::StrCat(descriptor_->index());
const Descriptor* msg_descriptor = descriptor_->containing_type();
variables_["owning_message_class"] = ClassName(msg_descriptor);
@@ -60,63 +61,63 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
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);
+ variables_["index"] = y_absl::StrCat(-index);
}
-void OneofGenerator::GenerateCaseEnum(io::Printer* printer) {
- printer->Print(
- variables_,
- "typedef GPB_ENUM($enum_name$) {\n");
+void OneofGenerator::GenerateCaseEnum(io::Printer* printer) const {
+ 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"];
+ printer->Print(variables_, "$enum_name$_GPBUnsetOneOfCase = 0,\n");
+ TProtoStringType enum_name = variables_.find("enum_name")->second;
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->Print("$enum_name$_$field_name$ = $field_number$,\n", "enum_name",
+ enum_name, "field_name", field_name, "field_number",
+ y_absl::StrCat(field->number()));
}
printer->Outdent();
+ // clang-format off
printer->Print(
"};\n"
"\n");
+ // clang-format on
}
void OneofGenerator::GeneratePublicCasePropertyDeclaration(
- io::Printer* printer) {
+ io::Printer* printer) const {
+ // clang-format off
printer->Print(
variables_,
"$comments$"
"@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n"
"\n");
+ // clang-format on
}
-void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
+void OneofGenerator::GenerateClearFunctionDeclaration(
+ io::Printer* printer) const {
+ // clang-format off
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");
+ // clang-format on
}
-void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) {
- printer->Print(
- variables_,
- "@dynamic $name$OneOfCase;\n");
+void OneofGenerator::GeneratePropertyImplementation(
+ io::Printer* printer) const {
+ printer->Print(variables_, "@dynamic $name$OneOfCase;\n");
}
-void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
+void OneofGenerator::GenerateClearFunctionImplementation(
+ io::Printer* printer) const {
+ // clang-format off
printer->Print(
variables_,
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
@@ -124,13 +125,14 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
" GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
" GPBClearOneof(message, oneof);\n"
"}\n");
+ // clang-format on
}
-TProtoStringType OneofGenerator::DescriptorName(void) const {
+TProtoStringType OneofGenerator::DescriptorName() const {
return variables_.find("name")->second;
}
-TProtoStringType OneofGenerator::HasIndexAsString(void) const {
+TProtoStringType OneofGenerator::HasIndexAsString() const {
return variables_.find("index")->second;
}
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/oneof.h
index 4173a0325c..411f832f21 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_oneof.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/oneof.h
@@ -32,10 +32,11 @@
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
#include <string>
-#include <set>
#include <vector>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/io/printer.h>
+
+#include "y_absl/container/flat_hash_map.h"
+#include "google/protobuf/descriptor.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
@@ -45,27 +46,27 @@ namespace objectivec {
class OneofGenerator {
public:
explicit OneofGenerator(const OneofDescriptor* descriptor);
- ~OneofGenerator();
+ ~OneofGenerator() = default;
OneofGenerator(const OneofGenerator&) = delete;
OneofGenerator& operator=(const OneofGenerator&) = delete;
void SetOneofIndexBase(int index_base);
- void GenerateCaseEnum(io::Printer* printer);
+ void GenerateCaseEnum(io::Printer* printer) const;
- void GeneratePublicCasePropertyDeclaration(io::Printer* printer);
- void GenerateClearFunctionDeclaration(io::Printer* printer);
+ void GeneratePublicCasePropertyDeclaration(io::Printer* printer) const;
+ void GenerateClearFunctionDeclaration(io::Printer* printer) const;
- void GeneratePropertyImplementation(io::Printer* printer);
- void GenerateClearFunctionImplementation(io::Printer* printer);
+ void GeneratePropertyImplementation(io::Printer* printer) const;
+ void GenerateClearFunctionImplementation(io::Printer* printer) const;
- TProtoStringType DescriptorName(void) const;
- TProtoStringType HasIndexAsString(void) const;
+ TProtoStringType DescriptorName() const;
+ TProtoStringType HasIndexAsString() const;
private:
const OneofDescriptor* descriptor_;
- std::map<TProtoStringType, TProtoStringType> variables_;
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType> variables_;
};
} // namespace objectivec
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/options.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/options.h
new file mode 100644
index 0000000000..d0f7ee0c76
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/options.h
@@ -0,0 +1,57 @@
+// 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_OPTIONS_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_OPTIONS_H__
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// Generation options, documented within generator.cc.
+struct GenerationOptions {
+ TProtoStringType generate_for_named_framework;
+ TProtoStringType named_framework_to_proto_path_mappings_path;
+ TProtoStringType runtime_import_prefix;
+ // TODO(thomasvl): Eventually flip this default to false for better interop
+ // with Swift if proto usages span modules made from ObjC sources.
+ bool headers_use_forward_declarations = true;
+ bool experimental_multi_source_generation = false;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_OPTIONS_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/primitive_field.cc
index f83e2691ae..aa839ecf2b 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/primitive_field.cc
@@ -28,22 +28,21 @@
// (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 "google/protobuf/compiler/objectivec/primitive_field.h"
+
#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 "y_absl/container/flat_hash_map.h"
+#include "y_absl/log/absl_log.h"
+#include "y_absl/strings/str_cat.h"
+#include "google/protobuf/compiler/objectivec/helpers.h"
+#include "google/protobuf/io/printer.h"
namespace google {
namespace protobuf {
namespace compiler {
namespace objectivec {
-using internal::WireFormat;
-using internal::WireFormatLite;
-
namespace {
const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
@@ -70,13 +69,13 @@ const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
case OBJECTIVECTYPE_ENUM:
return "arc_i32";
case OBJECTIVECTYPE_MESSAGE:
- return NULL; // Messages go through objectivec_message_field.cc|h.
+ return nullptr; // Messages go through 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;
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return nullptr;
}
const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
@@ -103,18 +102,19 @@ const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
case OBJECTIVECTYPE_ENUM:
return "Enum";
case OBJECTIVECTYPE_MESSAGE:
- // Want NSArray (but goes through objectivec_message_field.cc|h).
+ // Want NSArray (but goes through 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;
+ Y_ABSL_LOG(FATAL) << "Can't get here.";
+ return nullptr;
}
-void SetPrimitiveVariables(const FieldDescriptor* descriptor,
- std::map<TProtoStringType, TProtoStringType>* variables) {
+void SetPrimitiveVariables(
+ const FieldDescriptor* descriptor,
+ y_absl::flat_hash_map<y_absl::string_view, TProtoStringType>* variables) {
TProtoStringType primitive_name = PrimitiveTypeName(descriptor);
(*variables)["type"] = primitive_name;
(*variables)["storage_type"] = primitive_name;
@@ -128,8 +128,6 @@ PrimitiveFieldGenerator::PrimitiveFieldGenerator(
SetPrimitiveVariables(descriptor, &variables_);
}
-PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
-
void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
io::Printer* printer) const {
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
@@ -139,7 +137,7 @@ void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
}
}
-int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded() const {
if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
// Reserve a bit for the storage of the boolean.
return 1;
@@ -147,10 +145,10 @@ int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
return 0;
}
-void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
+void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int index_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_value"] = y_absl::StrCat(index_base);
variables_["storage_offset_comment"] =
" // Stored in _has_storage_ to save space.";
}
@@ -163,8 +161,6 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
variables_["property_storage_attribute"] = "copy";
}
-PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
-
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
const FieldDescriptor* descriptor)
: RepeatedFieldGenerator(descriptor) {
@@ -172,16 +168,15 @@ RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
TProtoStringType base_name = PrimitiveArrayTypeName(descriptor);
if (base_name.length()) {
- variables_["array_storage_type"] = "GPB" + base_name + "Array";
+ variables_["array_storage_type"] = y_absl::StrCat("GPB", base_name, "Array");
} else {
+ TProtoStringType storage_type = variables_["storage_type"];
variables_["array_storage_type"] = "NSMutableArray";
variables_["array_property_type"] =
- "NSMutableArray<" + variables_["storage_type"] + "*>";
+ y_absl::StrCat("NSMutableArray<", storage_type, "*>");
}
}
-RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
-
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/primitive_field.h
index 06a1528a82..e6916055cd 100644
--- a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/primitive_field.h
@@ -31,7 +31,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
-#include <google/protobuf/compiler/objectivec/objectivec_field.h>
+#include "google/protobuf/compiler/objectivec/field.h"
namespace google {
namespace protobuf {
@@ -43,15 +43,15 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator {
protected:
explicit PrimitiveFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~PrimitiveFieldGenerator();
+ ~PrimitiveFieldGenerator() override = default;
PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
- virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
- virtual int ExtraRuntimeHasBitsNeeded(void) const override;
- virtual void SetExtraRuntimeHasBitsBase(int index_base) override;
+ int ExtraRuntimeHasBitsNeeded() const override;
+ void SetExtraRuntimeHasBitsBase(int index_base) override;
};
class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
@@ -59,7 +59,7 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
protected:
explicit PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~PrimitiveObjFieldGenerator();
+ ~PrimitiveObjFieldGenerator() override = default;
PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete;
PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) =
@@ -71,7 +71,7 @@ class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
protected:
explicit RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor);
- virtual ~RepeatedPrimitiveFieldGenerator();
+ ~RepeatedPrimitiveFieldGenerator() override = default;
RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) =
delete;
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.cc b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.cc
new file mode 100644
index 0000000000..f254c6093f
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.cc
@@ -0,0 +1,254 @@
+// 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/text_format_decode_data.h"
+
+#include <iostream>
+#include <ostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "y_absl/strings/ascii.h"
+#include "y_absl/strings/escaping.h"
+#include "y_absl/strings/match.h"
+#include "google/protobuf/io/coded_stream.h"
+#include "google/protobuf/io/zero_copy_stream_impl.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 {
+
+namespace {
+
+// Helper to build up the decode data for a string.
+class DecodeDataBuilder {
+ public:
+ DecodeDataBuilder() { Reset(); }
+
+ bool AddCharacter(char desired, char input);
+ void AddUnderscore() {
+ Push();
+ need_underscore_ = true;
+ }
+ TProtoStringType Finish() {
+ Push();
+ return decode_data_;
+ }
+
+ private:
+ static constexpr uint8_t kAddUnderscore = 0x80;
+
+ static constexpr uint8_t kOpAsIs = 0x00;
+ static constexpr uint8_t kOpFirstUpper = 0x40;
+ static constexpr uint8_t kOpFirstLower = 0x20;
+ static constexpr uint8_t kOpAllUpper = 0x60;
+
+ static constexpr int kMaxSegmentLen = 0x1f;
+
+ void AddChar(const char desired) {
+ ++segment_len_;
+ is_all_upper_ &= y_absl::ascii_isupper(desired);
+ }
+
+ void Push() {
+ uint8_t 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 == y_absl::ascii_toupper(input)) {
+ op_ = kOpFirstUpper;
+ } else if (desired == y_absl::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_t op_;
+ int segment_len_;
+
+ TProtoStringType decode_data_;
+};
+
+bool DecodeDataBuilder::AddCharacter(char desired, 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) || y_absl::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 == y_absl::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
+
+void TextFormatDecodeData::AddString(arc_i32 key,
+ const TProtoStringType& input_for_decode,
+ const TProtoStringType& desired_output) {
+ for (std::vector<DataEntry>::const_iterator i = entries_.begin();
+ i != entries_.end(); ++i) {
+ Y_ABSL_CHECK(i->first != key)
+ << "error: duplicate key (" << key
+ << ") making TextFormat data, input: \"" << input_for_decode
+ << "\", desired: \"" << desired_output << "\".";
+ }
+
+ 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 data_stringstream.str();
+}
+
+// static
+TProtoStringType TextFormatDecodeData::DecodeDataForString(
+ const TProtoStringType& input_for_decode, const TProtoStringType& desired_output) {
+ Y_ABSL_CHECK(!input_for_decode.empty() && !desired_output.empty())
+ << "error: got empty string for making TextFormat data, input: \""
+ << input_for_decode << "\", desired: \"" << desired_output << "\".";
+ Y_ABSL_CHECK(!y_absl::StrContains(input_for_decode, '\0') &&
+ !y_absl::StrContains(desired_output, '\0'))
+ << "error: got a null char in a string for making TextFormat data,"
+ << " input: \"" << y_absl::CEscape(input_for_decode) << "\", desired: \""
+ << y_absl::CEscape(desired_output) << "\".";
+
+ 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 objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.h b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.h
new file mode 100644
index 0000000000..135e4045b4
--- /dev/null
+++ b/contrib/libs/protoc/src/google/protobuf/compiler/objectivec/text_format_decode_data.h
@@ -0,0 +1,83 @@
+// 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_TEXT_FORMAT_DECODE_DATA_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_TEXT_FORMAT_DECODE_DATA_H__
+
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "util/generic/string.h"
+
+// Must be included last
+#include "google/protobuf/port_def.inc"
+
+using TProtoStringType = TString;
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// TODO(b/250947994): PROTOC_EXPORT is only used to allow the CMake build to
+// find/link these in the unittest, this is not public api.
+
+// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
+// the input into the expected output.
+class PROTOC_EXPORT TextFormatDecodeData {
+ public:
+ TextFormatDecodeData() = default;
+ ~TextFormatDecodeData() = default;
+
+ TextFormatDecodeData(const TextFormatDecodeData&) = delete;
+ TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
+
+ void AddString(arc_i32 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<arc_i32, TProtoStringType> DataEntry;
+ std::vector<DataEntry> entries_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include "google/protobuf/port_undef.inc"
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_TEXT_FORMAT_DECODE_DATA_H__