aboutsummaryrefslogtreecommitdiff
path: root/src/google
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2015-06-17 15:03:47 +0100
committerJon Skeet <skeet@pobox.com>2015-06-17 15:03:47 +0100
commite2acd854250b449a3fdeef2ad52402c4c5d78259 (patch)
treea08126762b6c76d56fde8ce443f8dff36408b6e0 /src/google
parentd9dc05e500807a6f0cd10d4637c599acc9a6aecf (diff)
parentb36395b2bac88f70070544c325bc09234cb1f1a6 (diff)
downloadprotobuf-e2acd854250b449a3fdeef2ad52402c4c5d78259.tar.gz
protobuf-e2acd854250b449a3fdeef2ad52402c4c5d78259.tar.bz2
protobuf-e2acd854250b449a3fdeef2ad52402c4c5d78259.zip
Merged master
Diffstat (limited to 'src/google')
-rwxr-xr-xsrc/google/protobuf/arena.cc2
-rw-r--r--src/google/protobuf/arena.h3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc58
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc2
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc12
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc12
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_extension.cc39
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_extension.h6
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_field.cc91
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.cc293
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.h4
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_generator.cc4
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.cc63
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.h5
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc8
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message.cc369
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message.h11
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message_field.cc2
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc2
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc4
-rw-r--r--src/google/protobuf/descriptor.pb.cc41
-rw-r--r--src/google/protobuf/descriptor.proto1
-rw-r--r--src/google/protobuf/io/gzip_stream.cc2
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/atomicops.h1
-rw-r--r--src/google/protobuf/stubs/common.cc2
-rw-r--r--src/google/protobuf/stubs/common.h10
-rw-r--r--src/google/protobuf/stubs/common_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/pbconfig.h142
-rw-r--r--src/google/protobuf/stubs/platform_macros.h10
-rw-r--r--src/google/protobuf/testing/zcgunzip.cc2
-rw-r--r--src/google/protobuf/testing/zcgzip.cc2
32 files changed, 597 insertions, 610 deletions
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index 96009645..ed1c5ef2 100755
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -43,7 +43,7 @@ Arena::ThreadCache& Arena::thread_cache() {
static GOOGLE_THREAD_LOCAL ThreadCache thread_cache_ = { -1, NULL };
return thread_cache_;
}
-#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
+#elif defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
Arena::ThreadCache& Arena::thread_cache() {
static internal::ThreadLocalStorage<ThreadCache>* thread_cache_ =
new internal::ThreadLocalStorage<ThreadCache>();
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index 6c3f606e..51149bae 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/atomic_sequence_num.h>
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/platform_macros.h>
#include <google/protobuf/stubs/type_traits.h>
namespace google {
@@ -528,7 +529,7 @@ class LIBPROTOBUF_EXPORT Arena {
// Thread local variables cannot be exposed through DLL interface but we can
// wrap them in static functions.
static ThreadCache& thread_cache();
-#elif defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
+#elif defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
// Android ndk does not support GOOGLE_THREAD_LOCAL keyword so we use a custom thread
// local storage class we implemented.
// iOS also does not support the GOOGLE_THREAD_LOCAL keyword.
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index b997a51a..1f0a8205 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -434,20 +434,52 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
string file_data;
file_proto.SerializeToString(&file_data);
- printer->Print(
- "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
-
- // Only write 40 bytes per line.
- static const int kBytesPerLine = 40;
- for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
- printer->Print("\n \"$data$\"",
- "data",
- EscapeTrigraphs(
- CEscape(file_data.substr(i, kBytesPerLine))));
+ // Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
+ // bytes in length". Declare a static array of characters rather than use a
+ // string literal.
+ if (file_data.size() > 65535) {
+ printer->Print(
+ "static const char descriptor[] = {\n");
+ printer->Indent();
+
+ // Only write 25 bytes per line.
+ static const int kBytesPerLine = 25;
+ for (int i = 0; i < file_data.size();) {
+ for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
+ printer->Print(
+ "$char$, ",
+ "char", SimpleItoa(file_data[i]));
+ }
+ printer->Print(
+ "\n");
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "};\n");
+
+ printer->Print(
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
+ "size", SimpleItoa(file_data.size()));
+
+ } else {
+
+ printer->Print(
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
+
+ // Only write 40 bytes per line.
+ static const int kBytesPerLine = 40;
+ for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
+ printer->Print("\n \"$data$\"",
+ "data",
+ EscapeTrigraphs(
+ CEscape(file_data.substr(i, kBytesPerLine))));
+ }
+ printer->Print(
+ ", $size$);\n",
+ "size", SimpleItoa(file_data.size()));
+
}
- printer->Print(
- ", $size$);\n",
- "size", SimpleItoa(file_data.size()));
// Call MessageFactory::InternalRegisterGeneratedFile().
printer->Print(
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 212fe2e1..af85919a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -3510,7 +3510,7 @@ GenerateByteSize(io::Printer* printer) {
} else {
if (HasFieldPresence(descriptor_->file())) {
printer->Print(
- "if (_has_bits_[$index$ / 32] & $mask$) {\n",
+ "if (_has_bits_[$index$ / 32] & $mask$u) {\n",
"index", SimpleItoa(i),
"mask", SimpleItoa(mask));
printer->Indent();
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index b11fb21a..bd1c0fde 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -55,6 +55,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_optimize_for.pb.h>
#include <google/protobuf/unittest_embed_optimize_for.pb.h>
+#include <google/protobuf/unittest_enormous_descriptor.pb.h>
#include <google/protobuf/unittest_no_generic_services.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
@@ -130,6 +131,17 @@ TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
generated_decsriptor_proto.DebugString());
}
+// Test that generated code has proper descriptors:
+// Touch a descriptor generated from an enormous message to validate special
+// handling for descriptors exceeding the C++ standard's recommended minimum
+// limit for string literal size
+TEST(GeneratedDescriptorTest, EnormousDescriptor) {
+ const Descriptor* generated_descriptor =
+ TestEnormousDescriptor::descriptor();
+
+ EXPECT_TRUE(generated_descriptor != NULL);
+}
+
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
// ===================================================================
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
index d6609692..30a13ddb 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -55,8 +55,6 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
(descriptor->file() != descriptor->enum_type()->file())) {
(*variables)["property_type"] = "enum " + type;
}
- // TODO(thomasvl): Make inclusion of descriptor compile time and output
- // both of these. Note: Extensions currently have to have the EnumDescription.
(*variables)["enum_verifier"] = type + "_IsValidValue";
(*variables)["enum_desc_func"] = type + "_EnumDescriptor";
@@ -74,11 +72,9 @@ EnumFieldGenerator::~EnumFieldGenerator() {}
void EnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
io::Printer* printer) const {
- // TODO(thomasvl): Output the CPP check to use descFunc or validator based
- // on final compile.
printer->Print(
variables_,
- " .typeSpecific.enumDescFunc = $enum_desc_func$,\n");
+ " .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
}
void EnumFieldGenerator::GenerateCFunctionDeclarations(
@@ -103,7 +99,7 @@ void EnumFieldGenerator::GenerateCFunctionImplementations(
"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 GPBGetInt32IvarWithField(message, field);\n"
+ " return GPBGetMessageInt32Field(message, field);\n"
"}\n"
"\n"
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value) {\n"
@@ -137,11 +133,9 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
void RepeatedEnumFieldGenerator::GenerateFieldDescriptionTypeSpecific(
io::Printer* printer) const {
- // TODO(thomasvl): Output the CPP check to use descFunc or validator based
- // on final compile.
printer->Print(
variables_,
- " .typeSpecific.enumDescFunc = $enum_desc_func$,\n");
+ " .dataTypeSpecific.enumDescFunc = $enum_desc_func$,\n");
}
} // namespace objectivec
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
index 76137c80..4e348393 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -46,24 +46,6 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
: method_name_(ExtensionMethodName(descriptor)),
root_class_and_method_name_(root_class_name + "_" + method_name_),
descriptor_(descriptor) {
- // Extensions can be filtered via the method they are accessed off the
- // file's Root with.
- if (FilterClass(root_class_and_method_name_)) {
- filter_reason_ =
- string("Extension |") + root_class_and_method_name_ + "| was not whitelisted.";
- } else {
- // Extensions that add a Message field also require that field be allowed
- // by the filter, or they aren't usable.
- ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
- if (objc_type == OBJECTIVECTYPE_MESSAGE) {
- const string message_class_name(ClassName(descriptor_->message_type()));
- if (FilterClass(message_class_name)) {
- filter_reason_ = string("Extension |") + root_class_and_method_name_ +
- "| needs message |" + message_class_name +
- "|, which was not whitelisted.";
- }
- }
- }
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.
@@ -77,10 +59,6 @@ ExtensionGenerator::ExtensionGenerator(const string& root_class_name,
ExtensionGenerator::~ExtensionGenerator() {}
void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
- if (IsFiltered()) {
- printer->Print("// $filter_reason$\n\n", "filter_reason", filter_reason_);
- return;
- }
map<string, string> vars;
vars["method_name"] = method_name_;
SourceLocation location;
@@ -91,15 +69,11 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
}
printer->Print(vars,
"$comments$"
- "+ (GPBExtensionField*)$method_name$;\n");
+ "+ (GPBExtensionDescriptor *)$method_name$;\n");
}
void ExtensionGenerator::GenerateStaticVariablesInitialization(
- io::Printer* printer, bool* out_generated, bool root) {
- if (IsFiltered()) {
- return;
- }
- *out_generated = true;
+ io::Printer* printer) {
map<string, string> vars;
vars["root_class_and_method_name"] = root_class_and_method_name_;
vars["extended_type"] = ClassName(descriptor_->containing_type());
@@ -122,14 +96,14 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
vars["type"] = "NULL";
}
- vars["default_name"] = GPBValueFieldName(descriptor_);
+ vars["default_name"] = GPBGenericValueFieldName(descriptor_);
if (descriptor_->is_repeated()) {
vars["default"] = "nil";
} else {
vars["default"] = DefaultValue(descriptor_);
}
string type = GetCapitalizedType(descriptor_);
- vars["extension_type"] = string("GPBType") + type;
+ vars["extension_type"] = string("GPBDataType") + type;
if (objc_type == OBJECTIVECTYPE_ENUM) {
vars["enum_desc_func_name"] =
@@ -141,7 +115,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
printer->Print(vars,
"{\n"
" .singletonName = GPBStringifySymbol($root_class_and_method_name$),\n"
- " .type = $extension_type$,\n"
+ " .dataType = $extension_type$,\n"
" .extendedClass = GPBStringifySymbol($extended_type$),\n"
" .fieldNumber = $number$,\n"
" .defaultValue.$default_name$ = $default$,\n"
@@ -152,9 +126,6 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
}
void ExtensionGenerator::GenerateRegistrationSource(io::Printer* printer) {
- if (IsFiltered()) {
- return;
- }
printer->Print(
"[registry addExtension:$root_class_and_method_name$];\n",
"root_class_and_method_name", root_class_and_method_name_);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.h b/src/google/protobuf/compiler/objectivec/objectivec_extension.h
index 553f0887..e361e639 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.h
@@ -52,16 +52,12 @@ class ExtensionGenerator {
~ExtensionGenerator();
void GenerateMembersHeader(io::Printer* printer);
- void GenerateStaticVariablesInitialization(io::Printer* printer,
- bool* out_generated, bool root);
+ void GenerateStaticVariablesInitialization(io::Printer* printer);
void GenerateRegistrationSource(io::Printer* printer);
- bool IsFiltered() const { return filter_reason_.length() > 0; }
-
private:
string method_name_;
string root_class_and_method_name_;
- string filter_reason_;
const FieldDescriptor* descriptor_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
index c5f05653..0f96a4e6 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
@@ -87,18 +87,16 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
field_flags.push_back("GPBFieldHasDefaultValue");
if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
- // TODO(thomasvl): Output the CPP check to use descFunc or validator based
- // on final compile.
field_flags.push_back("GPBFieldHasEnumDescriptor");
}
(*variables)["fieldflags"] = BuildFlagsString(field_flags);
(*variables)["default"] = DefaultValue(descriptor);
- (*variables)["default_name"] = GPBValueFieldName(descriptor);
+ (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
- (*variables)["typeSpecific_name"] = "className";
- (*variables)["typeSpecific_value"] = "NULL";
+ (*variables)["dataTypeSpecific_name"] = "className";
+ (*variables)["dataTypeSpecific_value"] = "NULL";
string field_options = descriptor->options().SerializeAsString();
// Must convert to a standard byte order for packing length into
@@ -117,45 +115,6 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
(*variables)["storage_attribute"] = "";
}
-// A field generator that writes nothing.
-class EmptyFieldGenerator : public FieldGenerator {
- public:
- EmptyFieldGenerator(const FieldDescriptor* descriptor, const string& reason)
- : FieldGenerator(descriptor), reason_(reason) {}
- virtual ~EmptyFieldGenerator() {}
-
- virtual void GenerateFieldStorageDeclaration(io::Printer* printer) const {}
- virtual void GeneratePropertyDeclaration(io::Printer* printer) const {
- string name = FieldName(descriptor_);
- string type;
- switch (GetObjectiveCType(descriptor_)) {
- case OBJECTIVECTYPE_MESSAGE:
- type = ClassName(descriptor_->message_type()) + " *";
- break;
-
- case OBJECTIVECTYPE_ENUM:
- type = EnumName(descriptor_->enum_type()) + " ";
- break;
-
- default:
- type = string(descriptor_->type_name()) + " ";
- break;
- }
- printer->Print("// Field |$type$$name$| $reason$\n\n", "type", type, "name",
- name, "reason", reason_);
- }
-
- virtual void GenerateFieldNumberConstant(io::Printer* printer) const {}
- virtual void GeneratePropertyImplementation(io::Printer* printer) const {}
- virtual void GenerateFieldDescription(io::Printer* printer) const {}
-
- virtual bool WantsHasProperty(void) const { return false; }
-
- private:
- string reason_;
- GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EmptyFieldGenerator);
-};
-
} // namespace
FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
@@ -163,12 +122,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
if (field->is_repeated()) {
switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: {
- string type = ClassName(field->message_type());
- if (FilterClass(type)) {
- string reason =
- "Filtered by |" + type + "| not being whitelisted.";
- result = new EmptyFieldGenerator(field, reason);
- } else if (field->is_map()) {
+ if (field->is_map()) {
result = new MapFieldGenerator(field);
} else {
result = new RepeatedMessageFieldGenerator(field);
@@ -185,14 +139,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
} else {
switch (GetObjectiveCType(field)) {
case OBJECTIVECTYPE_MESSAGE: {
- string type = ClassName(field->message_type());
- if (FilterClass(type)) {
- string reason =
- "Filtered by |" + type + "| not being whitelisted.";
- result = new EmptyFieldGenerator(field, reason);
- } else {
- result = new MessageFieldGenerator(field);
- }
+ result = new MessageFieldGenerator(field);
break;
}
case OBJECTIVECTYPE_ENUM:
@@ -249,11 +196,17 @@ void FieldGenerator::GenerateFieldDescription(
" .number = $field_number_name$,\n"
" .hasIndex = $has_index$,\n"
" .flags = $fieldflags$,\n"
- " .type = GPBType$field_type$,\n"
- " .offset = offsetof($classname$_Storage, $name$),\n"
+ " .dataType = GPBDataType$field_type$,\n"
+ " .offset = offsetof($classname$__storage_, $name$),\n"
" .defaultValue.$default_name$ = $default$,\n");
- // " .typeSpecific.value* = [something],"
+ // TODO(thomasvl): It might be useful to add a CPP wrapper to support
+ // compiling away the EnumDescriptors. To do that, we'd need a #if here
+ // to control setting the descriptor vs. the validator, and above in
+ // SetCommonFieldVariables() we'd want to wrap how we add
+ // GPBFieldHasDefaultValue to the flags.
+
+ // " .dataTypeSpecific.value* = [something],"
GenerateFieldDescriptionTypeSpecific(printer);
const string& field_options(variables_.find("fieldoptions")->second);
@@ -280,7 +233,7 @@ void FieldGenerator::GenerateFieldDescriptionTypeSpecific(
io::Printer* printer) const {
printer->Print(
variables_,
- " .typeSpecific.$typeSpecific_name$ = $typeSpecific_value$,\n");
+ " .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n");
}
void FieldGenerator::SetOneofIndexBase(int index_base) {
@@ -410,22 +363,24 @@ void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
void RepeatedFieldGenerator::GeneratePropertyImplementation(
io::Printer* printer) const {
- printer->Print(variables_, "@dynamic $name$;\n");
+ printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
}
void RepeatedFieldGenerator::GeneratePropertyDeclaration(
io::Printer* printer) const {
- // Repeated fields don't need the has* properties, but this has the same
- // logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for dealing
- // with needing Objective C's rules around storage name conventions (init*,
- // new*, etc.)
+ // 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) $array_storage_type$ *$name$$storage_attribute$;\n");
+ "@property(nonatomic, readwrite, strong) $array_storage_type$ *$name$$storage_attribute$;\n"
+ "@property(nonatomic, readonly) NSUInteger $name$_Count;\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
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index d04eee85..1955c053 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -54,35 +54,24 @@ namespace objectivec {
FileGenerator::FileGenerator(const FileDescriptor *file)
: file_(file),
root_class_name_(FileClassName(file)),
- is_filtered_(true),
- all_extensions_filtered_(true),
is_public_dep_(false) {
- // Validate the objc prefix, do this even if the file's contents are filtered
- // to catch a bad prefix as soon as it is found.
+ // Validate the objc prefix.
ValidateObjCClassPrefix(file_);
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
- // The enums are exposed via C functions, so they will dead strip if
- // not used.
- is_filtered_ &= false;
enum_generators_.push_back(generator);
}
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator *generator =
new MessageGenerator(root_class_name_, file_->message_type(i));
- is_filtered_ &= generator->IsFiltered();
- is_filtered_ &= generator->IsSubContentFiltered();
message_generators_.push_back(generator);
}
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator *generator =
new ExtensionGenerator(root_class_name_, file_->extension(i));
- is_filtered_ &= generator->IsFiltered();
- all_extensions_filtered_ &= generator->IsFiltered();
extension_generators_.push_back(generator);
}
- // If there is nothing in the file we filter it.
}
FileGenerator::~FileGenerator() {
@@ -116,8 +105,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
"protoc_gen_objc_version",
SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION));
- const vector<FileGenerator *> &dependency_generators =
- DependencyGenerators();
+ const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
for (vector<FileGenerator *>::const_iterator iter =
dependency_generators.begin();
iter != dependency_generators.end(); ++iter) {
@@ -133,19 +121,17 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
printer->Print("CF_EXTERN_C_BEGIN\n\n");
- if (!IsFiltered()) {
- set<string> fwd_decls;
- for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
- iter != message_generators_.end(); ++iter) {
- (*iter)->DetermineForwardDeclarations(&fwd_decls);
- }
- for (set<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");
- }
+ set<string> fwd_decls;
+ for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
+ iter != message_generators_.end(); ++iter) {
+ (*iter)->DetermineForwardDeclarations(&fwd_decls);
+ }
+ for (set<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");
}
// need to write out all enums first
@@ -160,36 +146,27 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
}
// For extensions to chain together, the Root gets created even if there
- // are no extensions. So if the entire file isn't filtered away, output it.
- if (!IsFiltered()) {
- printer->Print(
- "\n"
- "#pragma mark - $root_class_name$\n"
- "\n"
- "@interface $root_class_name$ : GPBRootObject\n"
- "\n"
- "// The base class provides:\n"
- "// + (GPBExtensionRegistry *)extensionRegistry;\n"
- "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
- "// this file and all files that it depends on.\n"
- "\n"
- "@end\n"
- "\n",
- "root_class_name", root_class_name_);
- }
+ // are no extensions.
+ printer->Print(
+ "\n"
+ "#pragma mark - $root_class_name$\n"
+ "\n"
+ "@interface $root_class_name$ : GPBRootObject\n"
+ "\n"
+ "// The base class provides:\n"
+ "// + (GPBExtensionRegistry *)extensionRegistry;\n"
+ "// which is an GPBExtensionRegistry that includes all the extensions defined by\n"
+ "// this file and all files that it depends on.\n"
+ "\n"
+ "@end\n"
+ "\n",
+ "root_class_name", root_class_name_);
if (extension_generators_.size() > 0) {
- // The dynamic methods block is only needed if there are extensions. If
- // they are all filtered, output the @interface as a comment so there is
- // something left in the header for anyone that looks.
- const char *root_line_prefix = "";
- if (AreAllExtensionsFiltered()) {
- root_line_prefix = "// ";
- }
+ // The dynamic methods block is only needed if there are extensions.
printer->Print(
- "$root_line_prefix$@interface $root_class_name$ (DynamicMethods)\n",
- "root_class_name", root_class_name_,
- "root_line_prefix", root_line_prefix);
+ "@interface $root_class_name$ (DynamicMethods)\n",
+ "root_class_name", root_class_name_);
for (vector<ExtensionGenerator *>::iterator iter =
extension_generators_.begin();
@@ -197,8 +174,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
(*iter)->GenerateMembersHeader(printer);
}
- printer->Print("$root_line_prefix$@end\n\n",
- "root_line_prefix", root_line_prefix);
+ printer->Print("@end\n\n");
} // extension_generators_.size() > 0
for (vector<MessageGenerator *>::iterator iter = message_generators_.begin();
@@ -239,136 +215,119 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"// @@protoc_insertion_point(imports)\n"
"\n");
- if (IsFiltered()) {
- printer->Print(
- "// File empty because all messages, extensions and enum have been filtered.\n"
- "\n"
- "\n"
- "// Dummy symbol that will be stripped but will avoid linker warnings about\n"
- "// no symbols in the .o form compiling this file.\n"
- "static int $root_class_name$_dummy __attribute__((unused,used)) = 0;\n"
- "\n"
- "// @@protoc_insertion_point(global_scope)\n",
- "root_class_name", root_class_name_);
- return;
- }
-
printer->Print(
"#pragma mark - $root_class_name$\n"
"\n"
"@implementation $root_class_name$\n\n",
"root_class_name", root_class_name_);
- bool generated_extensions = false;
- if (file_->extension_count() + file_->message_type_count() +
- file_->dependency_count() >
- 0) {
- ostringstream extensions_stringstream;
-
- if (file_->extension_count() + file_->message_type_count() > 0) {
- io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
- io::Printer extensions_printer(&extensions_outputstream, '$');
- extensions_printer.Print(
- "static GPBExtensionDescription descriptions[] = {\n");
- extensions_printer.Indent();
- for (vector<ExtensionGenerator *>::iterator iter =
- extension_generators_.begin();
- iter != extension_generators_.end(); ++iter) {
- (*iter)->GenerateStaticVariablesInitialization(
- &extensions_printer, &generated_extensions, true);
- }
- for (vector<MessageGenerator *>::iterator iter =
- message_generators_.begin();
- iter != message_generators_.end(); ++iter) {
- (*iter)->GenerateStaticVariablesInitialization(&extensions_printer,
- &generated_extensions);
- }
- extensions_printer.Outdent();
- extensions_printer.Print("};\n");
- if (generated_extensions) {
- extensions_printer.Print(
- "for (size_t i = 0; i < sizeof(descriptions) / sizeof(descriptions[0]); ++i) {\n"
- " GPBExtensionField *extension = [[GPBExtensionField alloc] initWithDescription:&descriptions[i]];\n"
- " [registry addExtension:extension];\n"
- " [self globallyRegisterExtension:extension];\n"
- " [extension release];\n"
- "}\n");
- } else {
- extensions_printer.Print("#pragma unused (descriptions)\n");
- }
- const vector<FileGenerator *> &dependency_generators =
- DependencyGenerators();
- if (dependency_generators.size()) {
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
- if (!(*iter)->IsFiltered()) {
- extensions_printer.Print(
- "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
- "dependency", (*iter)->RootClassName());
- generated_extensions = true;
- }
- }
- } else if (!generated_extensions) {
- extensions_printer.Print("#pragma unused (registry)\n");
- }
+ // Generate the extension initialization structures for the top level and
+ // any nested messages.
+ ostringstream extensions_stringstream;
+ if (file_->extension_count() + file_->message_type_count() > 0) {
+ io::OstreamOutputStream extensions_outputstream(&extensions_stringstream);
+ io::Printer extensions_printer(&extensions_outputstream, '$');
+ for (vector<ExtensionGenerator *>::iterator iter =
+ extension_generators_.begin();
+ iter != extension_generators_.end(); ++iter) {
+ (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
+ }
+ for (vector<MessageGenerator *>::iterator iter =
+ message_generators_.begin();
+ iter != message_generators_.end(); ++iter) {
+ (*iter)->GenerateStaticVariablesInitialization(&extensions_printer);
}
+ extensions_stringstream.flush();
+ }
- if (generated_extensions) {
+ // If there were any extensions or this file has any dependencies, output
+ // a registry to override to create the file specific registry.
+ const string& extensions_str = extensions_stringstream.str();
+ if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
+ 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"
+ " GPBDebugCheckRuntimeVersion();\n"
+ " registry = [[GPBExtensionRegistry alloc] init];\n");
+
+ printer->Indent();
+ printer->Indent();
+
+ if (extensions_str.length() > 0) {
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"
- " registry = [[GPBExtensionRegistry alloc] init];\n");
-
- printer->Indent();
+ "static GPBExtensionDescription descriptions[] = {\n");
printer->Indent();
-
- extensions_stringstream.flush();
- printer->Print(extensions_stringstream.str().c_str());
- printer->Outdent();
+ printer->Print(extensions_str.c_str());
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"
+ " [registry addExtension:extension];\n"
+ " [self globallyRegisterExtension:extension];\n"
+ " [extension release];\n"
+ "}\n");
+ }
+ const vector<FileGenerator *> &dependency_generators =
+ DependencyGenerators();
+ for (vector<FileGenerator *>::const_iterator iter =
+ dependency_generators.begin();
+ iter != dependency_generators.end(); ++iter) {
printer->Print(
- " }\n"
- " return registry;\n"
- "}\n"
- "\n");
+ "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
+ "dependency", (*iter)->RootClassName());
}
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
+ " }\n"
+ " return registry;\n"
+ "}\n"
+ "\n");
}
printer->Print("@end\n\n");
-
- string syntax;
- switch (file_->syntax()) {
- case FileDescriptor::SYNTAX_UNKNOWN:
- syntax = "GPBFileSyntaxUnknown";
- break;
- case FileDescriptor::SYNTAX_PROTO2:
- syntax = "GPBFileSyntaxProto2";
- break;
- case FileDescriptor::SYNTAX_PROTO3:
- syntax = "GPBFileSyntaxProto3";
- break;
+ // File descriptor only needed if there are messages to use it.
+ if (message_generators_.size() > 0) {
+ string syntax;
+ switch (file_->syntax()) {
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ syntax = "GPBFileSyntaxUnknown";
+ break;
+ case FileDescriptor::SYNTAX_PROTO2:
+ syntax = "GPBFileSyntaxProto2";
+ break;
+ case FileDescriptor::SYNTAX_PROTO3:
+ syntax = "GPBFileSyntaxProto3";
+ break;
+ }
+ printer->Print(
+ "#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"
+ " GPBDebugCheckRuntimeVersion();\n"
+ " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+ " syntax:$syntax$];\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n"
+ "\n",
+ "root_class_name", root_class_name_,
+ "package", file_->package(),
+ "syntax", syntax);
}
- printer->Print(
- "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"
- " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
- " syntax:$syntax$];\n"
- " }\n"
- " return descriptor;\n"
- "}\n"
- "\n",
- "root_class_name", root_class_name_,
- "package", file_->package(),
- "syntax", syntax);
for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
iter != enum_generators_.end(); ++iter) {
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h
index 95d17bfd..1bb4f0ea 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h
@@ -64,8 +64,6 @@ class FileGenerator {
const string& RootClassName() const { return root_class_name_; }
const string Path() const;
- bool IsFiltered() const { return is_filtered_; }
- bool AreAllExtensionsFiltered() const { return all_extensions_filtered_; }
bool IsPublicDependency() const { return is_public_dep_; }
protected:
@@ -84,8 +82,6 @@ class FileGenerator {
vector<EnumGenerator*> enum_generators_;
vector<MessageGenerator*> message_generators_;
vector<ExtensionGenerator*> extension_generators_;
- bool is_filtered_;
- bool all_extensions_filtered_;
bool is_public_dep_;
const vector<FileGenerator*>& DependencyGenerators();
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
index 17776715..85e438f4 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -58,10 +58,6 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
return false;
}
- if (!InitializeClassWhitelist(error)) {
- return false;
- }
-
FileGenerator file_generator(file);
string filepath = FilePath(file);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 6d6e5959..9b645f09 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -50,8 +50,6 @@ namespace objectivec {
namespace {
-hash_set<string> gClassWhitelist;
-
// islower()/isupper()/tolower()/toupper() change based on locale.
//
// src/google/protobuf/stubs/strutil.h:150 has the same pattern. For the
@@ -580,7 +578,7 @@ string GetCapitalizedType(const FieldDescriptor* field) {
case FieldDescriptor::TYPE_STRING:
return "String";
case FieldDescriptor::TYPE_BYTES:
- return "Data";
+ return "Bytes";
case FieldDescriptor::TYPE_ENUM:
return "Enum";
case FieldDescriptor::TYPE_GROUP:
@@ -684,8 +682,9 @@ static string HandleExtremeFloatingPoint(string val, bool add_float_suffix) {
}
}
-string GPBValueFieldName(const FieldDescriptor* field) {
- // Returns the field within the GPBValue union to use for the given field.
+string GPBGenericValueFieldName(const FieldDescriptor* field) {
+ // Returns the field within the GPBGenericValue union to use for the given
+ // field.
if (field->is_repeated()) {
return "valueMessage";
}
@@ -831,60 +830,6 @@ string BuildCommentsString(const SourceLocation& location) {
return final_comments;
}
-bool InitializeClassWhitelist(string* error) {
- const char* env_var_value = getenv("GPB_OBJC_CLASS_WHITELIST_PATHS");
- if (env_var_value == NULL) {
- return true;
- }
-
- // The values are joined with ';' in case we ever want to make this a
- // generator parameter also (instead of env var), and generator parameter
- // parsing already has meaning for ',' and ':'.
- vector<string> file_paths = Split(env_var_value, ";", true);
-
- for (vector<string>::const_iterator i = file_paths.begin();
- i != file_paths.end(); ++i) {
- const string& file_path = *i;
-
- ifstream stream(file_path.c_str(), ifstream::in);
- if (!stream.good()) {
- if (error != NULL) {
- stringstream err_stream;
- err_stream << endl << file_path << ":0:0: error: Unable to open";
- *error = err_stream.str();
- return false;
- }
- }
-
- string input_line;
- while (stream.good()) {
- getline(stream, input_line);
- string trimmed_line(TrimString(input_line));
- if (trimmed_line.length() == 0) {
- // Skip empty lines
- continue;
- }
- if (trimmed_line[0] == '/' || trimmed_line[0] == '#') {
- // Skip comments and potential preprocessor symbols
- continue;
- }
- gClassWhitelist.insert(trimmed_line);
- }
- }
- return true;
-}
-
-bool FilterClass(const string& name) {
- if (gClassWhitelist.count(name) > 0) {
- // Whitelisted, don't filter.
- return false;
- }
-
- // If there was no list, default to everything in.
- // If there was a list, default to everything out.
- return gClassWhitelist.size() > 0;
-}
-
void TextFormatDecodeData::AddString(int32 key,
const string& input_for_decode,
const string& desired_output) {
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index 19317698..10d51a34 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -138,16 +138,13 @@ inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
bool IsPrimitiveType(const FieldDescriptor* field);
bool IsReferenceType(const FieldDescriptor* field);
-string GPBValueFieldName(const FieldDescriptor* field);
+string GPBGenericValueFieldName(const FieldDescriptor* field);
string DefaultValue(const FieldDescriptor* field);
string BuildFlagsString(const vector<string>& strings);
string BuildCommentsString(const SourceLocation& location);
-bool InitializeClassWhitelist(string* error);
-bool FilterClass(const string& name);
-
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the the expected output.
class LIBPROTOC_EXPORT TextFormatDecodeData {
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
index b091b77a..dc1cef55 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers_unittest.cc
@@ -242,6 +242,14 @@ TEST(ObjCHelperDeathTest, TextFormatDecodeData_Failures) {
}
#endif // PROTOBUF_HAS_DEATH_TEST
+// 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
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
index 52e583bf..32671d42 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
@@ -178,49 +178,25 @@ MessageGenerator::MessageGenerator(const string& root_classname,
: root_classname_(root_classname),
descriptor_(descriptor),
field_generators_(descriptor),
- class_name_(ClassName(descriptor_)),
- sub_content_filtered_(true) {
- if (FilterClass(class_name_)) {
- filter_reason_ =
- string("Message |") + class_name_ + "| was not whitelisted.";
+ class_name_(ClassName(descriptor_)) {
+ for (int i = 0; i < descriptor_->extension_count(); i++) {
+ extension_generators_.push_back(
+ new ExtensionGenerator(class_name_, descriptor_->extension(i)));
}
- if (!IsFiltered()) {
- // No need to generate extensions if this message is filtered
- for (int i = 0; i < descriptor_->extension_count(); i++) {
- extension_generators_.push_back(
- new ExtensionGenerator(class_name_, descriptor_->extension(i)));
- }
- // No need to generate oneofs if this message is filtered.
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
- OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
- oneof_generators_.push_back(generator);
- }
+
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
+ oneof_generators_.push_back(generator);
}
- // We may have enums of this message that are used even if the message
- // itself is filtered.
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
EnumGenerator* generator = new EnumGenerator(descriptor_->enum_type(i));
- // The enums are exposed via C functions, so they will dead strip if
- // not used.
- sub_content_filtered_ &= false;
enum_generators_.push_back(generator);
}
- // We may have nested messages that are used even if the message itself
- // is filtered.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- const Descriptor* nested_descriptor = descriptor_->nested_type(i);
MessageGenerator* generator =
- new MessageGenerator(root_classname_, nested_descriptor);
- // Don't check map entries for being filtered, as they don't directly
- // generate anything in Objective C. In theory, they only should include
- // references to other toplevel types, but we still make the generators
- // to be safe.
- if (!IsMapEntryMessage(nested_descriptor)) {
- sub_content_filtered_ &= generator->IsFiltered();
- }
- sub_content_filtered_ &= generator->IsSubContentFiltered();
+ new MessageGenerator(root_classname_, descriptor_->nested_type(i));
nested_message_generators_.push_back(generator);
}
}
@@ -236,31 +212,26 @@ MessageGenerator::~MessageGenerator() {
}
void MessageGenerator::GenerateStaticVariablesInitialization(
- io::Printer* printer, bool* out_generated) {
- if (!IsFiltered()) {
- // Skip extensions if we are filtered.
- for (vector<ExtensionGenerator*>::iterator iter =
- extension_generators_.begin();
- iter != extension_generators_.end(); ++iter) {
- (*iter)->GenerateStaticVariablesInitialization(printer, out_generated,
- false);
- }
+ io::Printer* printer) {
+ for (vector<ExtensionGenerator*>::iterator iter =
+ extension_generators_.begin();
+ iter != extension_generators_.end(); ++iter) {
+ (*iter)->GenerateStaticVariablesInitialization(printer);
}
- // Generating sub messages is perfectly fine though.
for (vector<MessageGenerator*>::iterator iter =
nested_message_generators_.begin();
iter != nested_message_generators_.end(); ++iter) {
- (*iter)->GenerateStaticVariablesInitialization(printer, out_generated);
+ (*iter)->GenerateStaticVariablesInitialization(printer);
}
}
void MessageGenerator::DetermineForwardDeclarations(set<string>* fwd_decls) {
- if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) {
+ if (!IsMapEntryMessage(descriptor_)) {
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
- // If it is a the field is repeated, the type will be and *Array,
- // and we don't need any forward decl.
+ // If it is a the field is repeated, the type will be and *Array, and we
+ // don't need any forward decl.
if (fieldDescriptor->is_repeated()) {
continue;
}
@@ -291,12 +262,10 @@ void MessageGenerator::GenerateEnumHeader(io::Printer* printer) {
void MessageGenerator::GenerateExtensionRegistrationSource(
io::Printer* printer) {
- if (!IsFiltered()) {
- for (vector<ExtensionGenerator*>::iterator iter =
- extension_generators_.begin();
- iter != extension_generators_.end(); ++iter) {
- (*iter)->GenerateRegistrationSource(printer);
- }
+ for (vector<ExtensionGenerator*>::iterator iter =
+ extension_generators_.begin();
+ iter != extension_generators_.end(); ++iter) {
+ (*iter)->GenerateRegistrationSource(printer);
}
for (vector<MessageGenerator*>::iterator iter =
@@ -317,101 +286,84 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
return;
}
- if (IsFiltered()) {
- printer->Print("// $filter_reason$\n\n",
- "filter_reason", filter_reason_);
- } else {
- printer->Print(
- "#pragma mark - $classname$\n"
- "\n",
- "classname", class_name_);
+ printer->Print(
+ "#pragma mark - $classname$\n"
+ "\n",
+ "classname", class_name_);
- if (descriptor_->field_count()) {
- // Even if there are fields, they could be filtered away, so always use
- // a buffer to confirm we have something.
- ostringstream fieldnumber_stringstream;
- {
- scoped_array<const FieldDescriptor*> sorted_fields(
- SortFieldsByNumber(descriptor_));
-
- io::OstreamOutputStream fieldnumber_outputstream(
- &fieldnumber_stringstream);
- io::Printer fieldnumber_printer(&fieldnumber_outputstream, '$');
- for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(sorted_fields[i])
- .GenerateFieldNumberConstant(&fieldnumber_printer);
- }
- fieldnumber_stringstream.flush();
- }
- const string& fieldnumber_str = fieldnumber_stringstream.str();
- if (fieldnumber_str.length()) {
- printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
- "classname", class_name_);
- printer->Indent();
- printer->Print(fieldnumber_str.c_str());
- printer->Outdent();
- printer->Print("};\n\n");
- }
- }
+ if (descriptor_->field_count()) {
+ scoped_array<const FieldDescriptor*> sorted_fields(
+ SortFieldsByNumber(descriptor_));
- for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
- iter != oneof_generators_.end(); ++iter) {
- (*iter)->GenerateCaseEnum(printer);
- }
+ printer->Print("typedef GPB_ENUM($classname$_FieldNumber) {\n",
+ "classname", class_name_);
+ printer->Indent();
- string message_comments;
- SourceLocation location;
- if (descriptor_->GetSourceLocation(&location)) {
- message_comments = BuildCommentsString(location);
- } else {
- message_comments = "";
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(sorted_fields[i])
+ .GenerateFieldNumberConstant(printer);
}
- printer->Print(
- "$comments$@interface $classname$ : GPBMessage\n\n",
- "classname", class_name_,
- "comments", message_comments);
+ printer->Outdent();
+ printer->Print("};\n\n");
+ }
- vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
- for (int i = 0; i < descriptor_->field_count(); i++) {
- const FieldDescriptor* field = descriptor_->field(i);
- if (field->containing_oneof() != NULL) {
- const int oneof_index = field->containing_oneof()->index();
- if (!seen_oneofs[oneof_index]) {
- seen_oneofs[oneof_index] = 1;
- oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
- printer);
- }
+ for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
+ iter != oneof_generators_.end(); ++iter) {
+ (*iter)->GenerateCaseEnum(printer);
+ }
+
+ string message_comments;
+ SourceLocation location;
+ if (descriptor_->GetSourceLocation(&location)) {
+ message_comments = BuildCommentsString(location);
+ } else {
+ message_comments = "";
+ }
+
+ printer->Print(
+ "$comments$@interface $classname$ : GPBMessage\n\n",
+ "classname", class_name_,
+ "comments", message_comments);
+
+ vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->containing_oneof() != NULL) {
+ const int oneof_index = field->containing_oneof()->index();
+ if (!seen_oneofs[oneof_index]) {
+ seen_oneofs[oneof_index] = 1;
+ oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
+ printer);
}
- field_generators_.get(field)
- .GeneratePropertyDeclaration(printer);
}
+ field_generators_.get(field).GeneratePropertyDeclaration(printer);
+ }
- printer->Print("@end\n\n");
+ printer->Print("@end\n\n");
- for (int i = 0; i < descriptor_->field_count(); i++) {
- field_generators_.get(descriptor_->field(i))
- .GenerateCFunctionDeclarations(printer);
- }
+ for (int i = 0; i < descriptor_->field_count(); i++) {
+ field_generators_.get(descriptor_->field(i))
+ .GenerateCFunctionDeclarations(printer);
+ }
- if (!oneof_generators_.empty()) {
- for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
- iter != oneof_generators_.end(); ++iter) {
- (*iter)->GenerateClearFunctionDeclaration(printer);
- }
- printer->Print("\n");
+ if (!oneof_generators_.empty()) {
+ for (vector<OneofGenerator*>::iterator iter = oneof_generators_.begin();
+ iter != oneof_generators_.end(); ++iter) {
+ (*iter)->GenerateClearFunctionDeclaration(printer);
}
+ printer->Print("\n");
+ }
- if (descriptor_->extension_count() > 0) {
- printer->Print("@interface $classname$ (DynamicMethods)\n\n",
- "classname", class_name_);
- for (vector<ExtensionGenerator*>::iterator iter =
- extension_generators_.begin();
- iter != extension_generators_.end(); ++iter) {
- (*iter)->GenerateMembersHeader(printer);
- }
- printer->Print("@end\n\n");
+ if (descriptor_->extension_count() > 0) {
+ printer->Print("@interface $classname$ (DynamicMethods)\n\n",
+ "classname", class_name_);
+ for (vector<ExtensionGenerator*>::iterator iter =
+ extension_generators_.begin();
+ iter != extension_generators_.end(); ++iter) {
+ (*iter)->GenerateMembersHeader(printer);
}
+ printer->Print("@end\n\n");
}
for (vector<MessageGenerator*>::iterator iter =
@@ -422,7 +374,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
}
void MessageGenerator::GenerateSource(io::Printer* printer) {
- if (!IsFiltered() && !IsMapEntryMessage(descriptor_)) {
+ if (!IsMapEntryMessage(descriptor_)) {
printer->Print(
"#pragma mark - $classname$\n"
"\n",
@@ -454,6 +406,23 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
sort(sorted_extensions.begin(), sorted_extensions.end(),
ExtensionRangeOrdering());
+ // TODO(thomasvl): Finish optimizing has bit. The current behavior is as
+ // follows:
+ // 1. objectivec_field.cc's SetCommonFieldVariables() defaults the has_index
+ // to the field's index in the list of fields.
+ // 2. RepeatedFieldGenerator::RepeatedFieldGenerator() sets has_index to
+ // GPBNoHasBit because repeated fields & map<> fields don't use the has
+ // bit.
+ // 3. FieldGenerator::SetOneofIndexBase() overrides has_bit with a negative
+ // index that groups all the elements on of the oneof.
+ // So in has_storage, we need enough bits for the single fields that aren't
+ // in any oneof, and then one int32 for each oneof (to store the field
+ // number). So we could save a little space by not using the field's index
+ // and instead make a second pass only assigning indexes for the fields
+ // that would need it. The only savings would come when messages have over
+ // a multiple of 32 fields with some number being repeated or in oneofs to
+ // drop the count below that 32 multiple; so it hasn't seemed worth doing
+ // at the moment.
size_t num_has_bits = descriptor_->field_count();
size_t sizeof_has_storage = (num_has_bits + 31) / 32;
// Tell all the fields the oneof base.
@@ -467,7 +436,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
printer->Print(
"\n"
- "typedef struct $classname$_Storage {\n"
+ "typedef struct $classname$__storage_ {\n"
" uint32_t _has_storage_[$sizeof_has_storage$];\n",
"classname", class_name_,
"sizeof_has_storage", SimpleItoa(sizeof_has_storage));
@@ -479,14 +448,14 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
}
printer->Outdent();
- printer->Print("} $classname$_Storage;\n\n", "classname", class_name_);
+ 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 = NULL;\n"
+ " static GPBDescriptor *descriptor = nil;\n"
" if (!descriptor) {\n");
bool has_oneofs = oneof_generators_.size();
@@ -507,30 +476,45 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" };\n");
}
- printer->Print(
- " static GPBMessageFieldDescription fields[] = {\n");
- printer->Indent();
- printer->Indent();
- printer->Indent();
TextFormatDecodeData text_format_decode_data;
- for (int i = 0; i < descriptor_->field_count(); ++i) {
- const FieldGenerator& field_generator =
- field_generators_.get(sorted_fields[i]);
- field_generator.GenerateFieldDescription(printer);
- 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());
+ bool has_fields = descriptor_->field_count() > 0;
+ if (has_fields) {
+ // TODO(thomasvl): The plugin's FieldGenerator::GenerateFieldDescription()
+ // wraps the fieldOptions's value of this structure in an CPP gate so
+ // they can be compiled away; but that still results in a const char* in
+ // the structure for a NULL pointer for every message field. If the
+ // fieldOptions are moved to a separate payload like the TextFormat extra
+ // data is, then it would shrink that static data shrinking the binaries
+ // a little more.
+ // TODO(thomasvl): proto3 syntax doens't need a defaultValue in the
+ // structure because primitive types are always zero. If we add a second
+ // structure and a different initializer, we can avoid the wasted static
+ // storage for every field in a proto3 message.
+ printer->Print(
+ " static GPBMessageFieldDescription fields[] = {\n");
+ printer->Indent();
+ printer->Indent();
+ 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);
+ 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->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " };\n");
}
- printer->Outdent();
- printer->Outdent();
- printer->Outdent();
bool has_enums = enum_generators_.size();
if (has_enums) {
printer->Print(
- " };\n"
" static GPBMessageEnumDescription enums[] = {\n");
printer->Indent();
printer->Indent();
@@ -543,12 +527,13 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
printer->Outdent();
printer->Outdent();
printer->Outdent();
+ printer->Print(
+ " };\n");
}
bool has_extensions = sorted_extensions.size();
if (has_extensions) {
printer->Print(
- " };\n"
" static GPBExtensionRange ranges[] = {\n");
printer->Indent();
printer->Indent();
@@ -561,11 +546,16 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
printer->Outdent();
printer->Outdent();
printer->Outdent();
+ printer->Print(
+ " };\n");
}
map<string, string> vars;
vars["classname"] = class_name_;
vars["rootclassname"] = root_classname_;
+ vars["fields"] = has_fields ? "fields" : "NULL";
+ vars["fields_count"] =
+ has_fields ? "sizeof(fields) / sizeof(GPBMessageFieldDescription)" : "0";
vars["oneofs"] = has_oneofs ? "oneofs" : "NULL";
vars["oneof_count"] =
has_oneofs ? "sizeof(oneofs) / sizeof(GPBMessageOneofDescription)" : "0";
@@ -578,23 +568,23 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
vars["wireformat"] =
descriptor_->options().message_set_wire_format() ? "YES" : "NO";
- printer->Print(" };\n");
if (text_format_decode_data.num_entries() == 0) {
printer->Print(
vars,
- " descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
- " rootClass:[$rootclassname$ class]\n"
- " file:$rootclassname$_FileDescriptor()\n"
- " fields:fields\n"
- " fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n"
- " oneofs:$oneofs$\n"
- " oneofCount:$oneof_count$\n"
- " enums:$enums$\n"
- " enumCount:$enum_count$\n"
- " ranges:$ranges$\n"
- " rangeCount:$range_count$\n"
- " storageSize:sizeof($classname$_Storage)\n"
- " wireFormat:$wireformat$];\n");
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+ " rootClass:[$rootclassname$ class]\n"
+ " file:$rootclassname$_FileDescriptor()\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " oneofs:$oneofs$\n"
+ " oneofCount:$oneof_count$\n"
+ " enums:$enums$\n"
+ " enumCount:$enum_count$\n"
+ " ranges:$ranges$\n"
+ " rangeCount:$range_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " wireFormat:$wireformat$];\n");
} else {
vars["extraTextFormatInfo"] = CEscape(text_format_decode_data.Data());
printer->Print(
@@ -604,26 +594,29 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
"#else\n"
" static const char *extraTextFormatInfo = \"$extraTextFormatInfo$\";\n"
"#endif // GPBOBJC_SKIP_MESSAGE_TEXTFORMAT_EXTRAS\n"
- " descriptor = [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
- " rootClass:[$rootclassname$ class]\n"
- " file:$rootclassname$_FileDescriptor()\n"
- " fields:fields\n"
- " fieldCount:sizeof(fields) / sizeof(GPBMessageFieldDescription)\n"
- " oneofs:$oneofs$\n"
- " oneofCount:$oneof_count$\n"
- " enums:$enums$\n"
- " enumCount:$enum_count$\n"
- " ranges:$ranges$\n"
- " rangeCount:$range_count$\n"
- " storageSize:sizeof($classname$_Storage)\n"
- " wireFormat:$wireformat$\n"
- " extraTextFormatInfo:extraTextFormatInfo];\n");
+ " GPBDescriptor *localDescriptor =\n"
+ " [GPBDescriptor allocDescriptorForClass:[$classname$ class]\n"
+ " rootClass:[$rootclassname$ class]\n"
+ " file:$rootclassname$_FileDescriptor()\n"
+ " fields:$fields$\n"
+ " fieldCount:$fields_count$\n"
+ " oneofs:$oneofs$\n"
+ " oneofCount:$oneof_count$\n"
+ " enums:$enums$\n"
+ " enumCount:$enum_count$\n"
+ " ranges:$ranges$\n"
+ " rangeCount:$range_count$\n"
+ " storageSize:sizeof($classname$__storage_)\n"
+ " wireFormat:$wireformat$\n"
+ " extraTextFormatInfo:extraTextFormatInfo];\n");
}
printer->Print(
- " }\n"
- " return descriptor;\n"
- "}\n\n"
- "@end\n\n");
+ " NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
+ " descriptor = localDescriptor;\n"
+ " }\n"
+ " return descriptor;\n"
+ "}\n\n"
+ "@end\n\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
field_generators_.get(descriptor_->field(i))
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h
index 8d03c0b8..06b536ff 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h
@@ -57,20 +57,13 @@ class MessageGenerator {
MessageGenerator(const string& root_classname, const Descriptor* descriptor);
~MessageGenerator();
- void GenerateStaticVariablesInitialization(io::Printer* printer,
- bool* out_generated);
+ 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 DetermineForwardDeclarations(set<string>* fwd_decls);
- // This only speaks for this message, not sub message/enums.
- bool IsFiltered() const { return filter_reason_.length() > 0; }
- // This message being filtered doesn't effect this, instead it covers if
- // there are any nested messages or enums.
- bool IsSubContentFiltered() const { return sub_content_filtered_; }
-
private:
void GenerateParseFromMethodsHeader(io::Printer* printer);
@@ -87,8 +80,6 @@ class MessageGenerator {
const Descriptor* descriptor_;
FieldGeneratorMap field_generators_;
const string class_name_;
- string filter_reason_;
- bool sub_content_filtered_;
vector<ExtensionGenerator*> extension_generators_;
vector<EnumGenerator*> enum_generators_;
vector<MessageGenerator*> nested_message_generators_;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
index 2e3bdfdb..f2ce4e5b 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -53,7 +53,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*variables)["group_or_message"] =
(descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
- (*variables)["typeSpecific_value"] = "GPBStringifySymbol(" + message_type + ")";
+ (*variables)["dataTypeSpecific_value"] = "GPBStringifySymbol(" + message_type + ")";
}
} // namespace
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index 344ed450..e7890fae 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -913,7 +913,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes(
int CodeGeneratorResponse_File::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 7) {
+ if (_has_bits_[0 / 32] & 7u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index 6c203ab6..1b04cb32 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -47,6 +47,7 @@ namespace {
string FindRubyTestDir(const string& file) {
// Inspired by TestSourceDir() in src/google/protobuf/testing/googletest.cc.
+#ifndef GOOGLE_THIRD_PARTY_PROTOBUF
string prefix = ".";
while (!File::Exists(prefix + "/src/google/protobuf/compiler/ruby" + file)) {
if (!File::Exists(prefix)) {
@@ -57,6 +58,9 @@ string FindRubyTestDir(const string& file) {
prefix += "/..";
}
return prefix + "/src/google/protobuf/compiler/ruby";
+#else
+ return "third_party/protobuf/src/google/protobuf/compiler/ruby";
+#endif // GOOGLE_THIRD_PARTY_PROTOBUF
}
// This test is a simple golden-file test over the output of the Ruby code
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 755c2617..30b3a3a7 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -753,9 +753,10 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"ion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004sp"
"an\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031"
"\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_det"
- "ached_comments\030\006 \003(\tBY\n\023com.google.proto"
- "bufB\020DescriptorProtosH\001\242\002\003GPB\252\002\'Google.P"
- "rotocolBuffers.DescriptorProtos", 4951);
+ "ached_comments\030\006 \003(\tBe\n\023com.google.proto"
+ "bufB\020DescriptorProtosH\001Z\ndescriptor\242\002\003GP"
+ "B\252\002\'Google.ProtocolBuffers.DescriptorPro"
+ "tos", 4963);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -1648,7 +1649,7 @@ void FileDescriptorProto::SerializeWithCachedSizes(
int FileDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 3) {
+ if (_has_bits_[0 / 32] & 3u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -1664,7 +1665,7 @@ int FileDescriptorProto::ByteSize() const {
}
}
- if (_has_bits_[9 / 32] & 3584) {
+ if (_has_bits_[9 / 32] & 3584u) {
// optional .google.protobuf.FileOptions options = 8;
if (has_options()) {
total_size += 1 +
@@ -2534,7 +2535,7 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
int DescriptorProto_ExtensionRange::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 3) {
+ if (_has_bits_[0 / 32] & 3u) {
// optional int32 start = 1;
if (has_start()) {
total_size += 1 +
@@ -2817,7 +2818,7 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes(
int DescriptorProto_ReservedRange::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 3) {
+ if (_has_bits_[0 / 32] & 3u) {
// optional int32 start = 1;
if (has_start()) {
total_size += 1 +
@@ -3373,7 +3374,7 @@ void DescriptorProto::SerializeWithCachedSizes(
int DescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 129) {
+ if (_has_bits_[0 / 32] & 129u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -4558,7 +4559,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes(
int FieldDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 255) {
+ if (_has_bits_[0 / 32] & 255u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -5633,7 +5634,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes(
int EnumDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 5) {
+ if (_has_bits_[0 / 32] & 5u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -6102,7 +6103,7 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes(
int EnumValueDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 7) {
+ if (_has_bits_[0 / 32] & 7u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -6569,7 +6570,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes(
int ServiceDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 5) {
+ if (_has_bits_[0 / 32] & 5u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -7165,7 +7166,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes(
int MethodDescriptorProto::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 63) {
+ if (_has_bits_[0 / 32] & 63u) {
// optional string name = 1;
if (has_name()) {
total_size += 1 +
@@ -8240,7 +8241,7 @@ void FileOptions::SerializeWithCachedSizes(
int FileOptions::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 255) {
+ if (_has_bits_[0 / 32] & 255u) {
// optional string java_package = 1;
if (has_java_package()) {
total_size += 1 +
@@ -8289,7 +8290,7 @@ int FileOptions::ByteSize() const {
}
}
- if (_has_bits_[8 / 32] & 16128) {
+ if (_has_bits_[8 / 32] & 16128u) {
// optional bool java_generic_services = 17 [default = false];
if (has_java_generic_services()) {
total_size += 2 + 1;
@@ -9279,7 +9280,7 @@ void MessageOptions::SerializeWithCachedSizes(
int MessageOptions::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 15) {
+ if (_has_bits_[0 / 32] & 15u) {
// optional bool message_set_wire_format = 1 [default = false];
if (has_message_set_wire_format()) {
total_size += 1 + 1;
@@ -9939,7 +9940,7 @@ void FieldOptions::SerializeWithCachedSizes(
int FieldOptions::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 63) {
+ if (_has_bits_[0 / 32] & 63u) {
// optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
if (has_ctype()) {
total_size += 1 +
@@ -10498,7 +10499,7 @@ void EnumOptions::SerializeWithCachedSizes(
int EnumOptions::ByteSize() const {
int total_size = 0;
- if (_has_bits_[0 / 32] & 3) {
+ if (_has_bits_[0 / 32] & 3u) {
// optional bool allow_alias = 2;
if (has_allow_alias()) {
total_size += 1 + 1;
@@ -12410,7 +12411,7 @@ void UninterpretedOption::SerializeWithCachedSizes(
int UninterpretedOption::ByteSize() const {
int total_size = 0;
- if (_has_bits_[1 / 32] & 126) {
+ if (_has_bits_[1 / 32] & 126u) {
// optional string identifier_value = 3;
if (has_identifier_value()) {
total_size += 1 +
@@ -13248,7 +13249,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes(
int SourceCodeInfo_Location::ByteSize() const {
int total_size = 0;
- if (_has_bits_[2 / 32] & 12) {
+ if (_has_bits_[2 / 32] & 12u) {
// optional string leading_comments = 3;
if (has_leading_comments()) {
total_size += 1 +
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index 97741b6a..82de7b09 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -40,6 +40,7 @@
syntax = "proto2";
package google.protobuf;
+option go_package = "descriptor";
option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.DescriptorProtos";
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index c9f4ca7f..dd7c036e 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -33,8 +33,6 @@
// This file contains the implementation of classes GzipInputStream and
// GzipOutputStream.
-#include "config.h"
-
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index dd3d1285..f2e5b629 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -46,8 +46,6 @@
// "parametized tests" so that one set of tests can be used on all the
// implementations.
-#include "config.h"
-
#ifdef _MSC_VER
#include <io.h>
#else
diff --git a/src/google/protobuf/stubs/atomicops.h b/src/google/protobuf/stubs/atomicops.h
index bbe2d845..cd20caac 100644
--- a/src/google/protobuf/stubs/atomicops.h
+++ b/src/google/protobuf/stubs/atomicops.h
@@ -56,6 +56,7 @@
// Don't include this file for people not concerned about thread safety.
#ifndef GOOGLE_PROTOBUF_NO_THREAD_SAFETY
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/platform_macros.h>
namespace google {
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index 54e00ccb..22cc5aa1 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -36,8 +36,6 @@
#include <errno.h>
#include <vector>
-#include "config.h"
-
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN // We only need minimal includes
#include <windows.h>
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index 3acaeba1..49d16020 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -62,6 +62,8 @@
#include <exception>
#endif
+#include <google/protobuf/stubs/platform_macros.h>
+
#if defined(__APPLE__)
#include <TargetConditionals.h> // for TARGET_OS_IPHONE
#endif
@@ -258,7 +260,7 @@ static const uint64 kuint64max = GOOGLE_ULONGLONG(0xFFFFFFFFFFFFFFFF);
#ifndef GOOGLE_PREDICT_FALSE
#ifdef __GNUC__
// Provided at least since GCC 3.0.
-#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(!!(x), 1))
+#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0))
#else
#define GOOGLE_PREDICT_FALSE
#endif
@@ -1174,11 +1176,7 @@ class LIBPROTOBUF_EXPORT MutexLockMaybe {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MutexLockMaybe);
};
-#if defined(__ANDROID__) || defined(GOOGLE_PROTOBUF_OS_ANDROID) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
-// Android ndk does not support the __thread keyword very well yet. Here
-// we use pthread_key_create()/pthread_getspecific()/... methods for
-// TLS support on android.
-// iOS also does not support the __thread keyword.
+#if defined(GOOGLE_PROTOBUF_NO_THREADLOCAL)
template<typename T>
class ThreadLocalStorage {
public:
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
index 5f458e98..f9e2cfd4 100644
--- a/src/google/protobuf/stubs/common_unittest.cc
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -39,8 +39,6 @@
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
-#include "config.h"
-
namespace google {
namespace protobuf {
namespace {
diff --git a/src/google/protobuf/stubs/pbconfig.h b/src/google/protobuf/stubs/pbconfig.h
new file mode 100644
index 00000000..0f21c560
--- /dev/null
+++ b/src/google/protobuf/stubs/pbconfig.h
@@ -0,0 +1,142 @@
+// 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_STUBS_PBCONFIG_H__
+#define GOOGLE_PROTOBUF_STUBS_PBCONFIG_H__
+
+#define GOOGLE_PROTOBUF_HAVE_HASH_MAP 1
+#define GOOGLE_PROTOBUF_HAVE_HASH_SET 1
+
+// Use C++11 unordered_{map|set} if available.
+#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X)
+# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
+
+// For XCode >= 4.6: the compiler is clang with libc++.
+// For earlier XCode version: the compiler is gcc-4.2.1 with libstdc++.
+// libc++ provides <unordered_map> and friends even in non C++11 mode,
+// and it does not provide the tr1 library. Therefore the following macro
+// checks against this special case.
+// Note that we should not test the __APPLE_CC__ version number or the
+// __clang__ macro, since the new compiler can still use -stdlib=libstdc++, in
+// which case <unordered_map> is not compilable without -std=c++11
+#elif defined(__APPLE_CC__)
+# if defined(_LIBCPP_VERSION)
+# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
+# elif __GNUC__ >= 4
+# define GOOGLE_PROTOBUF_HAS_TR1
+# else
+// Not tested for gcc < 4... These setting can compile under 4.2.1 though.
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx
+# define GOOGLE_PROTOBUF_HASH_MAP_H <ext/hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <ext/hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# endif
+
+// Version checks for gcc.
+#elif defined(__GNUC__)
+// For GCC 4.x+, use tr1::unordered_map/set; otherwise, follow the
+// instructions from:
+// https://gcc.gnu.org/onlinedocs/libstdc++/manual/backwards.html
+# if __GNUC__ >= 4
+# define GOOGLE_PROTOBUF_HAS_TR1
+# elif __GNUC__ >= 3
+# define GOOGLE_PROTOBUF_HASH_MAP_H <backward/hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <backward/hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# if __GNUC__ == 3 && __GNUC_MINOR__ == 0
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std // GCC 3.0
+# else
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE __gnu_cxx // GCC 3.1 and later
+# endif
+# else
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE
+# define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# endif
+
+// Version checks for MSC.
+// Apparently Microsoft decided to move hash_map *back* to the std namespace in
+// MSVC 2010:
+// http://blogs.msdn.com/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
+// And.. they are moved back to stdext in MSVC 2013 (haven't checked 2012). That
+// said, use unordered_map for MSVC 2010 and beyond is our safest bet.
+#elif defined(_MSC_VER)
+# if _MSC_VER >= 1600 // Since Visual Studio 2010
+# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
+# define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
+# elif _MSC_VER >= 1500 // Since Visual Studio 2008
+# define GOOGLE_PROTOBUF_HAS_TR1
+# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# elif _MSC_VER >= 1310
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
+# define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# else
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std
+# define GOOGLE_PROTOBUF_HASH_MAP_H <hash_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS hash_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <hash_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS hash_set
+# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# endif
+
+// **ADD NEW COMPILERS SUPPORT HERE.**
+// For other compilers, undefine the macro and fallback to use std::map, in
+// google/protobuf/stubs/hash.h
+#else
+# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
+# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
+#endif
+
+#if defined(GOOGLE_PROTOBUF_HAS_CXX11_HASH)
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std
+# define GOOGLE_PROTOBUF_HASH_MAP_H <unordered_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <unordered_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
+#elif defined(GOOGLE_PROTOBUF_HAS_TR1)
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE std::tr1
+# define GOOGLE_PROTOBUF_HASH_MAP_H <tr1/unordered_map>
+# define GOOGLE_PROTOBUF_HASH_MAP_CLASS unordered_map
+# define GOOGLE_PROTOBUF_HASH_SET_H <tr1/unordered_set>
+# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
+#endif
+
+#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
+#undef GOOGLE_PROTOBUF_HAS_TR1
+
+#endif // GOOGLE_PROTOBUF_STUBS_PBCONFIG_H__
diff --git a/src/google/protobuf/stubs/platform_macros.h b/src/google/protobuf/stubs/platform_macros.h
index 2ce7fc8f..9e0344d8 100644
--- a/src/google/protobuf/stubs/platform_macros.h
+++ b/src/google/protobuf/stubs/platform_macros.h
@@ -31,8 +31,6 @@
#ifndef GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
#define GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
-#include <google/protobuf/stubs/common.h>
-
#define GOOGLE_PROTOBUF_PLATFORM_ERROR \
#error "Host platform was not detected as supported by protobuf"
@@ -111,4 +109,12 @@ GOOGLE_PROTOBUF_PLATFORM_ERROR
#undef GOOGLE_PROTOBUF_PLATFORM_ERROR
+#if defined(GOOGLE_PROTOBUF_OS_ANDROID) || defined(GOOGLE_PROTOBUF_OS_IPHONE)
+// Android ndk does not support the __thread keyword very well yet. Here
+// we use pthread_key_create()/pthread_getspecific()/... methods for
+// TLS support on android.
+// iOS also does not support the __thread keyword.
+#define GOOGLE_PROTOBUF_NO_THREADLOCAL
+#endif
+
#endif // GOOGLE_PROTOBUF_PLATFORM_MACROS_H_
diff --git a/src/google/protobuf/testing/zcgunzip.cc b/src/google/protobuf/testing/zcgunzip.cc
index daf74ff1..c9d085c8 100644
--- a/src/google/protobuf/testing/zcgunzip.cc
+++ b/src/google/protobuf/testing/zcgunzip.cc
@@ -38,8 +38,6 @@
// Reads gzip stream on standard input and writes decompressed data to standard
// output.
-#include "config.h"
-
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/google/protobuf/testing/zcgzip.cc b/src/google/protobuf/testing/zcgzip.cc
index a4101999..e910f321 100644
--- a/src/google/protobuf/testing/zcgzip.cc
+++ b/src/google/protobuf/testing/zcgzip.cc
@@ -38,8 +38,6 @@
// Reads data on standard input and writes compressed gzip stream to standard
// output.
-#include "config.h"
-
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>