diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 15 | ||||
-rw-r--r-- | src/google/protobuf/compiler/command_line_interface.cc | 6 | ||||
-rw-r--r-- | src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc | 91 | ||||
-rw-r--r-- | src/google/protobuf/compiler/java/java_message.cc | 21 | ||||
-rw-r--r-- | src/google/protobuf/compiler/java/java_message_lite.cc | 15 | ||||
-rw-r--r-- | src/google/protobuf/compiler/java/java_primitive_field.cc | 26 | ||||
-rw-r--r-- | src/google/protobuf/compiler/mock_code_generator.cc | 9 | ||||
-rw-r--r-- | src/google/protobuf/compiler/php/php_generator.cc | 28 | ||||
-rw-r--r-- | src/google/protobuf/stubs/bytestream.h | 2 | ||||
-rw-r--r-- | src/google/protobuf/stubs/shared_ptr.h | 7 | ||||
-rw-r--r-- | src/google/protobuf/unittest.proto | 4 | ||||
-rw-r--r-- | src/google/protobuf/util/internal/protostream_objectwriter_test.cc | 22 | ||||
-rw-r--r-- | src/google/protobuf/util/internal/testdata/books.proto | 9 | ||||
-rw-r--r-- | src/google/protobuf/util/internal/type_info.cc | 24 | ||||
-rw-r--r-- | src/libprotobuf-lite.map | 9 | ||||
-rw-r--r-- | src/libprotobuf.map | 9 | ||||
-rw-r--r-- | src/libprotoc.map | 9 |
17 files changed, 258 insertions, 48 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 8c25a10a..6a91044d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -180,6 +180,10 @@ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) libprotobuf_lite_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotobuf_lite_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf-lite.map +EXTRA_libprotobuf_lite_la_DEPENDENCIES = libprotobuf-lite.map +endif libprotobuf_lite_la_SOURCES = \ google/protobuf/stubs/atomicops_internals_x86_gcc.cc \ google/protobuf/stubs/atomicops_internals_x86_msvc.cc \ @@ -221,6 +225,10 @@ libprotobuf_lite_la_SOURCES = \ libprotobuf_la_LIBADD = $(PTHREAD_LIBS) libprotobuf_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotobuf_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf.map +EXTRA_libprotobuf_la_DEPENDENCIES = libprotobuf.map +endif libprotobuf_la_SOURCES = \ $(libprotobuf_lite_la_SOURCES) \ google/protobuf/any.pb.cc \ @@ -305,6 +313,10 @@ nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES) libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +if HAVE_LD_VERSION_SCRIPT +libprotoc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotoc.map +EXTRA_libprotoc_la_DEPENDENCIES = libprotoc.map +endif libprotoc_la_SOURCES = \ google/protobuf/compiler/code_generator.cc \ google/protobuf/compiler/command_line_interface.cc \ @@ -580,6 +592,9 @@ EXTRA_DIST = \ google/protobuf/compiler/ruby/ruby_generated_code_pb.rb \ google/protobuf/compiler/package_info.h \ google/protobuf/compiler/zip_output_unittest.sh \ + libprotobuf-lite.map \ + libprotobuf.map \ + libprotoc.map \ README.md protoc_lite_outputs = \ diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 99d71381..f516477b 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -37,6 +37,12 @@ #include <stdio.h> #include <sys/types.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif #include <sys/stat.h> #include <fcntl.h> #ifdef _MSC_VER diff --git a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc index c1f90e41..4e44b578 100644 --- a/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc @@ -34,8 +34,8 @@ // generated automatically at build time. // // If this test fails, run the script -// "generate_descriptor_proto.sh" and add -// csharp/src/Google.Protobuf/Reflection/Descriptor.cs to your changelist. +// "generate_descriptor_proto.sh" and add the changed files under +// csharp/src/ to your changelist. #include <map> @@ -91,7 +91,8 @@ class MockGeneratorContext : public GeneratorContext { string actual_contents; GOOGLE_CHECK_OK( File::GetContents(TestSourceDir() + "/" + physical_filename, - &actual_contents, true)); + &actual_contents, true)) + << "Unable to get " << physical_filename; EXPECT_TRUE(actual_contents == *expected_contents) << physical_filename << " needs to be regenerated. Please run " "generate_descriptor_proto.sh. Then add this file " @@ -112,26 +113,80 @@ class MockGeneratorContext : public GeneratorContext { std::map<string, string*> files_; }; +class GenerateAndTest { + public: + GenerateAndTest() {} + void Run(const FileDescriptor* proto_file, string file1, string file2) { + ASSERT_TRUE(proto_file != NULL) << TestSourceDir(); + ASSERT_TRUE(generator_.Generate(proto_file, parameter_, + &context_, &error_)); + context_.ExpectFileMatches(file1, file2); + } + void SetParameter(string parameter) { + parameter_ = parameter; + } + + private: + Generator generator_; + MockGeneratorContext context_; + string error_; + string parameter_; +}; + TEST(CsharpBootstrapTest, GeneratedCsharpDescriptorMatches) { MockErrorCollector error_collector; DiskSourceTree source_tree; - source_tree.MapPath("", TestSourceDir()); Importer importer(&source_tree, &error_collector); - const FileDescriptor* proto_file = - importer.Import("google/protobuf/descriptor.proto"); + GenerateAndTest generate_test; + + generate_test.SetParameter("base_namespace=Google.Protobuf"); + source_tree.MapPath("", TestSourceDir()); + generate_test.Run(importer.Import("google/protobuf/descriptor.proto"), + "Reflection/Descriptor.cs", + "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"); + generate_test.Run(importer.Import("google/protobuf/any.proto"), + "WellKnownTypes/Any.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Any.cs"); + generate_test.Run(importer.Import("google/protobuf/api.proto"), + "WellKnownTypes/Api.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Api.cs"); + generate_test.Run(importer.Import("google/protobuf/duration.proto"), + "WellKnownTypes/Duration.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs"); + generate_test.Run(importer.Import("google/protobuf/empty.proto"), + "WellKnownTypes/Empty.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Empty.cs"); + generate_test.Run(importer.Import("google/protobuf/field_mask.proto"), + "WellKnownTypes/FieldMask.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/FieldMask.cs"); + generate_test.Run(importer.Import("google/protobuf/source_context.proto"), + "WellKnownTypes/SourceContext.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/SourceContext.cs"); + generate_test.Run(importer.Import("google/protobuf/struct.proto"), + "WellKnownTypes/Struct.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Struct.cs"); + generate_test.Run(importer.Import("google/protobuf/timestamp.proto"), + "WellKnownTypes/Timestamp.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs"); + generate_test.Run(importer.Import("google/protobuf/type.proto"), + "WellKnownTypes/Type.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Type.cs"); + generate_test.Run(importer.Import("google/protobuf/wrappers.proto"), + "WellKnownTypes/Wrappers.cs", + "../csharp/src/Google.Protobuf/WellKnownTypes/Wrappers.cs"); + + generate_test.SetParameter(""); + source_tree.MapPath("", TestSourceDir() + "/../examples"); + generate_test.Run(importer.Import("addressbook.proto"), + "Addressbook.cs", + "../csharp/src/AddressBook/Addressbook.cs"); + + source_tree.MapPath("", TestSourceDir() + "/../conformance"); + generate_test.Run(importer.Import("conformance.proto"), + "Conformance.cs", + "../csharp/src/Google.Protobuf.Conformance/Conformance.cs"); + EXPECT_EQ("", error_collector.text_); - ASSERT_TRUE(proto_file != NULL); - - Generator generator; - MockGeneratorContext context; - string error; - string parameter = "base_namespace=Google.Protobuf"; - ASSERT_TRUE(generator.Generate(proto_file, parameter, - &context, &error)); - - context.ExpectFileMatches( - "Reflection/Descriptor.cs", - "../csharp/src/Google.Protobuf/Reflection/Descriptor.cs"); } } // namespace diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index df4db463..3b8d7ab8 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -253,18 +253,22 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessage$ver$.\n" " ExtendableMessageOrBuilder<$classname$> {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", "", "ver", GeneratedCodeVersionSuffix()); } else { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageOrBuilder {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); @@ -304,6 +308,8 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); variables["ver"] = GeneratedCodeVersionSuffix(); + variables["deprecation"] = descriptor_->options().deprecated() + ? "@java.lang.Deprecated " : ""; WriteMessageDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, @@ -312,8 +318,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { // The builder_type stores the super type name of the nested Builder class. string builder_type; if (descriptor_->extension_range_count() > 0) { - printer->Print(variables, - "public $static$final class $classname$ extends\n"); + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); printer->Annotate("classname", descriptor_); printer->Print( variables, @@ -326,8 +333,9 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) { name_resolver_->GetImmutableClassName(descriptor_), GeneratedCodeVersionSuffix()); } else { - printer->Print(variables, - "public $static$final class $classname$ extends\n"); + printer->Print( + variables, + "$deprecation$public $static$final class $classname$ extends\n"); printer->Annotate("classname", descriptor_); printer->Print(variables, " com.google.protobuf.GeneratedMessage$ver$ implements\n" @@ -1445,6 +1453,7 @@ void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) { "\n" "private volatile com.google.protobuf.Message cachedUnpackValue;\n" "\n" + "@java.lang.SuppressWarnings(\"unchecked\")\n" "public <T extends com.google.protobuf.Message> T unpack(\n" " java.lang.Class<T> clazz)\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n" diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 048d5892..e84321bb 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -124,19 +124,23 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { /* immutable = */ true, "OrBuilder"); if (descriptor_->extension_range_count() > 0) { printer->Print( - "public interface $classname$OrBuilder$idend$ extends \n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends \n" " $extra_interfaces$\n" " com.google.protobuf.GeneratedMessageLite.\n" " ExtendableMessageOrBuilder<\n" " $classname$, $classname$.Builder> {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); } else { printer->Print( - "public interface $classname$OrBuilder$idend$ extends\n" + "$deprecation$public interface $classname$OrBuilder$idend$ extends\n" " $extra_interfaces$\n" " com.google.protobuf.MessageLiteOrBuilder {\n", + "deprecation", descriptor_->options().deprecated() ? + "@java.lang.Deprecated " : "", "extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_), "classname", descriptor_->name(), "idend", ""); @@ -174,6 +178,8 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { variables["static"] = is_own_file ? " " : " static "; variables["classname"] = descriptor_->name(); variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_); + variables["deprecation"] = descriptor_->options().deprecated() + ? "@java.lang.Deprecated " : ""; WriteMessageDocComment(printer, descriptor_); MaybePrintGeneratedAnnotation(context_, printer, descriptor_, @@ -184,7 +190,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { string builder_type; if (descriptor_->extension_range_count() > 0) { printer->Print(variables, - "public $static$final class $classname$ extends\n" + "$deprecation$public $static$final class $classname$ extends\n" " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" " $classname$, $classname$.Builder> implements\n" " $extra_interfaces$\n" @@ -194,7 +200,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { name_resolver_->GetImmutableClassName(descriptor_)); } else { printer->Print(variables, - "public $static$final class $classname$ extends\n" + "$deprecation$public $static$final class $classname$ extends\n" " com.google.protobuf.GeneratedMessageLite<\n" " $classname$, $classname$.Builder> implements\n" " $extra_interfaces$\n" @@ -339,6 +345,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { } printer->Print( + "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" "protected final Object dynamicMethod(\n" " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" " Object arg0, Object arg1) {\n" diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc index fa1047e8..840252e7 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field.cc @@ -523,8 +523,17 @@ void ImmutablePrimitiveOneofFieldGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, "if ($has_oneof_case_message$) {\n" - " output.write$capitalized_type$(\n" - " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + " output.write$capitalized_type$(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, + " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print(variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print( "}\n"); } @@ -533,8 +542,17 @@ GenerateSerializedSizeCode(io::Printer* printer) const { printer->Print(variables_, "if ($has_oneof_case_message$) {\n" " size += com.google.protobuf.CodedOutputStream\n" - " .compute$capitalized_type$Size(\n" - " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n" + " .compute$capitalized_type$Size(\n"); + // $type$ and $boxed_type$ is the same for bytes fields so we don't need to + // do redundant casts. + if (GetJavaType(descriptor_) == JAVATYPE_BYTES) { + printer->Print(variables_, + " $number$, ($type$) $oneof_name$_);\n"); + } else { + printer->Print(variables_, + " $number$, ($type$)(($boxed_type$) $oneof_name$_));\n"); + } + printer->Print( "}\n"); } diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index e82e6ae1..a4b522ce 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -40,7 +40,6 @@ #endif #include <vector> -#include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/stubs/logging.h> #include <google/protobuf/stubs/common.h> #include <google/protobuf/testing/file.h> @@ -54,6 +53,14 @@ #include <google/protobuf/stubs/substitute.h> #include <gtest/gtest.h> +#ifdef major +#undef major +#endif +#ifdef minor +#undef minor +#endif +#include <google/protobuf/compiler/plugin.pb.h> + namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index ec9a2365..7f35d712 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -439,9 +439,31 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, // Type check. if (field->is_map()) { + const Descriptor* map_entry = field->message_type(); + const FieldDescriptor* key = map_entry->FindFieldByName("key"); + const FieldDescriptor* value = map_entry->FindFieldByName("value"); + printer->Print( + "$arr = GPBUtil::checkMapField($var, " + "\\Google\\Protobuf\\Internal\\GPBType::^key_type^, " + "\\Google\\Protobuf\\Internal\\GPBType::^value_type^", + "key_type", ToUpper(key->type_name()), + "value_type", ToUpper(value->type_name())); + if (value->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + printer->Print( + ", \\^class_name^);\n", + "class_name", + MessageName(value->message_type(), is_descriptor) + "::class"); + } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { + printer->Print( + ", ^class_name^);\n", + "class_name", + EnumName(value->enum_type(), is_descriptor) + "::class"); + } else { + printer->Print(");\n"); + } } else if (field->is_repeated()) { printer->Print( - "GPBUtil::checkRepeatedField($var, " + "$arr = GPBUtil::checkRepeatedField($var, " "\\Google\\Protobuf\\Internal\\GPBType::^type^", "type", ToUpper(field->type_name())); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { @@ -480,6 +502,10 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( "$this->writeOneof(^number^, $var);\n", "number", IntToString(field->number())); + } else if (field->is_repeated()) { + printer->Print( + "$this->^name^ = $arr;\n", + "name", field->name()); } else { printer->Print( "$this->^name^ = $var;\n", diff --git a/src/google/protobuf/stubs/bytestream.h b/src/google/protobuf/stubs/bytestream.h index 07604e17..86510d14 100644 --- a/src/google/protobuf/stubs/bytestream.h +++ b/src/google/protobuf/stubs/bytestream.h @@ -64,7 +64,7 @@ namespace protobuf { namespace strings { // An abstract interface for an object that consumes a sequence of bytes. This -// interface offers 3 different ways to append data, and a Flush() function. +// interface offers a way to append data as well as a Flush() function. // // Example: // diff --git a/src/google/protobuf/stubs/shared_ptr.h b/src/google/protobuf/stubs/shared_ptr.h index d250bf4d..7da114e9 100644 --- a/src/google/protobuf/stubs/shared_ptr.h +++ b/src/google/protobuf/stubs/shared_ptr.h @@ -428,11 +428,11 @@ class enable_shared_from_this { shared_ptr<T> shared_from_this() { // Behavior is undefined if the precondition isn't satisfied; we choose // to die with a CHECK failure. - CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; return weak_this_.lock(); } shared_ptr<const T> shared_from_this() const { - CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; + GOOGLE_CHECK(!weak_this_.expired()) << "No shared_ptr owns this object"; return weak_this_.lock(); } @@ -456,7 +456,8 @@ class enable_shared_from_this { template<typename T> void shared_ptr<T>::MaybeSetupWeakThis(enable_shared_from_this<T>* ptr) { if (ptr) { - CHECK(ptr->weak_this_.expired()) << "Object already owned by a shared_ptr"; + GOOGLE_CHECK(ptr->weak_this_.expired()) + << "Object already owned by a shared_ptr"; ptr->weak_this_ = *this; } } diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 96289cc5..188a4f47 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -191,6 +191,10 @@ message TestDeprecatedFields { optional int32 deprecated_int32 = 1 [deprecated=true]; } +message TestDeprecatedMessage { + option deprecated = true; +} + // Define these after TestAllTypes to make sure the compiler can handle // that. message ForeignMessage { diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index a9b15e68..97ef8fff 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -74,6 +74,8 @@ using google::protobuf::testing::Primitive; using google::protobuf::testing::Proto3Message; using google::protobuf::testing::Publisher; using google::protobuf::testing::StructType; +using google::protobuf::testing::TestJsonName1; +using google::protobuf::testing::TestJsonName2; using google::protobuf::testing::TimestampDuration; using google::protobuf::testing::ValueWrapper; using google::protobuf::testing::oneofs::OneOfsRequest; @@ -271,6 +273,26 @@ TEST_P(ProtoStreamObjectWriterTest, CustomJsonName) { CheckOutput(book); } +// Test that two messages can have different fields mapped to the same JSON +// name. See: https://github.com/google/protobuf/issues/1415 +TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) { + ResetTypeInfo(TestJsonName1::descriptor()); + TestJsonName1 message1; + message1.set_one_value(12345); + ow_->StartObject("") + ->RenderInt32("value", 12345) + ->EndObject(); + CheckOutput(message1); + + ResetTypeInfo(TestJsonName2::descriptor()); + TestJsonName2 message2; + message2.set_another_value(12345); + ow_->StartObject("") + ->RenderInt32("value", 12345) + ->EndObject(); + CheckOutput(message2); +} + TEST_P(ProtoStreamObjectWriterTest, IntEnumValuesAreAccepted) { Book book; book.set_title("Some Book"); diff --git a/src/google/protobuf/util/internal/testdata/books.proto b/src/google/protobuf/util/internal/testdata/books.proto index 9fe4f7aa..869271f4 100644 --- a/src/google/protobuf/util/internal/testdata/books.proto +++ b/src/google/protobuf/util/internal/testdata/books.proto @@ -190,3 +190,12 @@ message Cyclic { repeated Author m_author = 5; optional Cyclic m_cyclic = 4; } + +// Test that two messages can have different fields mapped to the same JSON +// name. See: https://github.com/google/protobuf/issues/1415 +message TestJsonName1 { + optional int32 one_value = 1 [json_name = "value"]; +} +message TestJsonName2 { + optional int32 another_value = 1 [json_name = "value"]; +} diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index 17d58475..a5d903f1 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -107,12 +107,12 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual const google::protobuf::Field* FindField( const google::protobuf::Type* type, StringPiece camel_case_name) const { - if (indexed_types_.find(type) == indexed_types_.end()) { - PopulateNameLookupTable(type); - indexed_types_.insert(type); - } + std::map<const google::protobuf::Type*, + CamelCaseNameTable>::const_iterator it = indexed_types_.find(type); + const CamelCaseNameTable& camel_case_name_table = (it == indexed_types_.end()) + ? PopulateNameLookupTable(type, &indexed_types_[type]) : it->second; StringPiece name = - FindWithDefault(camel_case_name_table_, camel_case_name, StringPiece()); + FindWithDefault(camel_case_name_table, camel_case_name, StringPiece()); if (name.empty()) { // Didn't find a mapping. Use whatever provided. name = camel_case_name; @@ -123,6 +123,7 @@ class TypeInfoForTypeResolver : public TypeInfo { private: typedef util::StatusOr<const google::protobuf::Type*> StatusOrType; typedef util::StatusOr<const google::protobuf::Enum*> StatusOrEnum; + typedef std::map<StringPiece, StringPiece> CamelCaseNameTable; template <typename T> static void DeleteCachedTypes(std::map<StringPiece, T>* cached_types) { @@ -134,32 +135,35 @@ class TypeInfoForTypeResolver : public TypeInfo { } } - void PopulateNameLookupTable(const google::protobuf::Type* type) const { + const CamelCaseNameTable& PopulateNameLookupTable( + const google::protobuf::Type* type, + CamelCaseNameTable* camel_case_name_table) const { for (int i = 0; i < type->fields_size(); ++i) { const google::protobuf::Field& field = type->fields(i); StringPiece name = field.name(); StringPiece camel_case_name = field.json_name(); const StringPiece* existing = InsertOrReturnExisting( - &camel_case_name_table_, camel_case_name, name); + camel_case_name_table, camel_case_name, name); if (existing && *existing != name) { GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing << "' map to the same camel case name '" << camel_case_name << "'."; } } + return *camel_case_name_table; } TypeResolver* type_resolver_; // Stores string values that will be referenced by StringPieces in - // cached_types_, cached_enums_ and camel_case_name_table_. + // cached_types_, cached_enums_. mutable std::set<string> string_storage_; mutable std::map<StringPiece, StatusOrType> cached_types_; mutable std::map<StringPiece, StatusOrEnum> cached_enums_; - mutable std::set<const google::protobuf::Type*> indexed_types_; - mutable std::map<StringPiece, StringPiece> camel_case_name_table_; + mutable std::map<const google::protobuf::Type*, + CamelCaseNameTable> indexed_types_; }; } // namespace diff --git a/src/libprotobuf-lite.map b/src/libprotobuf-lite.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotobuf-lite.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; diff --git a/src/libprotobuf.map b/src/libprotobuf.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotobuf.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; diff --git a/src/libprotoc.map b/src/libprotoc.map new file mode 100644 index 00000000..39155466 --- /dev/null +++ b/src/libprotoc.map @@ -0,0 +1,9 @@ +{ + global: + extern "C++" { + *google*; + }; + + local: + *; +}; |