aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest/include/protobuf/compiler/objectivec
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDedicatedTest/include/protobuf/compiler/objectivec')
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc260
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc149
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc156
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc475
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h194
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc610
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h82
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc276
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc1960
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h347
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc385
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc189
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc636
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h99
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc107
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h87
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h197
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc140
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h76
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc190
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h95
26 files changed, 7078 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc
new file mode 100644
index 00000000..5510750a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -0,0 +1,260 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <algorithm> // std::find()
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor)
+ : descriptor_(descriptor),
+ name_(EnumName(descriptor_)) {
+ // Track the names for the enum values, and if an alias overlaps a base
+ // value, skip making a name for it. Likewise if two alias overlap, the
+ // first one wins.
+ // The one gap in this logic is if two base values overlap, but for that
+ // to happen you have to have "Foo" and "FOO" or "FOO_BAR" and "FooBar",
+ // and if an enum has that, it is already going to be confusing and a
+ // compile error is just fine.
+ // The values are still tracked to support the reflection apis and
+ // TextFormat handing since they are different there.
+ std::set<std::string> value_names;
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ base_values_.push_back(value);
+ value_names.insert(EnumValueName(value));
+ } else {
+ std::string value_name(EnumValueName(value));
+ if (value_names.find(value_name) != value_names.end()) {
+ alias_values_to_skip_.insert(value);
+ } else {
+ value_names.insert(value_name);
+ }
+ }
+ all_values_.push_back(value);
+ }
+}
+
+EnumGenerator::~EnumGenerator() {}
+
+void EnumGenerator::GenerateHeader(io::Printer* printer) {
+ std::string enum_comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ enum_comments = BuildCommentsString(location, true);
+ } else {
+ enum_comments = "";
+ }
+
+ printer->Print(
+ "#pragma mark - Enum $name$\n"
+ "\n",
+ "name", name_);
+
+ // Swift 5 included SE0192 "Handling Future Enum Cases"
+ // https://github.com/apple/swift-evolution/blob/master/proposals/0192-non-exhaustive-enums.md
+ // Since a .proto file can get new values added to an enum at any time, they
+ // are effectively "non-frozen". Even in a proto3 syntax file where there is
+ // support for the unknown value, an edit to the file can always add a new
+ // value moving something from unknown to known. Since Swift is now ABI
+ // stable, it also means a binary could contain Swift compiled against one
+ // version of the .pbobjc.h file, but finally linked against an enum with
+ // more cases. So the Swift code will always have to treat ObjC Proto Enums
+ // as "non-frozen". The default behavior in SE0192 is for all objc enums to
+ // be "non-frozen" unless marked as otherwise, so this means this generation
+ // doesn't have to bother with the `enum_extensibility` attribute, as the
+ // default will be what is needed.
+
+ printer->Print("$comments$typedef$deprecated_attribute$ GPB_ENUM($name$) {\n",
+ "comments", enum_comments,
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file()),
+ "name", name_);
+ printer->Indent();
+
+ if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+ // Include the unknown value.
+ printer->Print(
+ "/**\n"
+ " * Value used if any message's field encounters a value that is not defined\n"
+ " * by this enum. The message will also have C functions to get/set the rawValue\n"
+ " * of the field.\n"
+ " **/\n"
+ "$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
+ "name", name_);
+ }
+ for (int i = 0; i < all_values_.size(); i++) {
+ if (alias_values_to_skip_.find(all_values_[i]) != alias_values_to_skip_.end()) {
+ continue;
+ }
+ if (all_values_[i]->GetSourceLocation(&location)) {
+ std::string comments = BuildCommentsString(location, true).c_str();
+ if (comments.length() > 0) {
+ if (i > 0) {
+ printer->Print("\n");
+ }
+ printer->Print(comments.c_str());
+ }
+ }
+
+ printer->Print(
+ "$name$$deprecated_attribute$ = $value$,\n",
+ "name", EnumValueName(all_values_[i]),
+ "deprecated_attribute", GetOptionalDeprecatedAttribute(all_values_[i]),
+ "value", StrCat(all_values_[i]->number()));
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n"
+ "GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
+ "\n"
+ "/**\n"
+ " * Checks to see if the given value is defined by the enum or was not known at\n"
+ " * the time this source was generated.\n"
+ " **/\n"
+ "BOOL $name$_IsValidValue(int32_t value);\n"
+ "\n",
+ "name", name_);
+}
+
+void EnumGenerator::GenerateSource(io::Printer* printer) {
+ printer->Print(
+ "#pragma mark - Enum $name$\n"
+ "\n",
+ "name", name_);
+
+ // Note: For the TextFormat decode info, we can't use the enum value as
+ // the key because protocol buffer enums have 'allow_alias', which lets
+ // a value be used more than once. Instead, the index into the list of
+ // enum value descriptions is used. Note: start with -1 so the first one
+ // will be zero.
+ TextFormatDecodeData text_format_decode_data;
+ int enum_value_description_key = -1;
+ std::string text_blob;
+
+ for (int i = 0; i < all_values_.size(); i++) {
+ ++enum_value_description_key;
+ std::string short_name(EnumValueShortName(all_values_[i]));
+ text_blob += short_name + '\0';
+ if (UnCamelCaseEnumShortName(short_name) != all_values_[i]->name()) {
+ text_format_decode_data.AddString(enum_value_description_key, short_name,
+ all_values_[i]->name());
+ }
+ }
+
+ printer->Print(
+ "GPBEnumDescriptor *$name$_EnumDescriptor(void) {\n"
+ " static _Atomic(GPBEnumDescriptor*) descriptor = nil;\n"
+ " if (!descriptor) {\n",
+ "name", name_);
+
+ static const int kBytesPerLine = 40; // allow for escaping
+ printer->Print(
+ " static const char *valueNames =");
+ for (int i = 0; i < text_blob.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(CEscape(text_blob.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ";\n"
+ " static const int32_t values[] = {\n");
+ for (int i = 0; i < all_values_.size(); i++) {
+ printer->Print(" $name$,\n", "name", EnumValueName(all_values_[i]));
+ }
+ printer->Print(" };\n");
+
+ if (text_format_decode_data.num_entries() == 0) {
+ printer->Print(
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue];\n",
+ "name", name_);
+ } else {
+ printer->Print(
+ " static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
+ " GPBEnumDescriptor *worker =\n"
+ " [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol($name$)\n"
+ " valueNames:valueNames\n"
+ " values:values\n"
+ " count:(uint32_t)(sizeof(values) / sizeof(int32_t))\n"
+ " enumVerifier:$name$_IsValidValue\n"
+ " extraTextFormatInfo:extraTextFormatInfo];\n",
+ "name", name_,
+ "extraTextFormatInfo", CEscape(text_format_decode_data.Data()));
+ }
+ printer->Print(
+ " GPBEnumDescriptor *expected = nil;\n"
+ " if (!atomic_compare_exchange_strong(&descriptor, &expected, worker)) {\n"
+ " [worker release];\n"
+ " }\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n");
+
+ printer->Print(
+ "BOOL $name$_IsValidValue(int32_t value__) {\n"
+ " switch (value__) {\n",
+ "name", name_);
+
+ for (int i = 0; i < base_values_.size(); i++) {
+ printer->Print(
+ " case $name$:\n",
+ "name", EnumValueName(base_values_[i]));
+ }
+
+ printer->Print(
+ " return YES;\n"
+ " default:\n"
+ " return NO;\n"
+ " }\n"
+ "}\n\n");
+}
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h
new file mode 100644
index 00000000..51560dd1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum.h
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumGenerator {
+ public:
+ explicit EnumGenerator(const EnumDescriptor* descriptor);
+ ~EnumGenerator();
+
+ EnumGenerator(const EnumGenerator&) = delete;
+ EnumGenerator& operator=(const EnumGenerator&) = delete;
+
+ void GenerateHeader(io::Printer* printer);
+ void GenerateSource(io::Printer* printer);
+
+ const std::string& name() const { return name_; }
+
+ private:
+ const EnumDescriptor* descriptor_;
+ std::vector<const EnumValueDescriptor*> base_values_;
+ std::vector<const EnumValueDescriptor*> all_values_;
+ std::set<const EnumValueDescriptor*> alias_values_to_skip_;
+ const std::string name_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc
new file mode 100644
index 00000000..66877afb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -0,0 +1,149 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_enum_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetEnumVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string type = EnumName(descriptor->enum_type());
+ (*variables)["storage_type"] = type;
+ // For non repeated fields, if it was defined in a different file, the
+ // property decls need to use "enum NAME" rather than just "NAME" to support
+ // the forward declaration of the enums.
+ if (!descriptor->is_repeated() &&
+ (descriptor->file() != descriptor->enum_type()->file())) {
+ (*variables)["property_type"] = "enum " + type;
+ }
+ (*variables)["enum_verifier"] = type + "_IsValidValue";
+ (*variables)["enum_desc_func"] = type + "_EnumDescriptor";
+
+ (*variables)["dataTypeSpecific_name"] = "enumDescFunc";
+ (*variables)["dataTypeSpecific_value"] = (*variables)["enum_desc_func"];
+
+ const Descriptor* msg_descriptor = descriptor->containing_type();
+ (*variables)["owning_message_class"] = ClassName(msg_descriptor);
+}
+} // namespace
+
+EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_);
+}
+
+EnumFieldGenerator::~EnumFieldGenerator() {}
+
+void EnumFieldGenerator::GenerateCFunctionDeclarations(
+ io::Printer* printer) const {
+ if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) {
+ return;
+ }
+
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
+ " * if the value was not defined by the enum at the time the code was generated.\n"
+ " **/\n"
+ "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
+ "/**\n"
+ " * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
+ " * it to be set to a value that was not defined by the enum at the time the code\n"
+ " * was generated.\n"
+ " **/\n"
+ "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
+ "\n");
+}
+
+void EnumFieldGenerator::GenerateCFunctionImplementations(
+ io::Printer* printer) const {
+ if (!HasPreservingUnknownEnumSemantics(descriptor_->file())) return;
+
+ printer->Print(
+ variables_,
+ "int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
+ " return GPBGetMessageRawEnumField(message, field);\n"
+ "}\n"
+ "\n"
+ "void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBFieldDescriptor *field = [descriptor fieldWithNumber:$field_number_name$];\n"
+ " GPBSetMessageRawEnumField(message, field, value);\n"
+ "}\n"
+ "\n");
+}
+
+void EnumFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ SingleFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // If it is an enum defined in a different file, then we'll need a forward
+ // declaration for it. When it is in our file, all the enums are output
+ // before the message, so it will be declared before it is needed.
+ if (descriptor_->file() != descriptor_->enum_type()->file()) {
+ // Enum name is already in "storage_type".
+ const std::string& name = variable("storage_type");
+ fwd_decls->insert("GPB_ENUM_FWD_DECLARE(" + name + ")");
+ }
+}
+
+RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetEnumVariables(descriptor, &variables_);
+ variables_["array_storage_type"] = "GPBEnumArray";
+}
+
+RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
+
+void RepeatedEnumFieldGenerator::FinishInitialization(void) {
+ RepeatedFieldGenerator::FinishInitialization();
+ variables_["array_comment"] =
+ "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h
new file mode 100644
index 00000000..1f11abcb
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_enum_field.h
@@ -0,0 +1,80 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumFieldGenerator : public SingleFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ EnumFieldGenerator(const EnumFieldGenerator&) = delete;
+ EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete;
+
+ public:
+ virtual void GenerateCFunctionDeclarations(
+ io::Printer* printer) const override;
+ virtual void GenerateCFunctionImplementations(
+ io::Printer* printer) const override;
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+
+ protected:
+ EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+ virtual ~EnumFieldGenerator();
+};
+
+class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ public:
+ virtual void FinishInitialization() override;
+
+ protected:
+ RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedEnumFieldGenerator();
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ENUM_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc
new file mode 100644
index 00000000..7ec80bc9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -0,0 +1,156 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <iostream>
+
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.pb.h>
+#include <stubs/strutil.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+ExtensionGenerator::ExtensionGenerator(const std::string& root_class_name,
+ const FieldDescriptor* descriptor)
+ : method_name_(ExtensionMethodName(descriptor)),
+ root_class_and_method_name_(root_class_name + "_" + method_name_),
+ descriptor_(descriptor) {
+ if (descriptor->is_map()) {
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for errors.
+ std::cerr << "error: Extension is a map<>!"
+ << " That used to be blocked by the compiler." << std::endl;
+ std::cerr.flush();
+ abort();
+ }
+}
+
+ExtensionGenerator::~ExtensionGenerator() {}
+
+void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["method_name"] = method_name_;
+ if (IsRetainedName(method_name_)) {
+ vars["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
+ } else {
+ vars["storage_attribute"] = "";
+ }
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ vars["comments"] = BuildCommentsString(location, true);
+ } else {
+ vars["comments"] = "";
+ }
+ // Unlike normal message fields, check if the file for the extension was
+ // deprecated.
+ vars["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor_, descriptor_->file());
+ printer->Print(vars,
+ "$comments$"
+ "+ (GPBExtensionDescriptor *)$method_name$$storage_attribute$$deprecated_attribute$;\n");
+}
+
+void ExtensionGenerator::GenerateStaticVariablesInitialization(
+ io::Printer* printer) {
+ std::map<std::string, std::string> vars;
+ vars["root_class_and_method_name"] = root_class_and_method_name_;
+ const std::string containing_type = ClassName(descriptor_->containing_type());
+ vars["extended_type"] = ObjCClass(containing_type);
+ vars["number"] = StrCat(descriptor_->number());
+
+ std::vector<std::string> options;
+ if (descriptor_->is_repeated()) options.push_back("GPBExtensionRepeated");
+ if (descriptor_->is_packed()) options.push_back("GPBExtensionPacked");
+ if (descriptor_->containing_type()->options().message_set_wire_format()) {
+ options.push_back("GPBExtensionSetWireFormat");
+ }
+ vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options);
+
+ ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
+ if (objc_type == OBJECTIVECTYPE_MESSAGE) {
+ std::string message_type = ClassName(descriptor_->message_type());
+ vars["type"] = ObjCClass(message_type);
+ } else {
+ vars["type"] = "Nil";
+ }
+
+ vars["default_name"] = GPBGenericValueFieldName(descriptor_);
+ if (descriptor_->is_repeated()) {
+ vars["default"] = "nil";
+ } else {
+ vars["default"] = DefaultValue(descriptor_);
+ }
+ std::string type = GetCapitalizedType(descriptor_);
+ vars["extension_type"] = std::string("GPBDataType") + type;
+
+ if (objc_type == OBJECTIVECTYPE_ENUM) {
+ vars["enum_desc_func_name"] =
+ EnumName(descriptor_->enum_type()) + "_EnumDescriptor";
+ } else {
+ vars["enum_desc_func_name"] = "NULL";
+ }
+
+ printer->Print(vars,
+ "{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
+ " .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
+ " .extendedClass.clazz = $extended_type$,\n"
+ " .messageOrGroupClass.clazz = $type$,\n"
+ " .enumDescriptorFunc = $enum_desc_func_name$,\n"
+ " .fieldNumber = $number$,\n"
+ " .dataType = $extension_type$,\n"
+ " .options = $options$,\n"
+ "},\n");
+}
+
+void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) {
+ std::string extended_type = ClassName(descriptor_->containing_type());
+ fwd_decls->insert(ObjCClassDeclaration(extended_type));
+ ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
+ if (objc_type == OBJECTIVECTYPE_MESSAGE) {
+ std::string message_type = ClassName(descriptor_->message_type());
+ fwd_decls->insert(ObjCClassDeclaration(message_type));
+ }
+}
+
+void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
+ printer->Print(
+ "[registry addExtension:$root_class_and_method_name$];\n",
+ "root_class_and_method_name", root_class_and_method_name_);
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h
new file mode 100644
index 00000000..b985d831
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_extension.h
@@ -0,0 +1,67 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_EXTENSION_H__
+
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class ExtensionGenerator {
+ public:
+ ExtensionGenerator(const std::string& root_class_name,
+ const FieldDescriptor* descriptor);
+ ~ExtensionGenerator();
+
+ ExtensionGenerator(const ExtensionGenerator&) = delete;
+ ExtensionGenerator& operator=(const ExtensionGenerator&) = delete;
+
+ void GenerateMembersHeader(io::Printer* printer);
+ void GenerateStaticVariablesInitialization(io::Printer* printer);
+ void GenerateRegistrationSource(io::Printer* printer);
+ void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
+
+ private:
+ std::string method_name_;
+ std::string root_class_and_method_name_;
+ const FieldDescriptor* descriptor_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc
new file mode 100644
index 00000000..29f434b5
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.cc
@@ -0,0 +1,475 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <iostream>
+
+#include <compiler/objectivec/objectivec_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_enum_field.h>
+#include <compiler/objectivec/objectivec_map_field.h>
+#include <compiler/objectivec/objectivec_message_field.h>
+#include <compiler/objectivec/objectivec_primitive_field.h>
+#include <io/printer.h>
+#include <wire_format.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetCommonFieldVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string camel_case_name = FieldName(descriptor);
+ std::string raw_field_name;
+ if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
+ raw_field_name = descriptor->message_type()->name();
+ } else {
+ raw_field_name = descriptor->name();
+ }
+ // The logic here has to match -[GGPBFieldDescriptor textFormatName].
+ const std::string un_camel_case_name(
+ UnCamelCaseFieldName(camel_case_name, descriptor));
+ const bool needs_custom_name = (raw_field_name != un_camel_case_name);
+
+ SourceLocation location;
+ if (descriptor->GetSourceLocation(&location)) {
+ (*variables)["comments"] = BuildCommentsString(location, true);
+ } else {
+ (*variables)["comments"] = "\n";
+ }
+ const std::string& classname = ClassName(descriptor->containing_type());
+ (*variables)["classname"] = classname;
+ (*variables)["name"] = camel_case_name;
+ const std::string& capitalized_name = FieldNameCapitalized(descriptor);
+ (*variables)["capitalized_name"] = capitalized_name;
+ (*variables)["raw_field_name"] = raw_field_name;
+ (*variables)["field_number_name"] =
+ classname + "_FieldNumber_" + capitalized_name;
+ (*variables)["field_number"] = StrCat(descriptor->number());
+ (*variables)["field_type"] = GetCapitalizedType(descriptor);
+ (*variables)["deprecated_attribute"] = GetOptionalDeprecatedAttribute(descriptor);
+ std::vector<std::string> field_flags;
+ if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
+ if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
+ if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
+ if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
+
+ // ObjC custom flags.
+ if (descriptor->has_default_value())
+ field_flags.push_back("GPBFieldHasDefaultValue");
+ if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
+ if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
+ field_flags.push_back("GPBFieldHasEnumDescriptor");
+ }
+ // It will clear on a zero value if...
+ // - not repeated/map
+ // - doesn't have presence
+ bool clear_on_zero =
+ (!descriptor->is_repeated() && !descriptor->has_presence());
+ if (clear_on_zero) {
+ field_flags.push_back("GPBFieldClearHasIvarOnZero");
+ }
+
+ (*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
+
+ (*variables)["default"] = DefaultValue(descriptor);
+ (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
+
+ (*variables)["dataTypeSpecific_name"] = "clazz";
+ (*variables)["dataTypeSpecific_value"] = "Nil";
+
+ (*variables)["storage_offset_value"] =
+ "(uint32_t)offsetof(" + classname + "__storage_, " + camel_case_name + ")";
+ (*variables)["storage_offset_comment"] = "";
+
+ // Clear some common things so they can be set just when needed.
+ (*variables)["storage_attribute"] = "";
+}
+
+} // namespace
+
+FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options) {
+ FieldGenerator* result = NULL;
+ if (field->is_repeated()) {
+ switch (GetObjectiveCType(field)) {
+ case OBJECTIVECTYPE_MESSAGE: {
+ if (field->is_map()) {
+ result = new MapFieldGenerator(field, options);
+ } else {
+ result = new RepeatedMessageFieldGenerator(field, options);
+ }
+ break;
+ }
+ case OBJECTIVECTYPE_ENUM:
+ result = new RepeatedEnumFieldGenerator(field, options);
+ break;
+ default:
+ result = new RepeatedPrimitiveFieldGenerator(field, options);
+ break;
+ }
+ } else {
+ switch (GetObjectiveCType(field)) {
+ case OBJECTIVECTYPE_MESSAGE: {
+ result = new MessageFieldGenerator(field, options);
+ break;
+ }
+ case OBJECTIVECTYPE_ENUM:
+ result = new EnumFieldGenerator(field, options);
+ break;
+ default:
+ if (IsReferenceType(field)) {
+ result = new PrimitiveObjFieldGenerator(field, options);
+ } else {
+ result = new PrimitiveFieldGenerator(field, options);
+ }
+ break;
+ }
+ }
+ result->FinishInitialization();
+ return result;
+}
+
+FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor) {
+ SetCommonFieldVariables(descriptor, &variables_);
+}
+
+FieldGenerator::~FieldGenerator() {}
+
+void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
+ printer->Print(
+ variables_,
+ "$field_number_name$ = $field_number$,\n");
+}
+
+void FieldGenerator::GenerateCFunctionDeclarations(
+ io::Printer* printer) const {
+ // Nothing
+}
+
+void FieldGenerator::GenerateCFunctionImplementations(
+ io::Printer* printer) const {
+ // Nothing
+}
+
+void FieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ // Nothing
+}
+
+void FieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ // Nothing
+}
+
+void FieldGenerator::GenerateFieldDescription(
+ io::Printer* printer, bool include_default) const {
+ // Printed in the same order as the structure decl.
+ if (include_default) {
+ printer->Print(
+ variables_,
+ "{\n"
+ " .defaultValue.$default_name$ = $default$,\n"
+ " .core.name = \"$name$\",\n"
+ " .core.dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .core.number = $field_number_name$,\n"
+ " .core.hasIndex = $has_index$,\n"
+ " .core.offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .core.flags = $fieldflags$,\n"
+ " .core.dataType = GPBDataType$field_type$,\n"
+ "},\n");
+ } else {
+ printer->Print(
+ variables_,
+ "{\n"
+ " .name = \"$name$\",\n"
+ " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n"
+ " .number = $field_number_name$,\n"
+ " .hasIndex = $has_index$,\n"
+ " .offset = $storage_offset_value$,$storage_offset_comment$\n"
+ " .flags = $fieldflags$,\n"
+ " .dataType = GPBDataType$field_type$,\n"
+ "},\n");
+ }
+}
+
+void FieldGenerator::SetRuntimeHasBit(int has_index) {
+ variables_["has_index"] = StrCat(has_index);
+}
+
+void FieldGenerator::SetNoHasBit(void) {
+ variables_["has_index"] = "GPBNoHasBit";
+}
+
+int FieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ return 0;
+}
+
+void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for errors.
+ std::cerr << "Error: should have overridden SetExtraRuntimeHasBitsBase()." << std::endl;
+ std::cerr.flush();
+ abort();
+}
+
+void FieldGenerator::SetOneofIndexBase(int index_base) {
+ const OneofDescriptor* oneof = descriptor_->real_containing_oneof();
+ if (oneof != NULL) {
+ int index = oneof->index() + index_base;
+ // Flip the sign to mark it as a oneof.
+ variables_["has_index"] = StrCat(-index);
+ }
+}
+
+bool FieldGenerator::WantsHasProperty(void) const {
+ return descriptor_->has_presence() && !descriptor_->real_containing_oneof();
+}
+
+void FieldGenerator::FinishInitialization(void) {
+ // If "property_type" wasn't set, make it "storage_type".
+ if ((variables_.find("property_type") == variables_.end()) &&
+ (variables_.find("storage_type") != variables_.end())) {
+ variables_["property_type"] = variable("storage_type");
+ }
+}
+
+SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : FieldGenerator(descriptor, options) {
+ // Nothing
+}
+
+SingleFieldGenerator::~SingleFieldGenerator() {}
+
+void SingleFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$storage_type$ $name$;\n");
+}
+
+void SingleFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite) $property_type$ $name$$deprecated_attribute$;\n"
+ "\n");
+ if (WantsHasProperty()) {
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ }
+}
+
+void SingleFieldGenerator::GeneratePropertyImplementation(
+ io::Printer* printer) const {
+ if (WantsHasProperty()) {
+ printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n");
+ } else {
+ printer->Print(variables_, "@dynamic $name$;\n");
+ }
+}
+
+bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
+ if (descriptor_->real_containing_oneof()) {
+ // The oneof tracks what is set instead.
+ return false;
+ }
+ return true;
+}
+
+ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ variables_["property_storage_attribute"] = "strong";
+ if (IsRetainedName(variables_["name"])) {
+ variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
+ }
+}
+
+ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
+
+void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$storage_type$ *$name$;\n");
+}
+
+void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+
+ // Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that
+ // it uses pointers and deals with Objective C's rules around storage name
+ // conventions (init*, new*, etc.)
+
+ printer->Print(variables_, "$comments$");
+ printer->Print(
+ variables_,
+ "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n");
+ if (WantsHasProperty()) {
+ printer->Print(
+ variables_,
+ "/** Test to see if @c $name$ has been set. */\n"
+ "@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
+ }
+ if (IsInitName(variables_.find("name")->second)) {
+ // If property name starts with init we need to annotate it to get past ARC.
+ // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
+ printer->Print(variables_,
+ "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ }
+ printer->Print("\n");
+}
+
+RepeatedFieldGenerator::RepeatedFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ // Default to no comment and let the cases needing it fill it in.
+ variables_["array_comment"] = "";
+}
+
+RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
+
+void RepeatedFieldGenerator::FinishInitialization(void) {
+ FieldGenerator::FinishInitialization();
+ if (variables_.find("array_property_type") == variables_.end()) {
+ variables_["array_property_type"] = variable("array_storage_type");
+ }
+}
+
+void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ printer->Print(variables_, "$array_storage_type$ *$name$;\n");
+}
+
+void RepeatedFieldGenerator::GeneratePropertyImplementation(
+ io::Printer* printer) const {
+ printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
+}
+
+void RepeatedFieldGenerator::GeneratePropertyDeclaration(
+ io::Printer* printer) const {
+
+ // Repeated fields don't need the has* properties, but they do expose a
+ // *Count (to check without autocreation). So for the field property we need
+ // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
+ // dealing with needing Objective C's rules around storage name conventions
+ // (init*, new*, etc.)
+
+ printer->Print(
+ variables_,
+ "$comments$"
+ "$array_comment$"
+ "@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
+ "/** The number of items in @c $name$ without causing the array to be created. */\n"
+ "@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
+ if (IsInitName(variables_.find("name")->second)) {
+ // If property name starts with init we need to annotate it to get past ARC.
+ // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
+ printer->Print(variables_,
+ "- ($array_property_type$ *)$name$ GPB_METHOD_FAMILY_NONE$deprecated_attribute$;\n");
+ }
+ printer->Print("\n");
+}
+
+bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
+ return false; // The array (or map/dict) having anything is what is used.
+}
+
+FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
+ const Options& options)
+ : descriptor_(descriptor),
+ field_generators_(descriptor->field_count()),
+ extension_generators_(descriptor->extension_count()) {
+ // Construct all the FieldGenerators.
+ for (int i = 0; i < descriptor->field_count(); i++) {
+ field_generators_[i].reset(
+ FieldGenerator::Make(descriptor->field(i), options));
+ }
+ for (int i = 0; i < descriptor->extension_count(); i++) {
+ extension_generators_[i].reset(
+ FieldGenerator::Make(descriptor->extension(i), options));
+ }
+}
+
+FieldGeneratorMap::~FieldGeneratorMap() {}
+
+const FieldGenerator& FieldGeneratorMap::get(
+ const FieldDescriptor* field) const {
+ GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
+ return *field_generators_[field->index()];
+}
+
+const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
+ return *extension_generators_[index];
+}
+
+int FieldGeneratorMap::CalculateHasBits(void) {
+ int total_bits = 0;
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (field_generators_[i]->RuntimeUsesHasBit()) {
+ field_generators_[i]->SetRuntimeHasBit(total_bits);
+ ++total_bits;
+ } else {
+ field_generators_[i]->SetNoHasBit();
+ }
+ int extra_bits = field_generators_[i]->ExtraRuntimeHasBitsNeeded();
+ if (extra_bits) {
+ field_generators_[i]->SetExtraRuntimeHasBitsBase(total_bits);
+ total_bits += extra_bits;
+ }
+ }
+ return total_bits;
+}
+
+void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_[i]->SetOneofIndexBase(index_base);
+ }
+}
+
+bool FieldGeneratorMap::DoesAnyFieldHaveNonZeroDefault(void) const {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ if (HasNonZeroDefaultValue(descriptor_->field(i))) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h
new file mode 100644
index 00000000..ee213ff4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_field.h
@@ -0,0 +1,194 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class FieldGenerator {
+ public:
+ static FieldGenerator* Make(const FieldDescriptor* field,
+ const Options& options);
+
+ virtual ~FieldGenerator();
+
+ FieldGenerator(const FieldGenerator&) = delete;
+ FieldGenerator& operator=(const FieldGenerator&) = delete;
+
+ // Exposed for subclasses to fill in.
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const = 0;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const = 0;
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const = 0;
+
+ // Called by GenerateFieldDescription, exposed for classes that need custom
+ // generation.
+
+ // Exposed for subclasses to extend, base does nothing.
+ virtual void GenerateCFunctionDeclarations(io::Printer* printer) const;
+ virtual void GenerateCFunctionImplementations(io::Printer* printer) const;
+
+ // Exposed for subclasses, should always call it on the parent class also.
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const;
+
+ // Used during generation, not intended to be extended by subclasses.
+ void GenerateFieldDescription(
+ io::Printer* printer, bool include_default) const;
+ void GenerateFieldNumberConstant(io::Printer* printer) const;
+
+ // Exposed to get and set the has bits information.
+ virtual bool RuntimeUsesHasBit(void) const = 0;
+ void SetRuntimeHasBit(int has_index);
+ void SetNoHasBit(void);
+ virtual int ExtraRuntimeHasBitsNeeded(void) const;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base);
+ void SetOneofIndexBase(int index_base);
+
+ std::string variable(const char* key) const {
+ return variables_.find(key)->second;
+ }
+
+ bool needs_textformat_name_support() const {
+ const std::string& field_flags = variable("fieldflags");
+ return field_flags.find("GPBFieldTextFormatNameCustom") !=
+ std::string::npos;
+ }
+ std::string generated_objc_name() const { return variable("name"); }
+ std::string raw_field_name() const { return variable("raw_field_name"); }
+
+ protected:
+ FieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+
+ virtual void FinishInitialization(void);
+ bool WantsHasProperty(void) const;
+
+ const FieldDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+};
+
+class SingleFieldGenerator : public FieldGenerator {
+ public:
+ virtual ~SingleFieldGenerator();
+
+ 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;
+
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+
+ virtual bool RuntimeUsesHasBit(void) const override;
+
+ protected:
+ SingleFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+};
+
+// Subclass with common support for when the field ends up as an ObjC Object.
+class ObjCObjFieldGenerator : public SingleFieldGenerator {
+ public:
+ virtual ~ObjCObjFieldGenerator();
+
+ ObjCObjFieldGenerator(const ObjCObjFieldGenerator&) = delete;
+ ObjCObjFieldGenerator& operator=(const ObjCObjFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+
+ protected:
+ ObjCObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+};
+
+class RepeatedFieldGenerator : public ObjCObjFieldGenerator {
+ public:
+ virtual ~RepeatedFieldGenerator();
+
+ RepeatedFieldGenerator(const RepeatedFieldGenerator&) = delete;
+ RepeatedFieldGenerator& operator=(const RepeatedFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+ virtual void GeneratePropertyDeclaration(io::Printer* printer) const override;
+
+ virtual void GeneratePropertyImplementation(io::Printer* printer) const override;
+
+ virtual bool RuntimeUsesHasBit(void) const override;
+
+ protected:
+ RepeatedFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual void FinishInitialization(void) override;
+};
+
+// Convenience class which constructs FieldGenerators for a Descriptor.
+class FieldGeneratorMap {
+ public:
+ FieldGeneratorMap(const Descriptor* descriptor, const Options& options);
+ ~FieldGeneratorMap();
+
+ FieldGeneratorMap(const FieldGeneratorMap&) = delete;
+ FieldGeneratorMap& operator=(const FieldGeneratorMap&) = delete;
+
+ const FieldGenerator& get(const FieldDescriptor* field) const;
+ const FieldGenerator& get_extension(int index) const;
+
+ // Assigns the has bits and returns the number of bits needed.
+ int CalculateHasBits(void);
+
+ void SetOneofIndexBase(int index_base);
+
+ // Check if any field of this message has a non zero default.
+ bool DoesAnyFieldHaveNonZeroDefault(void) const;
+
+ private:
+ const Descriptor* descriptor_;
+ std::vector<std::unique_ptr<FieldGenerator>> field_generators_;
+ std::vector<std::unique_ptr<FieldGenerator>> extension_generators_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc
new file mode 100644
index 00000000..e98a8985
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.cc
@@ -0,0 +1,610 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <compiler/objectivec/objectivec_file.h>
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_message.h>
+#include <compiler/code_generator.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <stubs/stl_util.h>
+#include <stubs/strutil.h>
+#include <algorithm> // std::find()
+#include <iostream>
+#include <sstream>
+
+// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+// error cases, so it seems to be ok to use as a back door for errors.
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+// This is also found in GPBBootstrap.h, and needs to be kept in sync.
+const int32_t GOOGLE_PROTOBUF_OBJC_VERSION = 30004;
+
+const char* kHeaderExtension = ".pbobjc.h";
+
+// Checks if a message contains any enums definitions (on the message or
+// a nested message under it).
+bool MessageContainsEnums(const Descriptor* message) {
+ if (message->enum_type_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (MessageContainsEnums(message->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if a message contains any extension definitions (on the message or
+// a nested message under it).
+bool MessageContainsExtensions(const Descriptor* message) {
+ if (message->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (MessageContainsExtensions(message->nested_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if the file contains any enum definitions (at the root or
+// nested under a message).
+bool FileContainsEnums(const FileDescriptor* file) {
+ if (file->enum_type_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageContainsEnums(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Checks if the file contains any extensions definitions (at the root or
+// nested under a message).
+bool FileContainsExtensions(const FileDescriptor* file) {
+ if (file->extension_count() > 0) {
+ return true;
+ }
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageContainsExtensions(file->message_type(i))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all
+// deps as visited and prunes them from the needed files list.
+void PruneFileAndDepsMarkingAsVisited(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files,
+ std::set<const FileDescriptor*>* files_visited) {
+ std::vector<const FileDescriptor*>::iterator iter =
+ std::find(files->begin(), files->end(), file);
+ if (iter != files->end()) {
+ files->erase(iter);
+ }
+ files_visited->insert(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited);
+ }
+}
+
+// Helper for CollectMinimalFileDepsContainingExtensions.
+void CollectMinimalFileDepsContainingExtensionsWorker(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files,
+ std::set<const FileDescriptor*>* files_visited) {
+ if (files_visited->find(file) != files_visited->end()) {
+ return;
+ }
+ files_visited->insert(file);
+
+ if (FileContainsExtensions(file)) {
+ files->push_back(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ PruneFileAndDepsMarkingAsVisited(dep, files, files_visited);
+ }
+ } else {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ files_visited);
+ }
+ }
+}
+
+// Collect the deps of the given file that contain extensions. This can be used to
+// create the chain of roots that need to be wired together.
+//
+// NOTE: If any changes are made to this and the supporting functions, you will
+// need to manually validate what the generated code is for the test files:
+// objectivec/Tests/unittest_extension_chain_*.proto
+// There are comments about what the expected code should be line and limited
+// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
+// specifically).
+void CollectMinimalFileDepsContainingExtensions(
+ const FileDescriptor* file,
+ std::vector<const FileDescriptor*>* files) {
+ std::set<const FileDescriptor*> files_visited;
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ &files_visited);
+ }
+}
+
+bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ if (dep == file->dependency(i)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace
+
+FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
+ : file_(file),
+ root_class_name_(FileClassName(file)),
+ is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)),
+ options_(options) {
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ EnumGenerator* generator = new EnumGenerator(file_->enum_type(i));
+ enum_generators_.emplace_back(generator);
+ }
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ MessageGenerator* generator =
+ new MessageGenerator(root_class_name_, file_->message_type(i), options_);
+ message_generators_.emplace_back(generator);
+ }
+ for (int i = 0; i < file_->extension_count(); i++) {
+ ExtensionGenerator* generator =
+ new ExtensionGenerator(root_class_name_, file_->extension(i));
+ extension_generators_.emplace_back(generator);
+ }
+}
+
+FileGenerator::~FileGenerator() {}
+
+void FileGenerator::GenerateHeader(io::Printer* printer) {
+ std::vector<std::string> headers;
+ // Generated files bundled with the library get minimal imports, everything
+ // else gets the wrapper so everything is usable.
+ if (is_bundled_proto_) {
+ headers.push_back("GPBDescriptor.h");
+ headers.push_back("GPBMessage.h");
+ headers.push_back("GPBRootObject.h");
+ } else {
+ headers.push_back("GPBProtocolBuffers.h");
+ }
+ PrintFileRuntimePreamble(printer, headers);
+
+ // Add some verification that the generated code matches the source the
+ // code is being compiled with.
+ // NOTE: This captures the raw numeric values at the time the generator was
+ // compiled, since that will be the versions for the ObjC runtime at that
+ // time. The constants in the generated code will then get their values at
+ // at compile time (so checking against the headers being used to compile).
+ printer->Print(
+ "#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n"
+ "#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n"
+ "#endif\n"
+ "#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n"
+ "#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n"
+ "#endif\n"
+ "\n",
+ "google_protobuf_objc_version", StrCat(GOOGLE_PROTOBUF_OBJC_VERSION));
+
+ // #import any headers for "public imports" in the proto file.
+ {
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path,
+ options_.runtime_import_prefix,
+ is_bundled_proto_);
+ const std::string header_extension(kHeaderExtension);
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ import_writer.AddFile(file_->public_dependency(i), header_extension);
+ }
+ import_writer.Print(printer);
+ }
+
+ // Note:
+ // deprecated-declarations suppression is only needed if some place in this
+ // proto file is something deprecated or if it references something from
+ // another file that is deprecated.
+ printer->Print(
+ "// @@protoc_insertion_point(imports)\n"
+ "\n"
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n"
+ "\n"
+ "CF_EXTERN_C_BEGIN\n"
+ "\n");
+
+ std::set<std::string> fwd_decls;
+ for (const auto& generator : message_generators_) {
+ generator->DetermineForwardDeclarations(&fwd_decls);
+ }
+ for (std::set<std::string>::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<std::string> headers;
+ headers.push_back("GPBProtocolBuffers_RuntimeSupport.h");
+ PrintFileRuntimePreamble(printer, headers);
+
+ // Enums use atomic in the generated code, so add the system import as needed.
+ if (FileContainsEnums(file_)) {
+ printer->Print(
+ "#import <stdatomic.h>\n"
+ "\n");
+ }
+
+ std::vector<const FileDescriptor*> deps_with_extensions;
+ CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions);
+
+ {
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path,
+ options_.runtime_import_prefix,
+ is_bundled_proto_);
+ const std::string header_extension(kHeaderExtension);
+
+ // #import the header for this proto file.
+ import_writer.AddFile(file_, header_extension);
+
+ // #import the headers for anything that a plain dependency of this proto
+ // file (that means they were just an include, not a "public" include).
+ std::set<std::string> 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<std::string> 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 std::string 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<std::string, std::string> 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<std::string>& headers_to_import) const {
+ printer->Print(
+ "// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "// source: $filename$\n"
+ "\n",
+ "filename", file_->name());
+ ImportWriter::PrintRuntimeImports(
+ printer, headers_to_import, options_.runtime_import_prefix, true);
+ printer->Print("\n");
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.h
new file mode 100644
index 00000000..61572802
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_file.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_FILE_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class EnumGenerator;
+class ExtensionGenerator;
+class MessageGenerator;
+
+class FileGenerator {
+ public:
+ FileGenerator(const FileDescriptor* file, const Options& options);
+ ~FileGenerator();
+
+ FileGenerator(const FileGenerator&) = delete;
+ FileGenerator& operator=(const FileGenerator&) = delete;
+
+ void GenerateSource(io::Printer* printer);
+ void GenerateHeader(io::Printer* printer);
+
+ private:
+ const FileDescriptor* file_;
+ std::string root_class_name_;
+ bool is_bundled_proto_;
+
+ std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+ std::vector<std::unique_ptr<MessageGenerator>> message_generators_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+
+ const Options options_;
+
+ void PrintFileRuntimePreamble(
+ io::Printer* printer,
+ const std::vector<std::string>& headers_to_import) const;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_FILE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc
new file mode 100644
index 00000000..3dbd1d43
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -0,0 +1,276 @@
+// 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 <fstream>
+#include <iostream>
+#include <string>
+#include <unordered_set>
+#include <compiler/objectivec/objectivec_generator.h>
+#include <compiler/objectivec/objectivec_file.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+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.
+bool StringToBool(const std::string& value, bool* result) {
+ std::string upper_value(value);
+ UpperString(&upper_value);
+ if (upper_value == "NO") {
+ *result = false;
+ return true;
+ }
+ if (upper_value == "YES") {
+ *result = true;
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+ObjectiveCGenerator::ObjectiveCGenerator() {}
+
+ObjectiveCGenerator::~ObjectiveCGenerator() {}
+
+bool ObjectiveCGenerator::HasGenerateAll() const {
+ return true;
+}
+
+bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* context,
+ std::string* error) const {
+ *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
+ return false;
+}
+
+bool ObjectiveCGenerator::GenerateAll(
+ const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const {
+ // -----------------------------------------------------------------
+ // Parse generator options. These options are passed to the compiler using the
+ // --objc_opt flag. The options are passed as a comma separated list of
+ // options along with their values. If the option appears multiple times, only
+ // the last value will be considered.
+ //
+ // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
+
+ Options generation_options;
+
+ std::vector<std::pair<std::string, std::string> > options;
+ ParseGeneratorParameter(parameter, &options);
+ for (int i = 0; i < options.size(); i++) {
+ if (options[i].first == "expected_prefixes_path") {
+ // Path to find a file containing the expected prefixes
+ // (objc_class_prefix "PREFIX") for proto packages (package NAME). The
+ // generator will then issue warnings/errors if in the proto files being
+ // generated the option is not listed/wrong/etc in the file.
+ //
+ // The format of the file is:
+ // - An entry is a line of "package=prefix".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "package=prefix # comment")
+ //
+ // There is no validation that the prefixes are good prefixes, it is
+ // assumed that they are when you create the file.
+ generation_options.expected_prefixes_path = options[i].second;
+ } else if (options[i].first == "expected_prefixes_suppressions") {
+ // A semicolon delimited string that lists the paths of .proto files to
+ // exclude from the package prefix validations (expected_prefixes_path).
+ // This is provided as an "out", to skip some files being checked.
+ for (StringPiece split_piece : Split(
+ options[i].second, ";", true)) {
+ generation_options.expected_prefixes_suppressions.push_back(
+ std::string(split_piece));
+ }
+ } else if (options[i].first == "prefixes_must_be_registered") {
+ // If objc prefix file option value must be registered to be used. This
+ // option has no meaning if an "expected_prefixes_path" isn't set. The
+ // available options are:
+ // "no": They don't have to be registered.
+ // "yes": They must be registered and an error will be raised if a files
+ // tried to use a prefix that isn't registered.
+ // Default is "no".
+ if (!StringToBool(options[i].second,
+ &generation_options.prefixes_must_be_registered)) {
+ *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "require_prefixes") {
+ // If every file must have an objc prefix file option to be used. The
+ // available options are:
+ // "no": Files can be generated without the prefix option.
+ // "yes": Files must have the objc prefix option, and an error will be
+ // raised if a files doesn't have one.
+ // Default is "no".
+ if (!StringToBool(options[i].second,
+ &generation_options.require_prefixes)) {
+ *error = "error: Unknown value for require_prefixes: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "generate_for_named_framework") {
+ // The name of the framework that protos are being generated for. This
+ // will cause the #import statements to be framework based using this
+ // name (i.e. - "#import <NAME/proto.pbobjc.h>).
+ //
+ // NOTE: If this option is used with
+ // named_framework_to_proto_path_mappings_path, then this is effectively
+ // the "default" framework name used for everything that wasn't mapped by
+ // the mapping file.
+ generation_options.generate_for_named_framework = options[i].second;
+ } else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
+ // Path to find a file containing the list of framework names and proto
+ // files. The generator uses this to decide if a proto file
+ // referenced should use a framework style import vs. a user level import
+ // (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
+ //
+ // The format of the file is:
+ // - An entry is a line of "frameworkName: file.proto, dir/file2.proto".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "frameworkName: file.proto # comment")
+ //
+ // Any number of files can be listed for a framework, just separate them
+ // with commas.
+ //
+ // There can be multiple lines listing the same frameworkName in case it
+ // has a lot of proto files included in it; having multiple lines makes
+ // things easier to read. If a proto file is not configured in the
+ // mappings file, it will use the default framework name if one was passed
+ // with generate_for_named_framework, or the relative path to it's include
+ // path otherwise.
+ generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
+ } else if (options[i].first == "runtime_import_prefix") {
+ // Path to use as a prefix on #imports of runtime provided headers in the
+ // generated files. When integrating ObjC protos into a build system,
+ // this can be used to avoid having to add the runtime directory to the
+ // header search path since the generate #import will be more complete.
+ generation_options.runtime_import_prefix =
+ StripSuffixString(options[i].second, "/");
+ } else if (options[i].first == "use_package_as_prefix") {
+ // Controls how the symbols should be prefixed to avoid symbols
+ // collisions. The objc_class_prefix file option is always honored, this
+ // is just what to do if that isn't set. The available options are:
+ // "no": Not prefixed (the existing mode).
+ // "yes": Make a prefix out of the proto package.
+ bool value = false;
+ if (StringToBool(options[i].second, &value)) {
+ SetUseProtoPackageAsDefaultPrefix(value);
+ } else {
+ *error = "error: Unknown use_package_as_prefix: " + options[i].second;
+ return false;
+ }
+ } else if (options[i].first == "proto_package_prefix_exceptions_path") {
+ // Path to find a file containing the list of proto package names that are
+ // exceptions when use_package_as_prefix is enabled. This can be used to
+ // migrate packages one at a time to use_package_as_prefix since there
+ // are likely code updates needed with each one.
+ //
+ // The format of the file is:
+ // - An entry is a line of "proto.package.name".
+ // - Comments start with "#".
+ // - A comment can go on a line after a expected package/prefix pair.
+ // (i.e. - "some.proto.package # comment")
+ SetProtoPackagePrefixExceptionList(options[i].second);
+ } else {
+ *error = "error: Unknown generator option: " + options[i].first;
+ return 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<std::string> skip_impls;
+ if (getenv("GPB_OBJC_SKIP_IMPLS_FILE") != NULL) {
+ std::ifstream skip_file(getenv("GPB_OBJC_SKIP_IMPLS_FILE"));
+ if (skip_file.is_open()) {
+ std::string line;
+ while (std::getline(skip_file, line)) {
+ skip_impls.insert(line);
+ }
+ } else {
+ *error = "error: Failed to open GPB_OBJC_SKIP_IMPLS_FILE file";
+ return false;
+ }
+ }
+
+ // -----------------------------------------------------------------
+
+ // Validate the objc prefix/package pairings.
+ if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
+ // *error will have been filled in.
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ FileGenerator file_generator(file, generation_options);
+ std::string filepath = FilePath(file);
+
+ // Generate header.
+ {
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filepath + ".pbobjc.h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateHeader(&printer);
+ }
+
+ // Generate m file.
+ 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);
+ }
+ }
+
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h
new file mode 100644
index 00000000..c7cfe8d3
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_generator.h
@@ -0,0 +1,79 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Generates ObjectiveC code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
+
+#include <string>
+#include <compiler/code_generator.h>
+#include <descriptor.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// CodeGenerator implementation which generates a ObjectiveC source file and
+// header. If you create your own protocol compiler binary and you want it to
+// support ObjectiveC output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
+ public:
+ ObjectiveCGenerator();
+ ~ObjectiveCGenerator();
+
+ ObjectiveCGenerator(const ObjectiveCGenerator&) = delete;
+ ObjectiveCGenerator& operator=(const ObjectiveCGenerator&) = delete;
+
+ // implements CodeGenerator ----------------------------------------
+ bool HasGenerateAll() const override;
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* context, std::string* error) const override;
+ bool GenerateAll(const std::vector<const FileDescriptor*>& files,
+ const std::string& parameter, GeneratorContext* context,
+ std::string* error) const override;
+
+ uint64_t GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc
new file mode 100644
index 00000000..014edb9e
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -0,0 +1,1960 @@
+// 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 <compiler/code_generator.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_nsobject_methods.h>
+#include <descriptor.pb.h>
+#include <io/coded_stream.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream_impl.h>
+#include <io/io_win32.h>
+#include <port.h>
+#include <stubs/common.h>
+#include <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 {
+
+class SimpleLineCollector : public LineConsumer {
+ public:
+ SimpleLineCollector(std::unordered_set<std::string>* inout_set)
+ : set_(inout_set) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override {
+ set_->insert(std::string(line));
+ return true;
+ }
+
+ private:
+ std::unordered_set<std::string>* set_;
+};
+
+class PrefixModeStorage {
+ public:
+ PrefixModeStorage();
+
+ 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 std::string exception_path() const { return exception_path_; }
+ void set_exception_path(const std::string& path) {
+ exception_path_ = path;
+ exceptions_.clear();
+ }
+
+ bool is_package_exempted(const std::string& package);
+
+ private:
+ bool use_package_name_;
+ std::string exception_path_;
+ std::unordered_set<std::string> 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.
+
+ const char* use_package_cstr = getenv("GPB_OBJC_USE_PACKAGE_AS_PREFIX");
+ use_package_name_ =
+ (use_package_cstr && (std::string("YES") == ToUpper(use_package_cstr)));
+
+ const char* exception_path = getenv("GPB_OBJC_PACKAGE_PREFIX_EXCEPTIONS_PATH");
+ if (exception_path) {
+ exception_path_ = exception_path;
+ }
+}
+
+bool PrefixModeStorage::is_package_exempted(const std::string& package) {
+ if (exceptions_.empty() && !exception_path_.empty()) {
+ std::string error_str;
+ SimpleLineCollector collector(&exceptions_);
+ if (!ParseSimpleFile(exception_path_, &collector, &error_str)) {
+ if (error_str.empty()) {
+ error_str = std::string("protoc:0: warning: Failed to parse")
+ + std::string(" 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
+
+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);
+}
+
+std::string GetProtoPackagePrefixExceptionList() {
+ return g_prefix_mode.exception_path();
+}
+
+void SetProtoPackagePrefixExceptionList(const std::string& file_path) {
+ g_prefix_mode.set_exception_path(file_path);
+}
+
+Options::Options() {
+ // Default is the value of the env for the package prefixes.
+ const char* file_path = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES");
+ if (file_path) {
+ expected_prefixes_path = file_path;
+ }
+ const char* suppressions = getenv("GPB_OBJC_EXPECTED_PACKAGE_PREFIXES_SUPPRESSIONS");
+ if (suppressions) {
+ expected_prefixes_suppressions =
+ Split(suppressions, ";", true);
+ }
+ prefixes_must_be_registered = false;
+ require_prefixes = false;
+}
+
+namespace {
+
+std::unordered_set<std::string> MakeWordsMap(const char* const words[],
+ size_t num_words) {
+ std::unordered_set<std::string> 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<std::string> 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.
+std::string UnderscoresToCamelCase(const std::string& input,
+ bool first_capitalized) {
+ std::vector<std::string> values;
+ std::string 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);
+
+ std::string result;
+ bool first_segment_forces_upper = false;
+ for (std::vector<std::string>::iterator i = values.begin(); i != values.end();
+ ++i) {
+ std::string 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 std::string& input) {
+ if (input.length() > 2) {
+ if (input.at(0) == '_') {
+ if (isupper(input.at(1)) || input.at(1) == '_') {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+std::string SanitizeNameForObjC(const std::string& prefix,
+ const std::string& input,
+ const std::string& extension,
+ std::string* out_suffix_added) {
+ static const std::unordered_set<std::string> kReservedWords =
+ MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
+ static const std::unordered_set<std::string> kNSObjectMethods =
+ MakeWordsMap(kNSObjectMethodsList, GOOGLE_ARRAYSIZE(kNSObjectMethodsList));
+ std::string 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;
+}
+
+std::string NameFromFieldDescriptor(const FieldDescriptor* field) {
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
+ return field->message_type()->name();
+ } else {
+ return field->name();
+ }
+}
+
+void PathSplit(const std::string& path, std::string* directory,
+ std::string* basename) {
+ std::string::size_type last_slash = path.rfind('/');
+ if (last_slash == std::string::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 std::string& name, const std::string* 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;
+}
+
+std::string 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";
+ }
+}
+
+std::string 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 std::string();
+ }
+}
+
+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 \?
+std::string EscapeTrigraphs(const std::string& 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 std::string& name) {
+ // List of prefixes from
+ // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html
+ static const std::string retained_names[] = {"new", "alloc", "copy",
+ "mutableCopy"};
+ return IsSpecialName(name, retained_names,
+ sizeof(retained_names) / sizeof(retained_names[0]));
+}
+
+bool IsInitName(const std::string& name) {
+ static const std::string init_names[] = {"init"};
+ return IsSpecialName(name, init_names,
+ sizeof(init_names) / sizeof(init_names[0]));
+}
+
+std::string BaseFileName(const FileDescriptor* file) {
+ std::string basename;
+ PathSplit(file->name(), NULL, &basename);
+ return basename;
+}
+
+std::string 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 isn't enabled or no package, done.
+ if (!g_prefix_mode.use_package_name() || file->package().empty()) {
+ 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.
+ std::string result;
+ const std::vector<std::string> segments = Split(file->package(), ".", true);
+ for (const auto& segment : segments) {
+ const std::string part = UnderscoresToCamelCase(segment, true);
+ if (part.empty()) {
+ continue;
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ result.append(part);
+ }
+ if (!result.empty()) {
+ result.append("_");
+ }
+ return result;
+}
+
+std::string FilePath(const FileDescriptor* file) {
+ std::string output;
+ std::string basename;
+ std::string 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;
+}
+
+std::string FilePathBasename(const FileDescriptor* file) {
+ std::string output;
+ std::string basename;
+ std::string directory;
+ PathSplit(file->name(), &directory, &basename);
+ basename = StripProto(basename);
+
+ // CamelCase to be more ObjC friendly.
+ output = UnderscoresToCamelCase(basename, true);
+
+ return output;
+}
+
+std::string FileClassName(const FileDescriptor* file) {
+ const std::string prefix = FileClassPrefix(file);
+ const std::string 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);
+}
+
+std::string ClassNameWorker(const Descriptor* descriptor) {
+ std::string name;
+ if (descriptor->containing_type() != NULL) {
+ name = ClassNameWorker(descriptor->containing_type());
+ name += "_";
+ }
+ return name + descriptor->name();
+}
+
+std::string ClassNameWorker(const EnumDescriptor* descriptor) {
+ std::string name;
+ if (descriptor->containing_type() != NULL) {
+ name = ClassNameWorker(descriptor->containing_type());
+ name += "_";
+ }
+ return name + descriptor->name();
+}
+
+std::string ClassName(const Descriptor* descriptor) {
+ return ClassName(descriptor, NULL);
+}
+
+std::string ClassName(const Descriptor* descriptor,
+ std::string* 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 std::string prefix = FileClassPrefix(descriptor->file());
+ const std::string name = ClassNameWorker(descriptor);
+ return SanitizeNameForObjC(prefix, name, "_Class", out_suffix_added);
+}
+
+std::string 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 std::string prefix = FileClassPrefix(descriptor->file());
+ const std::string name = ClassNameWorker(descriptor);
+ return SanitizeNameForObjC(prefix, name, "_Enum", NULL);
+}
+
+std::string 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 std::string class_name = EnumName(descriptor->type());
+ const std::string value_str =
+ UnderscoresToCamelCase(descriptor->name(), true);
+ const std::string 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);
+}
+
+std::string 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 std::string class_name = EnumName(descriptor->type());
+ const std::string long_name_prefix = class_name + "_";
+ const std::string long_name = EnumValueName(descriptor);
+ return StripPrefixString(long_name, long_name_prefix);
+}
+
+std::string UnCamelCaseEnumShortName(const std::string& name) {
+ std::string 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;
+}
+
+std::string ExtensionMethodName(const FieldDescriptor* descriptor) {
+ const std::string name = NameFromFieldDescriptor(descriptor);
+ const std::string result = UnderscoresToCamelCase(name, false);
+ return SanitizeNameForObjC("", result, "_Extension", NULL);
+}
+
+std::string FieldName(const FieldDescriptor* field) {
+ const std::string name = NameFromFieldDescriptor(field);
+ std::string 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);
+}
+
+std::string FieldNameCapitalized(const FieldDescriptor* field) {
+ // Want the same suffix handling, so upcase the first letter of the other
+ // name.
+ std::string result = FieldName(field);
+ if (result.length() > 0) {
+ result[0] = ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+std::string OneofEnumName(const OneofDescriptor* descriptor) {
+ const Descriptor* fieldDescriptor = descriptor->containing_type();
+ std::string name = ClassName(fieldDescriptor);
+ name += "_" + UnderscoresToCamelCase(descriptor->name(), true) + "_OneOfCase";
+ // No sanitize needed because the OS never has names that end in _OneOfCase.
+ return name;
+}
+
+std::string OneofName(const OneofDescriptor* descriptor) {
+ std::string name = UnderscoresToCamelCase(descriptor->name(), false);
+ // No sanitize needed because it gets OneOfCase added and that shouldn't
+ // ever conflict.
+ return name;
+}
+
+std::string OneofNameCapitalized(const OneofDescriptor* descriptor) {
+ // Use the common handling and then up-case the first letter.
+ std::string result = OneofName(descriptor);
+ if (result.length() > 0) {
+ result[0] = ascii_toupper(result[0]);
+ }
+ return result;
+}
+
+std::string ObjCClass(const std::string& class_name) {
+ return std::string("GPBObjCClass(") + class_name + ")";
+}
+
+std::string ObjCClassDeclaration(const std::string& class_name) {
+ return std::string("GPBObjCClassDeclaration(") + class_name + ");";
+}
+
+std::string UnCamelCaseFieldName(const std::string& name, const FieldDescriptor* field) {
+ std::string 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 {
+ std::string 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;
+ }
+}
+
+std::string 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 std::string();
+}
+
+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 std::string HandleExtremeFloatingPoint(std::string 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(".") != std::string::npos ||
+ val.find("e") != std::string::npos ||
+ val.find("E") != std::string::npos)) {
+ val += "f";
+ }
+ return val;
+ }
+}
+
+std::string 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 std::string();
+}
+
+
+std::string 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 std::string& default_string = field->default_value_string();
+ if (!has_default_value || default_string.length() == 0) {
+ // If the field is defined as being the empty string,
+ // then we will just assign to nil, as the empty string is the
+ // default for both strings and data.
+ return "nil";
+ }
+ if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ // We want constant fields in our data structures so we can
+ // declare them as static. To achieve this we cheat and stuff
+ // a escaped c string (prefixed with a length) into the data
+ // field, and cast it to an (NSData*) so it will compile.
+ // The runtime library knows how to handle it.
+
+ // Must convert to a standard byte order for packing length into
+ // a cstring.
+ uint32_t length = ghtonl(default_string.length());
+ std::string 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 std::string();
+}
+
+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 std::string& 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;
+}
+
+std::string BuildFlagsString(const FlagType flag_type,
+ const std::vector<std::string>& strings) {
+ if (strings.empty()) {
+ return GetZeroEnumNameForFlagType(flag_type);
+ } else if (strings.size() == 1) {
+ return strings[0];
+ }
+ std::string 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;
+}
+
+std::string BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line) {
+ const std::string& comments = location.leading_comments.empty()
+ ? location.trailing_comments
+ : location.leading_comments;
+ std::vector<std::string> 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 "";
+ }
+
+ std::string prefix;
+ std::string suffix;
+ std::string final_comments;
+ std::string 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++) {
+ std::string 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";
+
+std::string ProtobufFrameworkImportSymbol(const std::string& framework_name) {
+ // GPB_USE_[framework_name]_FRAMEWORK_IMPORTS
+ std::string result = std::string("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 std::string name = file->name();
+ if (name == "google/protobuf/any.proto" ||
+ name == "google/protobuf/api.proto" ||
+ name == "google/protobuf/duration.proto" ||
+ name == "google/protobuf/empty.proto" ||
+ name == "google/protobuf/field_mask.proto" ||
+ name == "google/protobuf/source_context.proto" ||
+ name == "google/protobuf/struct.proto" ||
+ name == "google/protobuf/timestamp.proto" ||
+ name == "google/protobuf/type.proto" ||
+ name == "google/protobuf/wrappers.proto") {
+ return true;
+ }
+ return false;
+}
+
+bool ReadLine(StringPiece* input, StringPiece* line) {
+ for (int len = 0; len < input->size(); ++len) {
+ if (ascii_isnewline((*input)[len])) {
+ *line = StringPiece(input->data(), len);
+ ++len; // advance over the newline
+ *input = StringPiece(input->data() + len, input->size() - len);
+ return true;
+ }
+ }
+ return false; // Ran out of input with no newline.
+}
+
+void RemoveComment(StringPiece* input) {
+ int offset = input->find('#');
+ if (offset != StringPiece::npos) {
+ input->remove_suffix(input->length() - offset);
+ }
+}
+
+namespace {
+
+class ExpectedPrefixesCollector : public LineConsumer {
+ public:
+ ExpectedPrefixesCollector(std::map<std::string, std::string>* inout_package_to_prefix_map)
+ : prefix_map_(inout_package_to_prefix_map) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override;
+
+ private:
+ std::map<std::string, std::string>* prefix_map_;
+};
+
+bool ExpectedPrefixesCollector::ConsumeLine(
+ const StringPiece& line, std::string* out_error) {
+ int offset = line.find('=');
+ if (offset == StringPiece::npos) {
+ *out_error = std::string("Expected prefixes file line without equal sign: '") +
+ std::string(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_)[std::string(package)] = std::string(prefix);
+ return true;
+}
+
+bool LoadExpectedPackagePrefixes(const Options& generation_options,
+ std::map<std::string, std::string>* prefix_map,
+ std::string* out_error) {
+ if (generation_options.expected_prefixes_path.empty()) {
+ return true;
+ }
+
+ ExpectedPrefixesCollector collector(prefix_map);
+ return ParseSimpleFile(
+ generation_options.expected_prefixes_path, &collector, out_error);
+}
+
+bool ValidateObjCClassPrefix(
+ const FileDescriptor* file, const std::string& expected_prefixes_path,
+ const std::map<std::string, std::string>& expected_package_prefixes,
+ bool prefixes_must_be_registered, bool require_prefixes,
+ std::string* 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 std::string prefix = file->options().objc_class_prefix();
+ const std::string package = file->package();
+
+ // NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
+ // error cases, so it seems to be ok to use as a back door for warnings.
+
+ // Check: Error - See if there was an expected prefix for the package and
+ // report if it doesn't match (wrong or missing).
+ std::map<std::string, std::string>::const_iterator package_match =
+ expected_package_prefixes.find(package);
+ 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 + "\";' for package '" + package +
+ "' 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.
+ std::string other_package_for_prefix;
+ for (std::map<std::string, std::string>::const_iterator i =
+ expected_package_prefixes.begin();
+ i != expected_package_prefixes.end(); ++i) {
+ if (i->second == prefix) {
+ other_package_for_prefix = i->first;
+ break;
+ }
+ }
+
+ // Check: Warning - If the file does not have a package, check whether the
+ // prefix was declared is being used by another package or not. This is
+ // a special case for empty packages.
+ if (package.empty()) {
+ // The file does not have a package and ...
+ if (other_package_for_prefix.empty()) {
+ // ... no other package has declared that prefix.
+ std::cerr
+ << "protoc:0: warning: File '" << file->name() << "' has no "
+ << "package. Consider adding a new package to the proto and adding '"
+ << "new.package = " << prefix << "' to the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ } else {
+ // ... another package has declared the same prefix.
+ std::cerr
+ << "protoc:0: warning: File '" << file->name() << "' has no package "
+ << "and package '" << other_package_for_prefix << "' already uses '"
+ << prefix << "' as its prefix. Consider either adding a new package "
+ << "to the proto, or reusing one of the packages already using this "
+ << "prefix in the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ }
+ return true;
+ }
+
+ // Check: Error - Make sure the prefix wasn't expected for a different
+ // package (overlap is allowed, but it has to be listed as an expected
+ // overlap).
+ if (!other_package_for_prefix.empty()) {
+ *out_error =
+ "error: Found 'option objc_class_prefix = \"" + prefix +
+ "\";' in '" + file->name() +
+ "'; that prefix is already used for 'package " +
+ other_package_for_prefix + ";'. It can only be reused by listing " +
+ "it in the expected file (" +
+ expected_prefixes_path + ").";
+ return false; // Only report first usage of the prefix.
+ }
+ } // !prefix.empty()
+
+ // 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 it to the expected " +
+ "prefixes file (" + expected_prefixes_path + ") for the package '" +
+ package + "'.";
+ return false;
+ }
+
+ std::cerr
+ << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
+ << prefix << "\";' in '" << file->name() << "';"
+ << " consider adding it to the expected prefixes file ("
+ << expected_prefixes_path << ")." << std::endl;
+ std::cerr.flush();
+ }
+
+ return true;
+}
+
+} // namespace
+
+bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
+ const Options& generation_options,
+ std::string* 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<std::string, std::string> expected_package_prefixes;
+ if (!LoadExpectedPackagePrefixes(generation_options,
+ &expected_package_prefixes,
+ out_error)) {
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ bool should_skip =
+ (std::find(generation_options.expected_prefixes_suppressions.begin(),
+ generation_options.expected_prefixes_suppressions.end(),
+ files[i]->name())
+ != generation_options.expected_prefixes_suppressions.end());
+ if (should_skip) {
+ continue;
+ }
+
+ bool is_valid =
+ ValidateObjCClassPrefix(files[i],
+ generation_options.expected_prefixes_path,
+ expected_package_prefixes,
+ 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(int32_t key,
+ const std::string& input_for_decode,
+ const std::string& 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 std::string& data = TextFormatDecodeData::DecodeDataForString(
+ input_for_decode, desired_output);
+ entries_.push_back(DataEntry(key, data));
+}
+
+std::string 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();
+}
+
+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;
+ }
+ std::string 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_;
+
+ std::string 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.
+std::string DirectDecodeString(const std::string& str) {
+ std::string result;
+ result += (char)'\0'; // Marker for full string.
+ result += str;
+ result += (char)'\0'; // End of string.
+ return result;
+}
+
+} // namespace
+
+// static
+std::string TextFormatDecodeData::DecodeDataForString(
+ const std::string& input_for_decode, const std::string& 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') != std::string::npos) ||
+ (desired_output.find('\0') != std::string::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, std::string* 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(std::string* out_error);
+
+ int last_line() const { return line_; }
+
+ private:
+ LineConsumer* line_consumer_;
+ int line_;
+ std::string leftover_;
+};
+
+bool Parser::ParseChunk(StringPiece chunk, std::string* out_error) {
+ StringPiece full_chunk;
+ if (!leftover_.empty()) {
+ leftover_ += std::string(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_ = std::string(full_chunk);
+ }
+ return true;
+}
+
+bool Parser::Finish(std::string* 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;
+}
+
+std::string FullErrorString(const std::string& name, int line_num, const std::string& msg) {
+ return std::string("error: ") + name + " Line " + StrCat(line_num) + ", " + msg;
+}
+
+} // namespace
+
+LineConsumer::LineConsumer() {}
+
+LineConsumer::~LineConsumer() {}
+
+bool ParseSimpleFile(const std::string& path, LineConsumer* line_consumer,
+ std::string* out_error) {
+ int fd;
+ do {
+ fd = posix::open(path.c_str(), O_RDONLY);
+ } while (fd < 0 && errno == EINTR);
+ if (fd < 0) {
+ *out_error = std::string("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 std::string& stream_name,
+ LineConsumer* line_consumer,
+ std::string* out_error) {
+ std::string 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 std::string& generate_for_named_framework,
+ const std::string& named_framework_to_proto_path_mappings_path,
+ const std::string& 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 std::string& 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 std::string 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<std::string, std::string>::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<std::string>::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<std::string>::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<std::string>& header_to_import,
+ const std::string& 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 std::string framework_name(ProtobufLibraryFrameworkName);
+ const std::string 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_);
+ std::string 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, std::string* out_error) {
+ int offset = line.find(':');
+ if (offset == StringPiece::npos) {
+ *out_error =
+ std::string("Framework/proto file mapping line without colon sign: '") +
+ std::string(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<std::string, std::string>::iterator existing_entry =
+ map_->find(std::string(proto_file));
+ if (existing_entry != map_->end()) {
+ std::cerr << "warning: duplicate proto file reference, replacing "
+ "framework entry for '"
+ << std::string(proto_file) << "' with '" << std::string(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: '"
+ << std::string(proto_file) << "'" << std::endl;
+ std::cerr.flush();
+ }
+
+ (*map_)[std::string(proto_file)] = std::string(framework_name);
+ }
+
+ start = offset + 1;
+ }
+
+ return true;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h
new file mode 100644
index 00000000..e6a3e436
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -0,0 +1,347 @@
+// 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 <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/zero_copy_stream.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// 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
+// `UseProtoPackageAsDefaultPrefixUseProtoPackageAsDefaultPrefix()` is `true`.
+// And empty string means there should be no exceptions loaded.
+std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList();
+void PROTOC_EXPORT SetProtoPackagePrefixExceptionList(
+ const std::string& file_path);
+
+// Generator options (see objectivec_generator.cc for a description of each):
+struct Options {
+ Options();
+ std::string expected_prefixes_path;
+ std::vector<std::string> expected_prefixes_suppressions;
+ std::string generate_for_named_framework;
+ std::string named_framework_to_proto_path_mappings_path;
+ std::string runtime_import_prefix;
+ bool prefixes_must_be_registered;
+ bool require_prefixes;
+};
+
+// Escape C++ trigraphs by escaping question marks to "\?".
+std::string PROTOC_EXPORT EscapeTrigraphs(const std::string& 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 std::string& name);
+
+// Returns true if the name starts with "init" and will need to have special
+// handling under ARC.
+bool PROTOC_EXPORT IsInitName(const std::string& name);
+
+// Gets the objc_class_prefix or the prefix made from the proto package.
+std::string 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.
+std::string PROTOC_EXPORT FilePath(const FileDescriptor* file);
+
+// Just like FilePath(), but without the directory part.
+std::string 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
+std::string PROTOC_EXPORT FileClassName(const FileDescriptor* file);
+
+// These return the fully-qualified class name corresponding to the given
+// descriptor.
+std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor);
+std::string PROTOC_EXPORT ClassName(const Descriptor* descriptor,
+ std::string* out_suffix_added);
+std::string PROTOC_EXPORT EnumName(const EnumDescriptor* descriptor);
+
+// Returns the fully-qualified name of the enum value corresponding to the
+// the descriptor.
+std::string PROTOC_EXPORT EnumValueName(const EnumValueDescriptor* descriptor);
+
+// Returns the name of the enum value corresponding to the descriptor.
+std::string PROTOC_EXPORT EnumValueShortName(const EnumValueDescriptor* descriptor);
+
+// Reverse what an enum does.
+std::string PROTOC_EXPORT UnCamelCaseEnumShortName(const std::string& name);
+
+// Returns the name to use for the extension (used as the method off the file's
+// Root class).
+std::string PROTOC_EXPORT ExtensionMethodName(const FieldDescriptor* descriptor);
+
+// Returns the transformed field name.
+std::string PROTOC_EXPORT FieldName(const FieldDescriptor* field);
+std::string PROTOC_EXPORT FieldNameCapitalized(const FieldDescriptor* field);
+
+// Returns the transformed oneof name.
+std::string PROTOC_EXPORT OneofEnumName(const OneofDescriptor* descriptor);
+std::string PROTOC_EXPORT OneofName(const OneofDescriptor* descriptor);
+std::string 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.
+std::string PROTOC_EXPORT ObjCClass(const std::string& class_name);
+
+// Declares an Objective C class without initializing the class so that it can
+// be refrerred to by ObjCClass.
+std::string PROTOC_EXPORT ObjCClassDeclaration(const std::string& 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.
+std::string PROTOC_EXPORT UnCamelCaseFieldName(const std::string& 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>
+std::string 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) {
+ std::string message;
+ const FileDescriptor* sourceFile = descriptor->file();
+ if (isFileLevelDeprecation) {
+ message = sourceFile->name() + " is deprecated.";
+ } else {
+ message = descriptor->full_name() + " is deprecated (see " +
+ sourceFile->name() + ").";
+ }
+
+ std::string result = std::string("GPB_DEPRECATED_MSG(\"") + message + "\")";
+ if (preSpace) {
+ result.insert(0, " ");
+ }
+ if (postNewline) {
+ result.append("\n");
+ }
+ return result;
+ } else {
+ return "";
+ }
+}
+
+std::string 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);
+
+std::string PROTOC_EXPORT
+GPBGenericValueFieldName(const FieldDescriptor* field);
+std::string PROTOC_EXPORT DefaultValue(const FieldDescriptor* field);
+bool PROTOC_EXPORT HasNonZeroDefaultValue(const FieldDescriptor* field);
+
+std::string PROTOC_EXPORT
+BuildFlagsString(const FlagType type, const std::vector<std::string>& strings);
+
+// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
+// file.
+std::string 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.
+std::string PROTOC_EXPORT
+ProtobufFrameworkImportSymbol(const std::string& framework_name);
+
+// Checks if the file is one of the proto's bundled with the library.
+bool PROTOC_EXPORT
+IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
+
+// Checks the prefix for the given files and outputs any warnings as needed. If
+// there are flat out errors, then out_error is filled in with the first error
+// and the result is false.
+bool PROTOC_EXPORT ValidateObjCClassPrefixes(
+ const std::vector<const FileDescriptor*>& files,
+ const Options& generation_options, std::string* out_error);
+
+// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
+// the input into the expected output.
+class PROTOC_EXPORT TextFormatDecodeData {
+ public:
+ TextFormatDecodeData();
+ ~TextFormatDecodeData();
+
+ TextFormatDecodeData(const TextFormatDecodeData&) = delete;
+ TextFormatDecodeData& operator=(const TextFormatDecodeData&) = delete;
+
+ void AddString(int32_t key, const std::string& input_for_decode,
+ const std::string& desired_output);
+ size_t num_entries() const { return entries_.size(); }
+ std::string Data() const;
+
+ static std::string DecodeDataForString(const std::string& input_for_decode,
+ const std::string& desired_output);
+
+ private:
+ typedef std::pair<int32_t, std::string> DataEntry;
+ std::vector<DataEntry> entries_;
+};
+
+// Helper for parsing simple files.
+class PROTOC_EXPORT LineConsumer {
+ public:
+ LineConsumer();
+ virtual ~LineConsumer();
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) = 0;
+};
+
+bool PROTOC_EXPORT ParseSimpleFile(const std::string& path,
+ LineConsumer* line_consumer,
+ std::string* out_error);
+
+bool PROTOC_EXPORT ParseSimpleStream(io::ZeroCopyInputStream& input_stream,
+ const std::string& stream_name,
+ LineConsumer* line_consumer,
+ std::string* out_error);
+
+// Helper class for parsing framework import mappings and generating
+// import statements.
+class PROTOC_EXPORT ImportWriter {
+ public:
+ ImportWriter(const std::string& generate_for_named_framework,
+ const std::string& named_framework_to_proto_path_mappings_path,
+ const std::string& runtime_import_prefix,
+ bool include_wkt_imports);
+ ~ImportWriter();
+
+ void AddFile(const FileDescriptor* file, const std::string& header_extension);
+ void Print(io::Printer* printer) const;
+
+ static void PrintRuntimeImports(io::Printer* printer,
+ const std::vector<std::string>& header_to_import,
+ const std::string& runtime_import_prefix,
+ bool default_cpp_symbol = false);
+
+ private:
+ class ProtoFrameworkCollector : public LineConsumer {
+ public:
+ ProtoFrameworkCollector(std::map<std::string, std::string>* inout_proto_file_to_framework_name)
+ : map_(inout_proto_file_to_framework_name) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override;
+
+ private:
+ std::map<std::string, std::string>* map_;
+ };
+
+ void ParseFrameworkMappings();
+
+ const std::string generate_for_named_framework_;
+ const std::string named_framework_to_proto_path_mappings_path_;
+ const std::string runtime_import_prefix_;
+ const bool include_wkt_imports_;
+ std::map<std::string, std::string> proto_file_to_framework_name_;
+ bool need_to_parse_mapping_file_;
+
+ std::vector<std::string> protobuf_imports_;
+ std::vector<std::string> other_framework_imports_;
+ std::vector<std::string> other_imports_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
new file mode 100644
index 00000000..85f150b9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
@@ -0,0 +1,385 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2014 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 <compiler/objectivec/objectivec_helpers.h>
+#include <io/zero_copy_stream_impl_lite.h>
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+namespace {
+
+TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_RawStrings) {
+ std::string input_for_decode("abcdefghIJ");
+ std::string desired_output_for_decode;
+ std::string expected;
+ std::string result;
+
+ // Different data, can't transform.
+
+ desired_output_for_decode = "zbcdefghIJ";
+ expected = std::string("\0zbcdefghIJ\0", 12);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "abcdezghIJ";
+ expected = std::string("\0abcdezghIJ\0", 12);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Shortened data, can't transform.
+
+ desired_output_for_decode = "abcdefghI";
+ expected = std::string("\0abcdefghI\0", 11);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Extra data, can't transform.
+
+ desired_output_for_decode = "abcdefghIJz";
+ expected = std::string("\0abcdefghIJz\0", 13);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+}
+
+TEST(ObjCHelper, TextFormatDecodeData_DecodeDataForString_ByteCodes) {
+ std::string input_for_decode("abcdefghIJ");
+ std::string desired_output_for_decode;
+ std::string expected;
+ std::string result;
+
+ desired_output_for_decode = "abcdefghIJ";
+ expected = std::string("\x0A\x0", 2);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "_AbcdefghIJ";
+ expected = std::string("\xCA\x0", 2);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ desired_output_for_decode = "ABCD__EfghI_j";
+ expected = std::string("\x64\x80\xC5\xA1\x0", 5);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+
+ // Long name so multiple decode ops are needed.
+
+ input_for_decode =
+ "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000";
+ desired_output_for_decode =
+ "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000";
+ expected = std::string("\x04\xA5\xA4\xA2\xBF\x1F\x0E\x84\x0", 9);
+ result = TextFormatDecodeData::DecodeDataForString(input_for_decode,
+ desired_output_for_decode);
+ EXPECT_EQ(expected, result);
+}
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(ObjCHelperDeathTest, TextFormatDecodeData_DecodeDataForString_Failures) {
+ // Empty inputs.
+
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("a", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(TextFormatDecodeData::DecodeDataForString("", "a"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+
+ // Null char in the string.
+
+ std::string str_with_null_char("ab\0c", 4);
+ EXPECT_EXIT(
+ TextFormatDecodeData::DecodeDataForString(str_with_null_char, "def"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+ EXPECT_EXIT(
+ TextFormatDecodeData::DecodeDataForString("def", str_with_null_char),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(ObjCHelper, TextFormatDecodeData_RawStrings) {
+ TextFormatDecodeData decode_data;
+
+ // Different data, can't transform.
+ decode_data.AddString(1, "abcdefghIJ", "zbcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "abcdezghIJ");
+ // Shortened data, can't transform.
+ decode_data.AddString(2, "abcdefghIJ", "abcdefghI");
+ // Extra data, can't transform.
+ decode_data.AddString(4, "abcdefghIJ", "abcdefghIJz");
+
+ EXPECT_EQ(4, decode_data.num_entries());
+
+ uint8 expected_data[] = {
+ 0x4,
+ 0x1, 0x0, 'z', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 0x0,
+ 0x3, 0x0, 'a', 'b', 'c', 'd', 'e', 'z', 'g', 'h', 'I', 'J', 0x0,
+ 0x2, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 0x0,
+ 0x4, 0x0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'I', 'J', 'z', 0x0,
+ };
+ std::string expected((const char*)expected_data, sizeof(expected_data));
+
+ EXPECT_EQ(expected, decode_data.Data());
+}
+
+TEST(ObjCHelper, TextFormatDecodeData_ByteCodes) {
+ TextFormatDecodeData decode_data;
+
+ decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
+ decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
+ decode_data.AddString(4, "abcdefghIJ", "ABCD__EfghI_j");
+ decode_data.AddString(1000,
+ "longFieldNameIsLooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong1000",
+ "long_field_name_is_looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong_1000");
+
+ EXPECT_EQ(5, decode_data.num_entries());
+
+ uint8 expected_data[] = {
+ 0x5,
+ // All as is (00 op)
+ 0x1, 0x0A, 0x0,
+ // Underscore, upper + 9 (10 op)
+ 0x3, 0xCA, 0x0,
+ // Upper + 3 (10 op), underscore, upper + 5 (10 op)
+ 0x2, 0x44, 0xC6, 0x0,
+ // All Upper for 4 (11 op), underscore, underscore, upper + 5 (10 op),
+ // underscore, lower + 0 (01 op)
+ 0x4, 0x64, 0x80, 0xC5, 0xA1, 0x0,
+ // 2 byte key: as is + 3 (00 op), underscore, lower + 4 (01 op),
+ // underscore, lower + 3 (01 op), underscore, lower + 1 (01 op),
+ // underscore, lower + 30 (01 op), as is + 30 (00 op), as is + 13 (00
+ // op),
+ // underscore, as is + 3 (00 op)
+ 0xE8, 0x07, 0x04, 0xA5, 0xA4, 0xA2, 0xBF, 0x1F, 0x0E, 0x84, 0x0,
+ };
+ std::string expected((const char*)expected_data, sizeof(expected_data));
+
+ EXPECT_EQ(expected, decode_data.Data());
+}
+
+
+// Death tests do not work on Windows as of yet.
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
+ TextFormatDecodeData decode_data;
+
+ // Empty inputs.
+
+ EXPECT_EXIT(decode_data.AddString(1, "", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(decode_data.AddString(1, "a", ""),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+ EXPECT_EXIT(decode_data.AddString(1, "", "a"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got empty string for making TextFormat data, input:");
+
+ // Null char in the string.
+
+ std::string str_with_null_char("ab\0c", 4);
+ EXPECT_EXIT(
+ decode_data.AddString(1, str_with_null_char, "def"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+ EXPECT_EXIT(
+ decode_data.AddString(1, "def", str_with_null_char),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: got a null char in a string for making TextFormat data, input:");
+
+ // Duplicate keys
+
+ decode_data.AddString(1, "abcdefghIJ", "abcdefghIJ");
+ decode_data.AddString(3, "abcdefghIJ", "_AbcdefghIJ");
+ decode_data.AddString(2, "abcdefghIJ", "Abcd_EfghIJ");
+ EXPECT_EXIT(decode_data.AddString(2, "xyz", "x_yz"),
+ ::testing::KilledBySignal(SIGABRT),
+ "error: duplicate key \\(2\\) making TextFormat data, input:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+class TestLineCollector : public LineConsumer {
+ public:
+ TestLineCollector(std::vector<std::string>* inout_lines,
+ const std::string* reject_line = nullptr,
+ bool skip_msg = false)
+ : lines_(inout_lines), reject_(reject_line), skip_msg_(skip_msg) {}
+
+ bool ConsumeLine(const StringPiece& line, std::string* out_error) override {
+ if (reject_ && *reject_ == line) {
+ if (!skip_msg_) {
+ *out_error = std::string("Rejected '") + *reject_ + "'";
+ }
+ return false;
+ }
+ if (lines_) {
+ lines_->emplace_back(line);
+ }
+ return true;
+ }
+
+ private:
+ std::vector<std::string>* lines_;
+ const std::string* reject_;
+ bool skip_msg_;
+};
+
+const int kBlockSizes[] = {-1, 1, 2, 5, 64};
+const int kBlockSizeCount = GOOGLE_ARRAYSIZE(kBlockSizes);
+
+TEST(ObjCHelper, ParseSimple_BasicsSuccess) {
+ const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+ {"", {}},
+ {"a", {"a"}},
+ {"a c", {"a c"}},
+ {" a c ", {"a c"}},
+ {"\ta c ", {"a c"}},
+ {"abc\n", {"abc"}},
+ {"abc\nd f", {"abc", "d f"}},
+ {"\n abc \n def \n\n", {"abc", "def"}},
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+ std::string err_str;
+ std::vector<std::string> lines;
+ TestLineCollector collector(&lines);
+ EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ EXPECT_EQ(lines, test.second);
+ EXPECT_TRUE(err_str.empty());
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_DropsComments) {
+ const std::vector<std::pair<std::string, std::vector<std::string>>> tests = {
+ {"# nothing", {}},
+ {"#", {}},
+ {"##", {}},
+ {"\n# nothing\n", {}},
+ {"a # same line", {"a"}},
+ {"a # same line\n", {"a"}},
+ {"a\n# line\nc", {"a", "c"}},
+ {"# n o t # h i n g #", {}},
+ {"## n o # t h i n g #", {}},
+ {"a# n o t # h i n g #", {"a"}},
+ {"a\n## n o # t h i n g #", {"a"}},
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(test.first.data(), test.first.size(), kBlockSizes[i]);
+ std::string err_str;
+ std::vector<std::string> lines;
+ TestLineCollector collector(&lines);
+ EXPECT_TRUE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ EXPECT_EQ(lines, test.second);
+ EXPECT_TRUE(err_str.empty());
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLines) {
+ const std::vector<std::tuple<std::string, std::string, int>> tests = {
+ std::make_tuple("a\nb\nc", "a", 1),
+ std::make_tuple("a\nb\nc", "b", 2),
+ std::make_tuple("a\nb\nc", "c", 3),
+ std::make_tuple("a\nb\nc\n", "c", 3),
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+ kBlockSizes[i]);
+ std::string err_str;
+ TestLineCollector collector(nullptr, &std::get<1>(test));
+ EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ std::string expected_err =
+ StrCat("error: dummy Line ", std::get<2>(test), ", Rejected '", std::get<1>(test), "'");
+ EXPECT_EQ(err_str, expected_err);
+ }
+ }
+}
+
+TEST(ObjCHelper, ParseSimple_RejectLinesNoMessage) {
+ const std::vector<std::tuple<std::string, std::string, int>> tests = {
+ std::make_tuple("a\nb\nc", "a", 1),
+ std::make_tuple("a\nb\nc", "b", 2),
+ std::make_tuple("a\nb\nc", "c", 3),
+ std::make_tuple("a\nb\nc\n", "c", 3),
+ };
+
+ for (const auto& test : tests) {
+ for (int i = 0; i < kBlockSizeCount; i++) {
+ io::ArrayInputStream input(std::get<0>(test).data(), std::get<0>(test).size(),
+ kBlockSizes[i]);
+ std::string err_str;
+ TestLineCollector collector(nullptr, &std::get<1>(test), true /* skip msg */);
+ EXPECT_FALSE(ParseSimpleStream(input, "dummy", &collector, &err_str));
+ std::string expected_err =
+ StrCat("error: dummy Line ", std::get<2>(test),
+ ", ConsumeLine failed without setting an error.");
+ EXPECT_EQ(err_str, expected_err);
+ }
+ }
+}
+
+// TODO(thomasvl): Should probably add some unittests for all the special cases
+// of name mangling (class name, field name, enum names). Rather than doing
+// this with an ObjC test in the objectivec directory, we should be able to
+// use src/google/protobuf/compiler/importer* (like other tests) to support a
+// virtual file system to feed in protos, once we have the Descriptor tree, the
+// tests could use the helper methods for generating names and validate the
+// right things are happening.
+
+} // namespace
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc
new file mode 100644
index 00000000..58681ae4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -0,0 +1,189 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_map_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+// MapFieldGenerator uses RepeatedFieldGenerator as the parent because it
+// provides a bunch of things (no has* methods, comments for contained type,
+// etc.).
+
+namespace {
+
+const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "Int32";
+ case OBJECTIVECTYPE_UINT32:
+ return "UInt32";
+ case OBJECTIVECTYPE_INT64:
+ return "Int64";
+ case OBJECTIVECTYPE_UINT64:
+ return "UInt64";
+ case OBJECTIVECTYPE_FLOAT:
+ return "Float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "Double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "Bool";
+ case OBJECTIVECTYPE_STRING:
+ return (isKey ? "String" : "Object");
+ case OBJECTIVECTYPE_DATA:
+ return "Object";
+ case OBJECTIVECTYPE_ENUM:
+ return "Enum";
+ case OBJECTIVECTYPE_MESSAGE:
+ return "Object";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+} // namespace
+
+MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ const FieldDescriptor* key_descriptor =
+ descriptor->message_type()->map_key();
+ const FieldDescriptor* value_descriptor =
+ descriptor->message_type()->map_value();
+ value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options));
+
+ // Pull over some variables_ from the value.
+ variables_["field_type"] = value_field_generator_->variable("field_type");
+ variables_["default"] = value_field_generator_->variable("default");
+ variables_["default_name"] = value_field_generator_->variable("default_name");
+
+ // Build custom field flags.
+ std::vector<std::string> field_flags;
+ field_flags.push_back("GPBFieldMapKey" + GetCapitalizedType(key_descriptor));
+ // Pull over the current text format custom name values that was calculated.
+ if (variables_["fieldflags"].find("GPBFieldTextFormatNameCustom") !=
+ std::string::npos) {
+ field_flags.push_back("GPBFieldTextFormatNameCustom");
+ }
+ // Pull over some info from the value's flags.
+ const std::string& value_field_flags =
+ value_field_generator_->variable("fieldflags");
+ if (value_field_flags.find("GPBFieldHasDefaultValue") != std::string::npos) {
+ field_flags.push_back("GPBFieldHasDefaultValue");
+ }
+ if (value_field_flags.find("GPBFieldHasEnumDescriptor") !=
+ std::string::npos) {
+ field_flags.push_back("GPBFieldHasEnumDescriptor");
+ }
+
+ variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
+
+ ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
+ const bool value_is_object_type =
+ ((value_objc_type == OBJECTIVECTYPE_STRING) ||
+ (value_objc_type == OBJECTIVECTYPE_DATA) ||
+ (value_objc_type == OBJECTIVECTYPE_MESSAGE));
+ if ((GetObjectiveCType(key_descriptor) == OBJECTIVECTYPE_STRING) &&
+ value_is_object_type) {
+ variables_["array_storage_type"] = "NSMutableDictionary";
+ variables_["array_property_type"] =
+ "NSMutableDictionary<NSString*, " +
+ value_field_generator_->variable("storage_type") + "*>";
+ } else {
+ std::string class_name("GPB");
+ class_name += MapEntryTypeName(key_descriptor, true);
+ class_name += MapEntryTypeName(value_descriptor, false);
+ class_name += "Dictionary";
+ variables_["array_storage_type"] = class_name;
+ if (value_is_object_type) {
+ variables_["array_property_type"] =
+ class_name + "<" +
+ value_field_generator_->variable("storage_type") + "*>";
+ }
+ }
+
+ variables_["dataTypeSpecific_name"] =
+ value_field_generator_->variable("dataTypeSpecific_name");
+ variables_["dataTypeSpecific_value"] =
+ value_field_generator_->variable("dataTypeSpecific_value");
+}
+
+MapFieldGenerator::~MapFieldGenerator() {}
+
+void MapFieldGenerator::FinishInitialization(void) {
+ RepeatedFieldGenerator::FinishInitialization();
+ // Use the array_comment support in RepeatedFieldGenerator to output what the
+ // values in the map are.
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_ENUM) {
+ variables_["array_comment"] =
+ "// |" + variables_["name"] + "| values are |" + value_field_generator_->variable("storage_type") + "|\n";
+ }
+}
+
+void MapFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
+ const std::string& value_storage_type =
+ value_field_generator_->variable("storage_type");
+ fwd_decls->insert("@class " + value_storage_type);
+ }
+}
+
+void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ // Class name is already in "storage_type".
+ const FieldDescriptor* value_descriptor =
+ descriptor_->message_type()->FindFieldByName("value");
+ if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
+ fwd_decls->insert(ObjCClassDeclaration(
+ value_field_generator_->variable("storage_type")));
+ }
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h
new file mode 100644
index 00000000..32371123
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_map_field.h
@@ -0,0 +1,71 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2015 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class MapFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ public:
+ virtual void FinishInitialization(void) override;
+
+ MapFieldGenerator(const MapFieldGenerator&) = delete;
+ MapFieldGenerator& operator=(const MapFieldGenerator&) = delete;
+
+ protected:
+ MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options);
+ virtual ~MapFieldGenerator();
+
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+
+ private:
+ std::unique_ptr<FieldGenerator> value_field_generator_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MAP_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc
new file mode 100644
index 00000000..0e8bfec9
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.cc
@@ -0,0 +1,636 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+
+#include <compiler/objectivec/objectivec_message.h>
+#include <compiler/objectivec/objectivec_enum.h>
+#include <compiler/objectivec/objectivec_extension.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <stubs/stl_util.h>
+#include <stubs/strutil.h>
+#include <io/printer.h>
+#include <io/coded_stream.h>
+#include <io/zero_copy_stream_impl.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+#include <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 std::string& root_classname,
+ const Descriptor* descriptor,
+ const Options& options)
+ : root_classname_(root_classname),
+ descriptor_(descriptor),
+ field_generators_(descriptor, options),
+ class_name_(ClassName(descriptor_)),
+ deprecated_attribute_(GetOptionalDeprecatedAttribute(
+ descriptor, descriptor->file(), false, true)) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_.emplace_back(
+ new ExtensionGenerator(class_name_, descriptor_->extension(i)));
+ }
+
+ for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
+ OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
+ oneof_generators_.emplace_back(generator);
+ }
+
+ for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+ EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
+ enum_generators_.emplace_back(generator);
+ }
+
+ for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+ MessageGenerator* generator =
+ new MessageGenerator(root_classname_,
+ descriptor_->nested_type(i),
+ options);
+ nested_message_generators_.emplace_back(generator);
+ }
+}
+
+MessageGenerator::~MessageGenerator() {}
+
+void MessageGenerator::GenerateStaticVariablesInitialization(
+ io::Printer* printer) {
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateStaticVariablesInitialization(printer);
+ }
+}
+
+void MessageGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) {
+ if (!IsMapEntryMessage(descriptor_)) {
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+ field_generators_.get(fieldDescriptor)
+ .DetermineForwardDeclarations(fwd_decls);
+ }
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->DetermineForwardDeclarations(fwd_decls);
+ }
+}
+
+void MessageGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* 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) {
+ std::string 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);
+ }
+
+ std::string message_comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ message_comments = BuildCommentsString(location, false);
+ } else {
+ message_comments = "";
+ }
+
+ printer->Print(
+ "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n",
+ "classname", class_name_,
+ "deprecated_attribute", deprecated_attribute_,
+ "comments", message_comments);
+
+ std::vector<char> seen_oneofs(oneof_generators_.size(), 0);
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ const OneofDescriptor* oneof = field->real_containing_oneof();
+ if (oneof) {
+ const int oneof_index = oneof->index();
+ if (!seen_oneofs[oneof_index]) {
+ seen_oneofs[oneof_index] = 1;
+ oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
+ printer);
+ }
+ }
+ field_generators_.get(field).GeneratePropertyDeclaration(printer);
+ }
+
+ printer->Print("@end\n\n");
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateCFunctionDeclarations(printer);
+ }
+
+ if (!oneof_generators_.empty()) {
+ for (const auto& generator : oneof_generators_) {
+ generator->GenerateClearFunctionDeclaration(printer);
+ }
+ printer->Print("\n");
+ }
+
+ if (descriptor_->extension_count() > 0) {
+ printer->Print("@interface $classname$ (DynamicMethods)\n\n",
+ "classname", class_name_);
+ for (const auto& generator : extension_generators_) {
+ generator->GenerateMembersHeader(printer);
+ }
+ printer->Print("@end\n\n");
+ }
+
+ for (const auto& generator : nested_message_generators_) {
+ generator->GenerateMessageHeader(printer);
+ }
+}
+
+void MessageGenerator::GenerateSource(io::Printer* printer) {
+ if (!IsMapEntryMessage(descriptor_)) {
+ printer->Print(
+ "#pragma mark - $classname$\n"
+ "\n",
+ "classname", class_name_);
+
+ if (!deprecated_attribute_.empty()) {
+ // No warnings when compiling the impl of this deprecated class.
+ printer->Print(
+ "#pragma clang diagnostic push\n"
+ "#pragma clang diagnostic ignored \"-Wdeprecated-implementations\"\n"
+ "\n");
+ }
+
+ printer->Print("@implementation $classname$\n\n",
+ "classname", class_name_);
+
+ for (const auto& generator : oneof_generators_) {
+ generator->GeneratePropertyImplementation(printer);
+ }
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GeneratePropertyImplementation(printer);
+ }
+
+ std::unique_ptr<const FieldDescriptor*[]> sorted_fields(
+ SortFieldsByNumber(descriptor_));
+ std::unique_ptr<const FieldDescriptor*[]> size_order_fields(
+ SortFieldsByStorageSize(descriptor_));
+
+ std::vector<const Descriptor::ExtensionRange*> sorted_extensions;
+ sorted_extensions.reserve(descriptor_->extension_range_count());
+ for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
+ sorted_extensions.push_back(descriptor_->extension_range(i));
+ }
+
+ std::sort(sorted_extensions.begin(), sorted_extensions.end(),
+ ExtensionRangeOrdering());
+
+ // Assign has bits:
+ // 1. FieldGeneratorMap::CalculateHasBits() loops through the fields seeing
+ // who needs has bits and assigning them.
+ // 2. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
+ // index that groups all the elements in the oneof.
+ size_t num_has_bits = field_generators_.CalculateHasBits();
+ size_t sizeof_has_storage = (num_has_bits + 31) / 32;
+ if (sizeof_has_storage == 0) {
+ // In the case where no field needs has bits, don't let the _has_storage_
+ // end up as zero length (zero length arrays are sort of a grey area
+ // since it has to be at the start of the struct). This also ensures a
+ // field with only oneofs keeps the required negative indices they need.
+ sizeof_has_storage = 1;
+ }
+ // Tell all the fields the oneof base.
+ for (const auto& generator : oneof_generators_) {
+ generator->SetOneofIndexBase(sizeof_has_storage);
+ }
+ field_generators_.SetOneofIndexBase(sizeof_has_storage);
+ // sizeof_has_storage needs enough bits for the single fields that aren't in
+ // any oneof, and then one int32 for each oneof (to store the field number).
+ sizeof_has_storage += oneof_generators_.size();
+
+ printer->Print(
+ "\n"
+ "typedef struct $classname$__storage_ {\n"
+ " uint32_t _has_storage_[$sizeof_has_storage$];\n",
+ "classname", class_name_,
+ "sizeof_has_storage", StrCat(sizeof_has_storage));
+ printer->Indent();
+
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(size_order_fields[i])
+ .GenerateFieldStorageDeclaration(printer);
+ }
+ printer->Outdent();
+
+ printer->Print("} $classname$__storage_;\n\n", "classname", class_name_);
+
+
+ printer->Print(
+ "// This method is threadsafe because it is initially called\n"
+ "// in +initialize for each subclass.\n"
+ "+ (GPBDescriptor *)descriptor {\n"
+ " static GPBDescriptor *descriptor = nil;\n"
+ " if (!descriptor) {\n");
+
+ TextFormatDecodeData text_format_decode_data;
+ bool has_fields = descriptor_->field_count() > 0;
+ bool need_defaults = field_generators_.DoesAnyFieldHaveNonZeroDefault();
+ std::string 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<std::string, std::string> vars;
+ vars["classname"] = class_name_;
+ vars["rootclassname"] = root_classname_;
+ vars["fields"] = has_fields ? "fields" : "NULL";
+ if (has_fields) {
+ vars["fields_count"] =
+ "(uint32_t)(sizeof(fields) / sizeof(" + field_description_type + "))";
+ } else {
+ vars["fields_count"] = "0";
+ }
+
+ std::vector<std::string> init_flags;
+ init_flags.push_back("GPBDescriptorInitializationFlag_UsesClassRefs");
+ init_flags.push_back("GPBDescriptorInitializationFlag_Proto3OptionalKnown");
+ if (need_defaults) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_FieldsWithDefault");
+ }
+ if (descriptor_->options().message_set_wire_format()) {
+ init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
+ }
+ vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION,
+ init_flags);
+
+ printer->Print(
+ vars,
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+ " rootClass:[$rootclassname$ class]\n"
+ " file:$rootclassname$_FileDescriptor()\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " flags:$init_flags$];\n");
+ if (!oneof_generators_.empty()) {
+ printer->Print(
+ " static const char *oneofs[] = {\n");
+ for (const auto& generator : oneof_generators_) {
+ printer->Print(" \"$name$\",\n", "name",
+ generator->DescriptorName());
+ }
+ printer->Print(
+ " };\n"
+ " [localDescriptor setupOneofs:oneofs\n"
+ " count:(uint32_t)(sizeof(oneofs) / sizeof(char*))\n"
+ " firstHasIndex:$first_has_index$];\n",
+ "first_has_index", oneof_generators_[0]->HasIndexAsString());
+ }
+ if (text_format_decode_data.num_entries() != 0) {
+ const std::string text_format_data_str(text_format_decode_data.Data());
+ printer->Print(
+ "#if !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
+ " static const char *extraTextFormatInfo =");
+ static const int kBytesPerLine = 40; // allow for escaping
+ for (int i = 0; i < text_format_data_str.size(); i += kBytesPerLine) {
+ printer->Print(
+ "\n \"$data$\"",
+ "data", EscapeTrigraphs(
+ CEscape(text_format_data_str.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ";\n"
+ " [localDescriptor setupExtraTextInfo:extraTextFormatInfo];\n"
+ "#endif // !GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n");
+ }
+ if (!sorted_extensions.empty()) {
+ printer->Print(
+ " static const GPBExtensionRange ranges[] = {\n");
+ for (int i = 0; i < sorted_extensions.size(); i++) {
+ printer->Print(" { .start = $start$, .end = $end$ },\n",
+ "start", StrCat(sorted_extensions[i]->start),
+ "end", StrCat(sorted_extensions[i]->end));
+ }
+ printer->Print(
+ " };\n"
+ " [localDescriptor setupExtensionRanges:ranges\n"
+ " count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
+ }
+ if (descriptor_->containing_type() != NULL) {
+ std::string containing_class = ClassName(descriptor_->containing_type());
+ std::string parent_class_ref = ObjCClass(containing_class);
+ printer->Print(
+ " [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
+ "parent_class_ref", parent_class_ref);
+ }
+ std::string 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/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h
new file mode 100644
index 00000000..64c7b49f
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <compiler/objectivec/objectivec_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_oneof.h>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class ExtensionGenerator;
+class EnumGenerator;
+
+class MessageGenerator {
+ public:
+ MessageGenerator(const std::string& root_classname,
+ const Descriptor* descriptor, const Options& options);
+ ~MessageGenerator();
+
+ MessageGenerator(const MessageGenerator&) = delete;
+ MessageGenerator& operator=(const MessageGenerator&) = delete;
+
+ void GenerateStaticVariablesInitialization(io::Printer* printer);
+ void GenerateEnumHeader(io::Printer* printer);
+ void GenerateMessageHeader(io::Printer* printer);
+ void GenerateSource(io::Printer* printer);
+ void GenerateExtensionRegistrationSource(io::Printer* printer);
+ void DetermineObjectiveCClassDefinitions(std::set<std::string>* fwd_decls);
+ void DetermineForwardDeclarations(std::set<std::string>* fwd_decls);
+
+ // Checks if the message or a nested message includes a oneof definition.
+ bool IncludesOneOfDefinition() const;
+
+ private:
+ void GenerateParseFromMethodsHeader(io::Printer* printer);
+
+ void GenerateSerializeOneFieldSource(io::Printer* printer,
+ const FieldDescriptor* field);
+ void GenerateSerializeOneExtensionRangeSource(
+ io::Printer* printer, const Descriptor::ExtensionRange* range);
+
+ void GenerateMessageDescriptionSource(io::Printer* printer);
+ void GenerateDescriptionOneFieldSource(io::Printer* printer,
+ const FieldDescriptor* field);
+
+ const std::string root_classname_;
+ const Descriptor* descriptor_;
+ FieldGeneratorMap field_generators_;
+ const std::string class_name_;
+ const std::string deprecated_attribute_;
+ std::vector<std::unique_ptr<ExtensionGenerator>> extension_generators_;
+ std::vector<std::unique_ptr<EnumGenerator>> enum_generators_;
+ std::vector<std::unique_ptr<MessageGenerator>> nested_message_generators_;
+ std::vector<std::unique_ptr<OneofGenerator>> oneof_generators_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc
new file mode 100644
index 00000000..241ae0fa
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -0,0 +1,107 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_message_field.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <wire_format.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+namespace {
+
+void SetMessageVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ const std::string& message_type = ClassName(descriptor->message_type());
+ const std::string& containing_class =
+ ClassName(descriptor->containing_type());
+ (*variables)["type"] = message_type;
+ (*variables)["containing_class"] = containing_class;
+ (*variables)["storage_type"] = message_type;
+ (*variables)["group_or_message"] =
+ (descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
+ (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type);
+}
+
+} // namespace
+
+MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ SetMessageVariables(descriptor, &variables_);
+}
+
+MessageFieldGenerator::~MessageFieldGenerator() {}
+
+void MessageFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ ObjCObjFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // Class name is already in "storage_type".
+ fwd_decls->insert("@class " + variable("storage_type"));
+}
+
+void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
+}
+
+RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetMessageVariables(descriptor, &variables_);
+ variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
+}
+
+RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
+
+void RepeatedMessageFieldGenerator::DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const {
+ RepeatedFieldGenerator::DetermineForwardDeclarations(fwd_decls);
+ // Class name is already in "storage_type".
+ fwd_decls->insert("@class " + variable("storage_type"));
+}
+
+void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const {
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h
new file mode 100644
index 00000000..7ea99c37
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_message_field.h
@@ -0,0 +1,87 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class MessageFieldGenerator : public ObjCObjFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ MessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+
+ MessageFieldGenerator(const MessageFieldGenerator&) = delete;
+ MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete;
+
+ virtual ~MessageFieldGenerator();
+
+ public:
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+};
+
+class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedMessageFieldGenerator();
+
+ RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete;
+ RepeatedMessageFieldGenerator operator=(const RepeatedMessageFieldGenerator&) = delete;
+
+ public:
+ virtual void DetermineForwardDeclarations(
+ std::set<std::string>* fwd_decls) const override;
+ virtual void DetermineObjectiveCClassDefinitions(
+ std::set<std::string>* fwd_decls) const override;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_MESSAGE_FIELD_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
new file mode 100644
index 00000000..16330466
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_nsobject_methods.h
@@ -0,0 +1,197 @@
+// NSObject methods
+// Autogenerated by method_dump.sh. Do not edit by hand.
+// Date: Thu Nov 1 14:12:16 PDT 2018
+// macOS: MacOSX10.14.sdk
+// iOS: iPhoneSimulator12.1.sdk
+
+const char* const kNSObjectMethodsList[] = {
+ "CAMLType",
+ "CA_copyRenderValue",
+ "CA_prepareRenderValue",
+ "NS_copyCGImage",
+ "NS_tiledLayerVisibleRect",
+ "___tryRetain_OA",
+ "__autorelease_OA",
+ "__dealloc_zombie",
+ "__release_OA",
+ "__retain_OA",
+ "_accessibilityFinalize",
+ "_accessibilityIsTableViewDescendant",
+ "_accessibilityUIElementSpecifier",
+ "_accessibilityUseConvenienceAPI",
+ "_allowsDirectEncoding",
+ "_asScriptTerminologyNameArray",
+ "_asScriptTerminologyNameString",
+ "_bindingAdaptor",
+ "_cfTypeID",
+ "_copyDescription",
+ "_destroyObserverList",
+ "_didEndKeyValueObserving",
+ "_implicitObservationInfo",
+ "_internalAccessibilityAttributedHint",
+ "_internalAccessibilityAttributedLabel",
+ "_internalAccessibilityAttributedValue",
+ "_isAXConnector",
+ "_isAccessibilityContainerSectionCandidate",
+ "_isAccessibilityContentNavigatorSectionCandidate",
+ "_isAccessibilityContentSectionCandidate",
+ "_isAccessibilityTopLevelNavigatorSectionCandidate",
+ "_isDeallocating",
+ "_isKVOA",
+ "_isToManyChangeInformation",
+ "_ivarDescription",
+ "_localClassNameForClass",
+ "_methodDescription",
+ "_observerStorage",
+ "_overrideUseFastBlockObservers",
+ "_propertyDescription",
+ "_releaseBindingAdaptor",
+ "_scriptingCount",
+ "_scriptingCountNonrecursively",
+ "_scriptingDebugDescription",
+ "_scriptingExists",
+ "_scriptingShouldCheckObjectIndexes",
+ "_shortMethodDescription",
+ "_shouldSearchChildrenForSection",
+ "_traitStorageList",
+ "_tryRetain",
+ "_ui_descriptionBuilder",
+ "_uikit_variesByTraitCollections",
+ "_web_description",
+ "_webkit_invokeOnMainThread",
+ "_willBeginKeyValueObserving",
+ "accessibilityActivate",
+ "accessibilityActivationPoint",
+ "accessibilityAllowsOverriddenAttributesWhenIgnored",
+ "accessibilityAssistiveTechnologyFocusedIdentifiers",
+ "accessibilityAttributedHint",
+ "accessibilityAttributedLabel",
+ "accessibilityAttributedValue",
+ "accessibilityContainer",
+ "accessibilityContainerType",
+ "accessibilityCustomActions",
+ "accessibilityCustomRotors",
+ "accessibilityDecrement",
+ "accessibilityDragSourceDescriptors",
+ "accessibilityDropPointDescriptors",
+ "accessibilityElementCount",
+ "accessibilityElementDidBecomeFocused",
+ "accessibilityElementDidLoseFocus",
+ "accessibilityElementIsFocused",
+ "accessibilityElements",
+ "accessibilityElementsHidden",
+ "accessibilityFrame",
+ "accessibilityHeaderElements",
+ "accessibilityHint",
+ "accessibilityIdentification",
+ "accessibilityIdentifier",
+ "accessibilityIncrement",
+ "accessibilityLabel",
+ "accessibilityLanguage",
+ "accessibilityLocalizedStringKey",
+ "accessibilityNavigationStyle",
+ "accessibilityOverriddenAttributes",
+ "accessibilityParameterizedAttributeNames",
+ "accessibilityPath",
+ "accessibilityPerformEscape",
+ "accessibilityPerformMagicTap",
+ "accessibilityPresenterProcessIdentifier",
+ "accessibilityShouldUseUniqueId",
+ "accessibilitySupportsNotifications",
+ "accessibilitySupportsOverriddenAttributes",
+ "accessibilityTemporaryChildren",
+ "accessibilityTraits",
+ "accessibilityValue",
+ "accessibilityViewIsModal",
+ "accessibilityVisibleArea",
+ "allPropertyKeys",
+ "allowsWeakReference",
+ "attributeKeys",
+ "autoContentAccessingProxy",
+ "autorelease",
+ "awakeFromNib",
+ "boolValueSafe",
+ "bs_encoded",
+ "bs_isPlistableType",
+ "bs_secureEncoded",
+ "cl_json_serializeKey",
+ "class",
+ "classCode",
+ "classDescription",
+ "classForArchiver",
+ "classForCoder",
+ "classForKeyedArchiver",
+ "classForPortCoder",
+ "className",
+ "clearProperties",
+ "copy",
+ "dealloc",
+ "debugDescription",
+ "defaultAccessibilityTraits",
+ "description",
+ "doubleValueSafe",
+ "entityName",
+ "exposedBindings",
+ "finalize",
+ "finishObserving",
+ "flushKeyBindings",
+ "hash",
+ "init",
+ "int64ValueSafe",
+ "isAccessibilityElement",
+ "isAccessibilityElementByDefault",
+ "isElementAccessibilityExposedToInterfaceBuilder",
+ "isFault",
+ "isNSArray__",
+ "isNSCFConstantString__",
+ "isNSData__",
+ "isNSDate__",
+ "isNSDictionary__",
+ "isNSNumber__",
+ "isNSObject__",
+ "isNSOrderedSet__",
+ "isNSSet__",
+ "isNSString__",
+ "isNSTimeZone__",
+ "isNSValue__",
+ "isProxy",
+ "mutableCopy",
+ "nilValueForKey",
+ "objectSpecifier",
+ "observationInfo",
+ "pep_onDetachedThread",
+ "pep_onMainThread",
+ "pep_onMainThreadIfNecessary",
+ "prepareForInterfaceBuilder",
+ "release",
+ "releaseOnMainThread",
+ "retain",
+ "retainCount",
+ "retainWeakReference",
+ "scriptingProperties",
+ "self",
+ "shouldGroupAccessibilityChildren",
+ "storedAccessibilityActivationPoint",
+ "storedAccessibilityContainerType",
+ "storedAccessibilityElementsHidden",
+ "storedAccessibilityFrame",
+ "storedAccessibilityNavigationStyle",
+ "storedAccessibilityTraits",
+ "storedAccessibilityViewIsModal",
+ "storedIsAccessibilityElement",
+ "storedShouldGroupAccessibilityChildren",
+ "stringValueSafe",
+ "superclass",
+ "toManyRelationshipKeys",
+ "toOneRelationshipKeys",
+ "traitStorageList",
+ "un_safeBoolValue",
+ "userInterfaceItemIdentifier",
+ "utf8ValueSafe",
+ "valuesForKeysWithDictionary",
+ "zone",
+// Protocol: CAAnimatableValue
+// Protocol: CARenderValue
+// Protocol: NSObject
+// Protocol: ROCKRemoteInvocationInterface
+};
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc
new file mode 100644
index 00000000..de00a1f4
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.cc
@@ -0,0 +1,140 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_oneof.h>
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
+ : descriptor_(descriptor) {
+ variables_["enum_name"] = OneofEnumName(descriptor_);
+ variables_["name"] = OneofName(descriptor_);
+ variables_["capitalized_name"] = OneofNameCapitalized(descriptor_);
+ variables_["raw_index"] = StrCat(descriptor_->index());
+ const Descriptor* msg_descriptor = descriptor_->containing_type();
+ variables_["owning_message_class"] = ClassName(msg_descriptor);
+
+ std::string comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ comments = BuildCommentsString(location, true);
+ } else {
+ comments = "";
+ }
+ variables_["comments"] = comments;
+}
+
+OneofGenerator::~OneofGenerator() {}
+
+void OneofGenerator::SetOneofIndexBase(int index_base) {
+ int index = descriptor_->index() + index_base;
+ // Flip the sign to mark it as a oneof.
+ variables_["index"] = StrCat(-index);
+}
+
+void OneofGenerator::GenerateCaseEnum(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "typedef GPB_ENUM($enum_name$) {\n");
+ printer->Indent();
+ printer->Print(
+ variables_,
+ "$enum_name$_GPBUnsetOneOfCase = 0,\n");
+ std::string enum_name = variables_["enum_name"];
+ for (int j = 0; j < descriptor_->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->field(j);
+ std::string field_name = FieldNameCapitalized(field);
+ printer->Print(
+ "$enum_name$_$field_name$ = $field_number$,\n",
+ "enum_name", enum_name,
+ "field_name", field_name,
+ "field_number", StrCat(field->number()));
+ }
+ printer->Outdent();
+ printer->Print(
+ "};\n"
+ "\n");
+}
+
+void OneofGenerator::GeneratePublicCasePropertyDeclaration(
+ io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "$comments$"
+ "@property(nonatomic, readonly) $enum_name$ $name$OneOfCase;\n"
+ "\n");
+}
+
+void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "/**\n"
+ " * Clears whatever value was set for the oneof '$name$'.\n"
+ " **/\n"
+ "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
+}
+
+void OneofGenerator::GeneratePropertyImplementation(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "@dynamic $name$OneOfCase;\n");
+}
+
+void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
+ printer->Print(
+ variables_,
+ "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
+ " GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
+ " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
+ " GPBClearOneof(message, oneof);\n"
+ "}\n");
+}
+
+std::string OneofGenerator::DescriptorName(void) const {
+ return variables_.find("name")->second;
+}
+
+std::string OneofGenerator::HasIndexAsString(void) const {
+ return variables_.find("index")->second;
+}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h
new file mode 100644
index 00000000..3d59f4ff
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_oneof.h
@@ -0,0 +1,76 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
+
+#include <string>
+#include <set>
+#include <vector>
+#include <descriptor.h>
+#include <io/printer.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class OneofGenerator {
+ public:
+ explicit OneofGenerator(const OneofDescriptor* descriptor);
+ ~OneofGenerator();
+
+ OneofGenerator(const OneofGenerator&) = delete;
+ OneofGenerator& operator=(const OneofGenerator&) = delete;
+
+ void SetOneofIndexBase(int index_base);
+
+ void GenerateCaseEnum(io::Printer* printer);
+
+ void GeneratePublicCasePropertyDeclaration(io::Printer* printer);
+ void GenerateClearFunctionDeclaration(io::Printer* printer);
+
+ void GeneratePropertyImplementation(io::Printer* printer);
+ void GenerateClearFunctionImplementation(io::Printer* printer);
+
+ std::string DescriptorName(void) const;
+ std::string HasIndexAsString(void) const;
+
+ private:
+ const OneofDescriptor* descriptor_;
+ std::map<std::string, std::string> variables_;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_ONEOF_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc
new file mode 100644
index 00000000..7b5eec0c
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.cc
@@ -0,0 +1,190 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <map>
+#include <string>
+
+#include <compiler/objectivec/objectivec_helpers.h>
+#include <compiler/objectivec/objectivec_primitive_field.h>
+#include <io/printer.h>
+#include <stubs/strutil.h>
+#include <wire_format.h>
+#include <wire_format_lite.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+using internal::WireFormat;
+using internal::WireFormatLite;
+
+namespace {
+
+const char* PrimitiveTypeName(const FieldDescriptor* descriptor) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "int32_t";
+ case OBJECTIVECTYPE_UINT32:
+ return "uint32_t";
+ case OBJECTIVECTYPE_INT64:
+ return "int64_t";
+ case OBJECTIVECTYPE_UINT64:
+ return "uint64_t";
+ case OBJECTIVECTYPE_FLOAT:
+ return "float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "BOOL";
+ case OBJECTIVECTYPE_STRING:
+ return "NSString";
+ case OBJECTIVECTYPE_DATA:
+ return "NSData";
+ case OBJECTIVECTYPE_ENUM:
+ return "int32_t";
+ case OBJECTIVECTYPE_MESSAGE:
+ return NULL; // Messages go through objectivec_message_field.cc|h.
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+const char* PrimitiveArrayTypeName(const FieldDescriptor* descriptor) {
+ ObjectiveCType type = GetObjectiveCType(descriptor);
+ switch (type) {
+ case OBJECTIVECTYPE_INT32:
+ return "Int32";
+ case OBJECTIVECTYPE_UINT32:
+ return "UInt32";
+ case OBJECTIVECTYPE_INT64:
+ return "Int64";
+ case OBJECTIVECTYPE_UINT64:
+ return "UInt64";
+ case OBJECTIVECTYPE_FLOAT:
+ return "Float";
+ case OBJECTIVECTYPE_DOUBLE:
+ return "Double";
+ case OBJECTIVECTYPE_BOOLEAN:
+ return "Bool";
+ case OBJECTIVECTYPE_STRING:
+ return ""; // Want NSArray
+ case OBJECTIVECTYPE_DATA:
+ return ""; // Want NSArray
+ case OBJECTIVECTYPE_ENUM:
+ return "Enum";
+ case OBJECTIVECTYPE_MESSAGE:
+ // Want NSArray (but goes through objectivec_message_field.cc|h).
+ return "";
+ }
+
+ // Some compilers report reaching end of function even though all cases of
+ // the enum are handed in the switch.
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return NULL;
+}
+
+void SetPrimitiveVariables(const FieldDescriptor* descriptor,
+ std::map<std::string, std::string>* variables) {
+ std::string primitive_name = PrimitiveTypeName(descriptor);
+ (*variables)["type"] = primitive_name;
+ (*variables)["storage_type"] = primitive_name;
+}
+
+} // namespace
+
+PrimitiveFieldGenerator::PrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : SingleFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+}
+
+PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
+
+void PrimitiveFieldGenerator::GenerateFieldStorageDeclaration(
+ io::Printer* printer) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Nothing, BOOLs are stored in the has bits.
+ } else {
+ SingleFieldGenerator::GenerateFieldStorageDeclaration(printer);
+ }
+}
+
+int PrimitiveFieldGenerator::ExtraRuntimeHasBitsNeeded(void) const {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Reserve a bit for the storage of the boolean.
+ return 1;
+ }
+ return 0;
+}
+
+void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) {
+ if (GetObjectiveCType(descriptor_) == OBJECTIVECTYPE_BOOLEAN) {
+ // Set into the offset the has bit to use for the actual value.
+ variables_["storage_offset_value"] = StrCat(has_base);
+ variables_["storage_offset_comment"] =
+ " // Stored in _has_storage_ to save space.";
+ }
+}
+
+PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : ObjCObjFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+ variables_["property_storage_attribute"] = "copy";
+}
+
+PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {}
+
+RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
+ const FieldDescriptor* descriptor, const Options& options)
+ : RepeatedFieldGenerator(descriptor, options) {
+ SetPrimitiveVariables(descriptor, &variables_);
+
+ std::string base_name = PrimitiveArrayTypeName(descriptor);
+ if (base_name.length()) {
+ variables_["array_storage_type"] = "GPB" + base_name + "Array";
+ } else {
+ variables_["array_storage_type"] = "NSMutableArray";
+ variables_["array_property_type"] =
+ "NSMutableArray<" + variables_["storage_type"] + "*>";
+ }
+}
+
+RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h
new file mode 100644
index 00000000..88e91ba8
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/objectivec/objectivec_primitive_field.h
@@ -0,0 +1,95 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
+#define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__
+
+#include <map>
+#include <string>
+#include <compiler/objectivec/objectivec_field.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace objectivec {
+
+class PrimitiveFieldGenerator : public SingleFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ PrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~PrimitiveFieldGenerator();
+
+ PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete;
+ PrimitiveFieldGenerator& operator=(const PrimitiveFieldGenerator&) = delete;
+
+ virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const override;
+
+ virtual int ExtraRuntimeHasBitsNeeded(void) const override;
+ virtual void SetExtraRuntimeHasBitsBase(int index_base) override;
+};
+
+class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~PrimitiveObjFieldGenerator();
+
+ PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete;
+ PrimitiveObjFieldGenerator& operator=(const PrimitiveObjFieldGenerator&) =
+ delete;
+};
+
+class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator {
+ friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field,
+ const Options& options);
+
+ protected:
+ RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor,
+ const Options& options);
+ virtual ~RepeatedPrimitiveFieldGenerator();
+
+ RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) =
+ delete;
+ RepeatedPrimitiveFieldGenerator& operator=(
+ const RepeatedPrimitiveFieldGenerator&) = delete;
+};
+
+} // namespace objectivec
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_PRIMITIVE_FIELD_H__