aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am45
-rw-r--r--src/google/protobuf/any.pb.cc21
-rw-r--r--src/google/protobuf/api.pb.cc39
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc5
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc26
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.cc205
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.h4
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc12
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc2
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum.cc4
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_generator.cc3
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_options.h9
-rw-r--r--src/google/protobuf/compiler/java/java_file.cc18
-rw-r--r--src/google/protobuf/compiler/java/java_generator.cc2
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc62
-rw-r--r--src/google/protobuf/compiler/java/java_message_builder.cc93
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc2
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc6
-rwxr-xr-xsrc/google/protobuf/compiler/js/js_generator.cc160
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum.cc18
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc14
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_extension.cc4
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_field.cc8
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.cc455
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_file.h15
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_generator.cc76
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_generator.h11
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.cc413
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_helpers.h67
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_map_field.cc2
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_message.cc18
-rw-r--r--src/google/protobuf/compiler/objectivec/objectivec_oneof.cc8
-rw-r--r--src/google/protobuf/compiler/parser.cc1
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc37
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc60
-rw-r--r--src/google/protobuf/compiler/python/python_plugin_unittest.cc48
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb (renamed from src/google/protobuf/compiler/ruby/ruby_generated_code.rb)0
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator.cc60
-rw-r--r--src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc4
-rw-r--r--src/google/protobuf/compiler/subprocess.cc12
-rw-r--r--src/google/protobuf/descriptor.pb.cc237
-rw-r--r--src/google/protobuf/descriptor.proto1
-rw-r--r--src/google/protobuf/duration.pb.cc23
-rw-r--r--src/google/protobuf/empty.pb.cc21
-rw-r--r--src/google/protobuf/extension_set_heavy.cc2
-rw-r--r--src/google/protobuf/field_mask.pb.cc21
-rw-r--r--src/google/protobuf/generated_message_util.cc6
-rw-r--r--src/google/protobuf/generated_message_util.h11
-rw-r--r--src/google/protobuf/io/coded_stream.cc8
-rw-r--r--src/google/protobuf/io/coded_stream.h47
-rw-r--r--src/google/protobuf/map.h2
-rw-r--r--src/google/protobuf/map_entry_lite.h26
-rw-r--r--src/google/protobuf/map_proto2_unittest.proto20
-rw-r--r--src/google/protobuf/map_test.cc77
-rw-r--r--src/google/protobuf/map_type_handler.h18
-rw-r--r--src/google/protobuf/message.cc2
-rw-r--r--src/google/protobuf/message.h2
-rw-r--r--src/google/protobuf/message_lite.cc2
-rw-r--r--src/google/protobuf/message_lite.h2
-rw-r--r--src/google/protobuf/repeated_field_reflection.h337
-rw-r--r--src/google/protobuf/source_context.pb.cc21
-rw-r--r--src/google/protobuf/struct.pb.cc156
-rw-r--r--src/google/protobuf/stubs/atomicops_internals_generic_gcc.h18
-rw-r--r--src/google/protobuf/stubs/callback.h4
-rw-r--r--src/google/protobuf/stubs/common_unittest.cc2
-rw-r--r--src/google/protobuf/stubs/int128.cc6
-rw-r--r--src/google/protobuf/stubs/map_util.h7
-rw-r--r--src/google/protobuf/stubs/once_unittest.cc5
-rw-r--r--src/google/protobuf/stubs/port.h20
-rw-r--r--src/google/protobuf/testdata/golden_message_mapsbin0 -> 13619 bytes
-rw-r--r--src/google/protobuf/testing/file.cc17
-rw-r--r--src/google/protobuf/text_format.cc14
-rw-r--r--src/google/protobuf/timestamp.pb.cc23
-rw-r--r--src/google/protobuf/type.pb.cc55
-rw-r--r--src/google/protobuf/unknown_field_set.cc28
-rw-r--r--src/google/protobuf/unknown_field_set.h8
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc34
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.h12
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter_test.cc33
-rw-r--r--src/google/protobuf/util/internal/proto_writer.cc34
-rw-r--r--src/google/protobuf/util/internal/proto_writer.h9
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.cc2
-rw-r--r--src/google/protobuf/util/json_util.cc60
-rw-r--r--src/google/protobuf/util/json_util.h29
-rw-r--r--src/google/protobuf/util/json_util_test.cc88
-rw-r--r--src/google/protobuf/util/message_differencer.cc3
-rw-r--r--src/google/protobuf/util/time_util.cc9
-rw-r--r--src/google/protobuf/wire_format_lite.cc6
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h10
-rw-r--r--src/google/protobuf/wrappers.pb.cc85
90 files changed, 2320 insertions, 1392 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index b75b6f74..f70e9550 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -19,8 +19,9 @@ PTHREAD_DEF =
endif
if GCC
-# These are good warnings to turn on by default
-NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) -Wall -Wwrite-strings -Woverloaded-virtual -Wno-sign-compare
+# Turn on all warnings except for sign comparison (we ignore sign comparison
+# in Google so our code base have tons of such warnings).
+NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) -Wall -Wno-sign-compare
else
NO_OPT_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF)
endif
@@ -32,6 +33,10 @@ AM_LDFLAGS = $(PTHREAD_CFLAGS)
# If I say "dist_include_DATA", automake complains that $(includedir) is not
# a "legitimate" directory for DATA. Screw you, automake.
protodir = $(includedir)
+
+# If you are adding new files here, also remember to change the build files for
+# all other languages, //protoc-artifacts/build-zip.sh and run
+# //update_file_list.sh for bazel.
nobase_dist_proto_DATA = google/protobuf/descriptor.proto \
google/protobuf/any.proto \
google/protobuf/api.proto \
@@ -50,7 +55,8 @@ clean-local:
rm -f *.loT
CLEANFILES = $(protoc_outputs) unittest_proto_middleman \
- testzip.jar testzip.list testzip.proto testzip.zip
+ testzip.jar testzip.list testzip.proto testzip.zip \
+ no_warning_test.cc
MAINTAINERCLEANFILES = \
Makefile.in
@@ -59,6 +65,7 @@ nobase_include_HEADERS = \
google/protobuf/stubs/atomic_sequence_num.h \
google/protobuf/stubs/atomicops.h \
google/protobuf/stubs/atomicops_internals_power.h \
+ google/protobuf/stubs/atomicops_internals_ppc_gcc.h \
google/protobuf/stubs/atomicops_internals_arm64_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_gcc.h \
google/protobuf/stubs/atomicops_internals_arm_qnx.h \
@@ -121,7 +128,6 @@ nobase_include_HEADERS = \
google/protobuf/reflection.h \
google/protobuf/reflection_ops.h \
google/protobuf/repeated_field.h \
- google/protobuf/repeated_field_reflection.h \
google/protobuf/service.h \
google/protobuf/source_context.pb.h \
google/protobuf/struct.pb.h \
@@ -530,6 +536,7 @@ EXTRA_DIST = \
google/protobuf/io/gzip_stream.h \
google/protobuf/io/gzip_stream_unittest.sh \
google/protobuf/testdata/golden_message \
+ google/protobuf/testdata/golden_message_maps \
google/protobuf/testdata/golden_message_oneof_implemented \
google/protobuf/testdata/golden_message_proto3 \
google/protobuf/testdata/golden_packed_fields_message \
@@ -544,9 +551,10 @@ EXTRA_DIST = \
google/protobuf/package_info.h \
google/protobuf/io/package_info.h \
google/protobuf/compiler/ruby/ruby_generated_code.proto \
- google/protobuf/compiler/ruby/ruby_generated_code.rb \
+ google/protobuf/compiler/ruby/ruby_generated_code_pb.rb \
google/protobuf/compiler/package_info.h \
- google/protobuf/compiler/zip_output_unittest.sh
+ google/protobuf/compiler/zip_output_unittest.sh \
+ README.md
protoc_lite_outputs = \
google/protobuf/map_lite_unittest.pb.cc \
@@ -677,7 +685,7 @@ COMMON_TEST_SOURCES = \
check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \
protobuf-lite-test test_plugin protobuf-lite-arena-test \
- $(GZCHECKPROGRAMS)
+ no-warning-test $(GZCHECKPROGRAMS)
protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
../gmock/gtest/lib/libgtest.la \
../gmock/lib/libgmock.la \
@@ -830,6 +838,27 @@ zcgunzip_LDADD = $(PTHREAD_LIBS) libprotobuf.la
zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
endif
+# This test target is to ensure all our public header files and generated
+# code is free from warnings. We have to be more pedantic about these
+# files because they are compiled by users with different compiler flags.
+no_warning_test.cc:
+ echo "// Generated from Makefile.am" > no_warning_test.cc
+ for FILE in $(nobase_include_HEADERS); do \
+ if ! echo $${FILE} | grep "atomicops"; then \
+ echo "#include <$${FILE}>" >> no_warning_test.cc; \
+ fi \
+ done
+ echo "#include <gtest/gtest.h>" >> no_warning_test.cc
+ echo "TEST(NoWarningTest, Empty) {}" >> no_warning_test.cc
+
+no_warning_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la \
+ ../gmock/gtest/lib/libgtest.la \
+ ../gmock/gtest/lib/libgtest_main.la
+no_warning_test_CPPFLAGS = -I$(srcdir)/../gmock/gtest/include
+no_warning_test_CXXFLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_DEF) $(ZLIB_DEF) \
+ -Wall -Werror
+nodist_no_warning_test_SOURCES = no_warning_test.cc $(protoc_outputs)
+
TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS) \
- protobuf-lite-arena-test
+ protobuf-lite-arena-test no-warning-test
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index c91faa08..ccccc9c1 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fany_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fany_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -74,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fany_2eproto() {
delete Any_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fany_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fany_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fany_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
void Any::PackFrom(const ::google::protobuf::Message& message) {
@@ -334,7 +327,9 @@ int Any::ByteSize() const {
void Any::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Any)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Any* source =
::google::protobuf::internal::DynamicCastToGenerated<const Any>(
&from);
@@ -349,7 +344,9 @@ void Any::MergeFrom(const ::google::protobuf::Message& from) {
void Any::MergeFrom(const Any& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.type_url().size() > 0) {
type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_);
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index d5dd8923..e8c2a178 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -35,6 +35,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -109,6 +110,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -130,6 +132,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() {
delete Mixin_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -175,16 +178,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fapi_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fapi_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -601,7 +594,9 @@ int Api::ByteSize() const {
void Api::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Api)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Api* source =
::google::protobuf::internal::DynamicCastToGenerated<const Api>(
&from);
@@ -616,7 +611,9 @@ void Api::MergeFrom(const ::google::protobuf::Message& from) {
void Api::MergeFrom(const Api& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
methods_.MergeFrom(from.methods_);
options_.MergeFrom(from.options_);
mixins_.MergeFrom(from.mixins_);
@@ -1008,7 +1005,7 @@ void Method::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -1345,7 +1342,9 @@ int Method::ByteSize() const {
void Method::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Method)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Method* source =
::google::protobuf::internal::DynamicCastToGenerated<const Method>(
&from);
@@ -1360,7 +1359,9 @@ void Method::MergeFrom(const ::google::protobuf::Message& from) {
void Method::MergeFrom(const Method& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -1858,7 +1859,9 @@ int Mixin::ByteSize() const {
void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Mixin)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Mixin* source =
::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
&from);
@@ -1873,7 +1876,9 @@ void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
void Mixin::MergeFrom(const Mixin& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 0ebf9b6a..dee438c6 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -719,6 +719,11 @@ TEST_F(CommandLineInterfaceTest, TrailingBackslash) {
ExpectGenerated("test_generator", "", "foo.proto", "Foo");
}
+TEST_F(CommandLineInterfaceTest, Win32ErrorMessage) {
+ EXPECT_EQ("The system cannot find the file specified.\r\n",
+ Subprocess::Win32ErrorMessage(ERROR_FILE_NOT_FOUND));
+}
+
#endif // defined(_WIN32) || defined(__CYGWIN__)
TEST_F(CommandLineInterfaceTest, PathLookup) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 385b973e..b3eca660 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -336,19 +336,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
// Generate classes.
for (int i = 0; i < file_->message_type_count(); i++) {
- if (i == 0 && HasGeneratedMethods(file_, options_)) {
- printer->Print(
- "\n"
- "namespace {\n"
- "\n"
- "static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;\n"
- "static void MergeFromFail(int line) {\n"
- " GOOGLE_CHECK(false) << __FILE__ << \":\" << line;\n"
- "}\n"
- "\n"
- "} // namespace\n"
- "\n");
- }
printer->Print("\n");
printer->Print(kThickSeparator);
printer->Print("\n");
@@ -464,9 +451,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// and we only use AddDescriptors() to allocate default instances.
if (HasDescriptorMethods(file_, options_)) {
printer->Print(
- "\n"
- "void $assigndescriptorsname$() {\n",
- "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
+ "\n"
+ "void $assigndescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
+ "void $assigndescriptorsname$() {\n",
+ "assigndescriptorsname", GlobalAssignDescriptorsName(file_->name()));
printer->Indent();
// Make sure the file has found its way into the pool. If a descriptor
@@ -525,8 +513,9 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// protobuf_RegisterTypes(): Calls
// MessageFactory::InternalRegisterGeneratedType() for each message type.
printer->Print(
- "void protobuf_RegisterTypes(const ::std::string&) {\n"
- " protobuf_AssignDescriptorsOnce();\n");
+ "void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;\n"
+ "void protobuf_RegisterTypes(const ::std::string&) {\n"
+ " protobuf_AssignDescriptorsOnce();\n");
printer->Indent();
for (int i = 0; i < file_->message_type_count(); i++) {
@@ -566,6 +555,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// Note that we don't need any special synchronization in the following
// code
// because it is called at static init time before any threads exist.
+ "void $adddescriptorsname$() GOOGLE_ATTRIBUTE_COLD;\n"
"void $adddescriptorsname$() {\n"
" static bool already_here = false;\n"
" if (already_here) return;\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index dd9f1887..0588e34e 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -251,117 +251,148 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
}
}
-void MapFieldGenerator::
-GenerateSerializeWithCachedSizes(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
+static void GenerateSerializationLoop(io::Printer* printer,
+ const map<string, string>& variables,
+ bool supports_arenas,
+ const string& utf8_check,
+ const string& loop_header,
+ const string& ptr,
+ bool loop_via_iterators) {
+ printer->Print(variables,
+ StrCat("::google::protobuf::scoped_ptr<$map_classname$> entry;\n",
+ loop_header, " {\n").c_str());
+ printer->Indent();
+
+ printer->Print(variables, StrCat(
+ "entry.reset($name$_.New$wrapper$(\n"
+ " ", ptr, "->first, ", ptr, "->second));\n"
+ "$write_entry$;\n").c_str());
// If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
+ if (supports_arenas) {
+ printer->Print(
+ "if (entry->GetArena() != NULL) {\n"
+ " entry.release();\n"
+ "}\n");
}
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " ::google::protobuf::internal::WireFormatLite::Write$stream_writer$(\n"
- " $number$, *entry, output);\n");
-
- printer->Indent();
- printer->Indent();
-
- const FieldDescriptor* key_field =
- descriptor_->message_type()->FindFieldByName("key");
- const FieldDescriptor* value_field =
- descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(key_field, options_, false, variables_,
- "it->first.data(), it->first.length(),\n",
- printer);
- }
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(value_field, options_, false, variables_,
- "it->second.data(), it->second.length(),\n",
- printer);
+ if (!utf8_check.empty()) {
+ // If loop_via_iterators is true then ptr is actually an iterator, and we
+ // create a pointer by prefixing it with "&*".
+ printer->Print(
+ StrCat(utf8_check, "(", (loop_via_iterators ? "&*" : ""), ptr, ");\n")
+ .c_str());
}
printer->Outdent();
- printer->Outdent();
-
printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
+ "}\n");
+}
- printer->Print("}\n");
+void MapFieldGenerator::
+GenerateSerializeWithCachedSizes(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["write_entry"] = "::google::protobuf::internal::WireFormatLite::Write" +
+ variables["stream_writer"] + "(\n " +
+ variables["number"] + ", *entry, output)";
+ variables["deterministic"] = "output->IsSerializationDeterminstic()";
+ GenerateSerializeWithCachedSizes(printer, variables);
}
void MapFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
- printer->Print(variables_,
- "{\n"
- " ::google::protobuf::scoped_ptr<$map_classname$> entry;\n"
- " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
- " it = this->$name$().begin();\n"
- " it != this->$name$().end(); ++it) {\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
- printer->Print(variables_,
- " entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
- " target = ::google::protobuf::internal::WireFormatLite::\n"
- " InternalWrite$declared_type$NoVirtualToArray(\n"
- " $number$, *entry, false, target);\n");
+ map<string, string> variables(variables_);
+ variables["write_entry"] =
+ "target = ::google::protobuf::internal::WireFormatLite::\n"
+ " InternalWrite" + variables["declared_type"] +
+ "NoVirtualToArray(\n " + variables["number"] +
+ ", *entry, deterministic, target);\n";
+ variables["deterministic"] = "deterministic";
+ GenerateSerializeWithCachedSizes(printer, variables);
+}
+void MapFieldGenerator::GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map<string, string>& variables) const {
+ printer->Print(variables,
+ "if (!this->$name$().empty()) {\n");
printer->Indent();
- printer->Indent();
-
const FieldDescriptor* key_field =
descriptor_->message_type()->FindFieldByName("key");
const FieldDescriptor* value_field =
descriptor_->message_type()->FindFieldByName("value");
- if (key_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(key_field, options_, false, variables_,
- "it->first.data(), it->first.length(),\n",
- printer);
+ const bool string_key = key_field->type() == FieldDescriptor::TYPE_STRING;
+ const bool string_value = value_field->type() == FieldDescriptor::TYPE_STRING;
+
+ printer->Print(variables,
+ "typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_pointer\n"
+ " ConstPtr;\n");
+ if (string_key) {
+ printer->Print(variables,
+ "typedef ConstPtr SortItem;\n"
+ "typedef ::google::protobuf::internal::"
+ "CompareByDerefFirst<SortItem> Less;\n");
+ } else {
+ printer->Print(variables,
+ "typedef ::google::protobuf::internal::SortItem< $key_cpp$, ConstPtr > "
+ "SortItem;\n"
+ "typedef ::google::protobuf::internal::CompareByFirstField<SortItem> Less;\n");
}
- if (value_field->type() == FieldDescriptor::TYPE_STRING) {
- GenerateUtf8CheckCodeForString(value_field, options_, false, variables_,
- "it->second.data(), it->second.length(),\n",
- printer);
+ string utf8_check;
+ if (string_key || string_value) {
+ printer->Print(
+ "struct Utf8Check {\n"
+ " static void Check(ConstPtr p) {\n");
+ printer->Indent();
+ printer->Indent();
+ if (string_key) {
+ GenerateUtf8CheckCodeForString(key_field, options_, false, variables,
+ "p->first.data(), p->first.length(),\n",
+ printer);
+ }
+ if (string_value) {
+ GenerateUtf8CheckCodeForString(value_field, options_, false, variables,
+ "p->second.data(), p->second.length(),\n",
+ printer);
+ }
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " }\n"
+ "};\n");
+ utf8_check = "Utf8Check::Check";
}
- printer->Outdent();
+ printer->Print(variables,
+ "\n"
+ "if ($deterministic$ &&\n"
+ " this->$name$().size() > 1) {\n"
+ " ::google::protobuf::scoped_array<SortItem> items(\n"
+ " new SortItem[this->$name$().size()]);\n"
+ " typedef ::google::protobuf::Map< $key_cpp$, $val_cpp$ >::size_type size_type;\n"
+ " size_type n = 0;\n"
+ " for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it, ++n) {\n"
+ " items[n] = SortItem(&*it);\n"
+ " }\n"
+ " ::std::sort(&items[0], &items[n], Less());\n");
+ printer->Indent();
+ GenerateSerializationLoop(printer, variables, SupportsArenas(descriptor_),
+ utf8_check, "for (size_type i = 0; i < n; i++)",
+ string_key ? "items[i]" : "items[i].second", false);
printer->Outdent();
printer->Print(
- " }\n");
-
- // If entry is allocated by arena, its desctructor should be avoided.
- if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- " if (entry.get() != NULL && entry->GetArena() != NULL) {\n"
- " entry.release();\n"
- " }\n");
- }
-
+ "} else {\n");
+ printer->Indent();
+ GenerateSerializationLoop(
+ printer, variables, SupportsArenas(descriptor_), utf8_check,
+ "for (::google::protobuf::Map< $key_cpp$, $val_cpp$ >::const_iterator\n"
+ " it = this->$name$().begin();\n"
+ " it != this->$name$().end(); ++it)",
+ "it", true);
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
printer->Print("}\n");
}
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index 087dcde0..2930fe59 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -61,6 +61,10 @@ class MapFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
private:
+ // A helper for GenerateSerializeWithCachedSizes{,ToArray}.
+ void GenerateSerializeWithCachedSizes(
+ io::Printer* printer, const map<string, string>& variables) const;
+
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map<string, string> variables_;
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index 32f63152..69cd5f3c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -2419,7 +2419,7 @@ GenerateClear(io::Printer* printer) {
" &reinterpret_cast<$classname$*>(16)->f)\n"
"#endif\n\n"
"#define ZR_(first, last) do {\\\n"
- " ::memset(&first, 0,\\\n"
+ " ::memset(&(first), 0,\\\n"
" ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\\\n"
"} while (0)\n\n";
for (int i = 0; i < runs_of_fields_.size(); i++) {
@@ -2715,7 +2715,9 @@ GenerateMergeFrom(io::Printer* printer) {
"void $classname$::MergeFrom(const ::google::protobuf::Message& from) {\n"
"// @@protoc_insertion_point(generalized_merge_from_start:"
"$full_name$)\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
"classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
@@ -2756,7 +2758,9 @@ GenerateMergeFrom(io::Printer* printer) {
"void $classname$::MergeFrom(const $classname$& from) {\n"
"// @@protoc_insertion_point(class_specific_merge_from_start:"
"$full_name$)\n"
- " if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);\n",
+ " if (GOOGLE_PREDICT_FALSE(&from == this)) {\n"
+ " ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);\n"
+ " }\n",
"classname", classname_, "full_name", descriptor_->full_name());
printer->Indent();
@@ -2952,7 +2956,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
// on the CodedOutputStream.
printer->Print(
" ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n"
- " ::google::protobuf::internal::NewPermanentCallback(\n"
+ " ::google::protobuf::NewPermanentCallback(\n"
" &MutableUnknownFieldsFor$classname$, this));\n"
" ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n"
" &unknown_fields_string, false);\n",
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index 5d82946d..b7b6039a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -1252,7 +1252,7 @@ class GeneratedServiceTest : public testing::Test {
foo_(descriptor_->FindMethodByName("Foo")),
bar_(descriptor_->FindMethodByName("Bar")),
stub_(&mock_channel_),
- done_(::google::protobuf::internal::NewPermanentCallback(&DoNothing)) {}
+ done_(NewPermanentCallback(&DoNothing)) {}
virtual void SetUp() {
ASSERT_TRUE(foo_ != NULL);
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc
index 64381d0f..9e4da1ed 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc
@@ -68,9 +68,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
for (int i = 0; i < descriptor_->value_count(); i++) {
WriteEnumValueDocComment(printer, descriptor_->value(i));
string original_name = descriptor_->value(i)->name();
- string name = options()->legacy_enum_values
- ? descriptor_->value(i)->name()
- : GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
+ string name = GetEnumValueName(descriptor_->name(), descriptor_->value(i)->name());
// Make sure we don't get any duplicate names due to prefix removal.
while (!used_names.insert(name).second) {
// It's possible we'll end up giving this warning multiple times, but that's better than not at all.
diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc
index d74e8c88..c13ed65b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_generator.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc
@@ -83,9 +83,6 @@ bool Generator::Generate(
cli_options.base_namespace_specified = true;
} else if (options[i].first == "internal_access") {
cli_options.internal_access = true;
- } else if (options[i].first == "legacy_enum_values") {
- // TODO: Remove this before final release
- cli_options.legacy_enum_values = true;
} else {
*error = "Unknown generator option: " + options[i].first;
return false;
diff --git a/src/google/protobuf/compiler/csharp/csharp_options.h b/src/google/protobuf/compiler/csharp/csharp_options.h
index 4079bf7f..426fb3b5 100644
--- a/src/google/protobuf/compiler/csharp/csharp_options.h
+++ b/src/google/protobuf/compiler/csharp/csharp_options.h
@@ -45,8 +45,7 @@ struct Options {
file_extension(".cs"),
base_namespace(""),
base_namespace_specified(false),
- internal_access(false),
- legacy_enum_values(false) {
+ internal_access(false) {
}
// Extension of the generated file. Defaults to ".cs"
string file_extension;
@@ -69,12 +68,6 @@ struct Options {
// Whether the generated classes should have accessibility level of "internal".
// Defaults to false that generates "public" classes.
bool internal_access;
- // By default, C# codegen now uses PascalCased enum values names, after
- // removing the enum type name as a prefix (if it *is* a prefix of the value).
- // Setting this option reverts to the previous behavior of just copying the
- // value name specified in the .proto file, allowing gradual migration.
- // This option will be removed before final release.
- bool legacy_enum_values;
};
} // namespace csharp
diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc
index a06c5f6d..5e387285 100644
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -266,9 +266,7 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Print(
"public static void registerAllExtensions(\n"
- " com.google.protobuf.ExtensionRegistry$lite$ registry) {\n",
- "lite",
- HasDescriptorMethods(file_, context_->EnforceLite()) ? "" : "Lite");
+ " com.google.protobuf.ExtensionRegistryLite registry) {\n");
printer->Indent();
@@ -283,6 +281,20 @@ void FileGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
"}\n");
+ if (HasDescriptorMethods(file_, context_->EnforceLite())) {
+ // Overload registerAllExtensions for the non-lite usage to
+ // redundantly maintain the original signature (this is
+ // redundant because ExtensionRegistryLite now invokes
+ // ExtensionRegistry in the non-lite usage). Intent is
+ // to remove this in the future.
+ printer->Print(
+ "\n"
+ "public static void registerAllExtensions(\n"
+ " com.google.protobuf.ExtensionRegistry registry) {\n"
+ " registerAllExtensions(\n"
+ " (com.google.protobuf.ExtensionRegistryLite) registry);\n"
+ "}\n");
+ }
// -----------------------------------------------------------------
diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc
index 3c545e15..b1ab4043 100644
--- a/src/google/protobuf/compiler/java/java_generator.cc
+++ b/src/google/protobuf/compiler/java/java_generator.cc
@@ -79,8 +79,6 @@ bool JavaGenerator::Generate(const FileDescriptor* file,
file_options.generate_mutable_code = true;
} else if (options[i].first == "shared") {
file_options.generate_shared_code = true;
- } else if (options[i].first == "lite") {
- file_options.enforce_lite = true;
} else if (options[i].first == "annotate_code") {
file_options.annotate_code = true;
} else if (options[i].first == "annotation_list_file") {
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index d55a9849..6c80d070 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -205,9 +205,10 @@ GenerateFieldAccessorTable(io::Printer* printer, int* bytecode_estimate) {
} else {
vars["final"] = "";
}
+ vars["ver"] = GeneratedCodeVersionSuffix();
printer->Print(vars,
"$private$static $final$\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internal_$identifier$_fieldAccessorTable;\n");
// 6 bytes per field and oneof
@@ -220,11 +221,11 @@ GenerateFieldAccessorTableInitializer(io::Printer* printer) {
int bytecode_estimate = 10;
printer->Print(
"internal_$identifier$_fieldAccessorTable = new\n"
- " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
+ " com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable(\n"
" internal_$identifier$_descriptor,\n"
" new java.lang.String[] { ",
- "identifier",
- UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
@@ -254,11 +255,11 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
printer->Print(
"public interface $classname$OrBuilder$idend$ extends\n"
" $extra_interfaces$\n"
- " com.google.protobuf.GeneratedMessage.\n"
+ " com.google.protobuf.GeneratedMessage$ver$.\n"
" ExtendableMessageOrBuilder<$classname$> {\n",
"extra_interfaces", ExtraMessageOrBuilderInterfaces(descriptor_),
"classname", descriptor_->name(),
- "idend", "");
+ "idend", "", "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
"public interface $classname$OrBuilder$idend$ extends\n"
@@ -302,6 +303,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
variables["static"] = is_own_file ? " " : " static ";
variables["classname"] = descriptor_->name();
variables["extra_interfaces"] = ExtraMessageInterfaces(descriptor_);
+ variables["ver"] = GeneratedCodeVersionSuffix();
WriteMessageDocComment(printer, descriptor_);
MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
@@ -315,22 +317,25 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
printer->Annotate("classname", descriptor_);
printer->Print(
variables,
- " com.google.protobuf.GeneratedMessage.ExtendableMessage<\n"
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableMessage<\n"
" $classname$> implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
builder_type = strings::Substitute(
- "com.google.protobuf.GeneratedMessage.ExtendableBuilder<$0, ?>",
- name_resolver_->GetImmutableClassName(descriptor_));
+ "com.google.protobuf.GeneratedMessage$1.ExtendableBuilder<$0, ?>",
+ name_resolver_->GetImmutableClassName(descriptor_),
+ GeneratedCodeVersionSuffix());
} else {
printer->Print(variables,
"public $static$final class $classname$ extends\n");
printer->Annotate("classname", descriptor_);
printer->Print(variables,
- " com.google.protobuf.GeneratedMessage implements\n"
+ " com.google.protobuf.GeneratedMessage$ver$ implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
- builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
+ builder_type = strings::Substitute(
+ "com.google.protobuf.GeneratedMessage$0.Builder<?>",
+ GeneratedCodeVersionSuffix());
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
@@ -581,16 +586,18 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
if (descriptor_->options().message_set_wire_format()) {
printer->Print(
- "com.google.protobuf.GeneratedMessage\n"
+ "com.google.protobuf.GeneratedMessage$ver$\n"
" .ExtendableMessage<$classname$>.ExtensionWriter\n"
" extensionWriter = newMessageSetExtensionWriter();\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
- "com.google.protobuf.GeneratedMessage\n"
+ "com.google.protobuf.GeneratedMessage$ver$\n"
" .ExtendableMessage<$classname$>.ExtensionWriter\n"
" extensionWriter = newExtensionWriter();\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
}
@@ -694,43 +701,44 @@ GenerateParseFromMethods(io::Printer* printer) {
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseDelimitedWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(\n"
" java.io.InputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseDelimitedWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseWithIOException(PARSER, input);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws java.io.IOException {\n"
- " return com.google.protobuf.GeneratedMessage\n"
+ " return com.google.protobuf.GeneratedMessage$ver$\n"
" .parseWithIOException(PARSER, input, extensionRegistry);\n"
"}\n"
"\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
void ImmutableMessageGenerator::GenerateSerializeOneField(
@@ -769,10 +777,11 @@ void ImmutableMessageGenerator::GenerateBuilder(io::Printer* printer) {
printer->Print(
"@java.lang.Override\n"
"protected Builder newBuilderForType(\n"
- " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
" Builder builder = new Builder(parent);\n"
" return builder;\n"
- "}\n");
+ "}\n",
+ "ver", GeneratedCodeVersionSuffix());
MessageBuilderGenerator builderGenerator(descriptor_, context_);
builderGenerator.Generate(printer);
@@ -826,7 +835,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
"}\n");
}
printer->Print(
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internalGetFieldAccessorTable() {\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
" .ensureFieldAccessorsInitialized(\n"
@@ -835,7 +844,8 @@ GenerateDescriptorMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
"fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
// ===================================================================
diff --git a/src/google/protobuf/compiler/java/java_message_builder.cc b/src/google/protobuf/compiler/java/java_message_builder.cc
index b3e9e986..42154694 100644
--- a/src/google/protobuf/compiler/java/java_message_builder.cc
+++ b/src/google/protobuf/compiler/java/java_message_builder.cc
@@ -94,20 +94,22 @@ Generate(io::Printer* printer) {
if (descriptor_->extension_range_count() > 0) {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.ExtendableBuilder<\n"
+ " com.google.protobuf.GeneratedMessage$ver$.ExtendableBuilder<\n"
" $classname$, Builder> implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
- "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
} else {
printer->Print(
"public static final class Builder extends\n"
- " com.google.protobuf.GeneratedMessage.Builder<Builder> implements\n"
+ " com.google.protobuf.GeneratedMessage$ver$.Builder<Builder> implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
- "extra_interfaces", ExtraBuilderInterfaces(descriptor_));
+ "extra_interfaces", ExtraBuilderInterfaces(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
printer->Indent();
@@ -181,6 +183,18 @@ Generate(io::Printer* printer) {
" return this;\n"
"}\n"
"\n");
+ } else {
+ printer->Print(
+ "public final Builder setUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.setUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n"
+ "public final Builder mergeUnknownFields(\n"
+ " final com.google.protobuf.UnknownFieldSet unknownFields) {\n"
+ " return super.mergeUnknownFields(unknownFields);\n"
+ "}\n"
+ "\n");
}
printer->Print(
@@ -268,7 +282,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
"}\n");
}
printer->Print(
- "protected com.google.protobuf.GeneratedMessage.FieldAccessorTable\n"
+ "protected com.google.protobuf.GeneratedMessage$ver$.FieldAccessorTable\n"
" internalGetFieldAccessorTable() {\n"
" return $fileclass$.internal_$identifier$_fieldAccessorTable\n"
" .ensureFieldAccessorsInitialized(\n"
@@ -277,7 +291,8 @@ GenerateDescriptorMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_),
"fileclass", name_resolver_->GetImmutableClassName(descriptor_->file()),
- "identifier", UniqueFileScopeIdentifier(descriptor_));
+ "identifier", UniqueFileScopeIdentifier(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
}
// ===================================================================
@@ -294,15 +309,18 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
printer->Print(
"private Builder(\n"
- " com.google.protobuf.GeneratedMessage.BuilderParent parent) {\n"
+ " com.google.protobuf.GeneratedMessage$ver$.BuilderParent parent) {\n"
" super(parent);\n"
" maybeForceBuilderInitialization();\n"
"}\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ "classname", name_resolver_->GetImmutableClassName(descriptor_),
+ "ver", GeneratedCodeVersionSuffix());
printer->Print(
"private void maybeForceBuilderInitialization() {\n"
- " if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {\n");
+ " if (com.google.protobuf.GeneratedMessage$ver$\n"
+ " .alwaysUseFieldBuilders) {\n",
+ "ver", GeneratedCodeVersionSuffix());
printer->Indent();
printer->Indent();
@@ -438,6 +456,62 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
+ printer->Print(
+ "public Builder clone() {\n"
+ " return (Builder) super.clone();\n"
+ "}\n"
+ "public Builder setField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.setField(field, value);\n"
+ "}\n"
+ "public Builder clearField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field) {\n"
+ " return (Builder) super.clearField(field);\n"
+ "}\n"
+ "public Builder clearOneof(\n"
+ " com.google.protobuf.Descriptors.OneofDescriptor oneof) {\n"
+ " return (Builder) super.clearOneof(oneof);\n"
+ "}\n"
+ "public Builder setRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " int index, Object value) {\n"
+ " return (Builder) super.setRepeatedField(field, index, value);\n"
+ "}\n"
+ "public Builder addRepeatedField(\n"
+ " com.google.protobuf.Descriptors.FieldDescriptor field,\n"
+ " Object value) {\n"
+ " return (Builder) super.addRepeatedField(field, value);\n"
+ "}\n");
+
+ if (descriptor_->extension_range_count() > 0) {
+ printer->Print(
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, Type> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.setExtension(extension, value);\n"
+ "}\n"
+ "public <Type> Builder setExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " int index, Type value) {\n"
+ " return (Builder) super.setExtension(extension, index, value);\n"
+ "}\n"
+ "public <Type> Builder addExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, java.util.List<Type>> extension,\n"
+ " Type value) {\n"
+ " return (Builder) super.addExtension(extension, value);\n"
+ "}\n"
+ "public <Type> Builder clearExtension(\n"
+ " com.google.protobuf.GeneratedMessage.GeneratedExtension<\n"
+ " $classname$, ?> extension) {\n"
+ " return (Builder) super.clearExtension(extension);\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
+ }
+
// -----------------------------------------------------------------
if (context_->HasGeneratedMethods(descriptor_)) {
@@ -522,6 +596,7 @@ GenerateCommonBuilderMethods(io::Printer* printer) {
" return this;\n"
"}\n"
"\n");
+
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index cc627b5a..c9865dda 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -1203,7 +1203,7 @@ GenerateMergingCode(io::Printer* printer) const {
" $name$_ = other.$name$_;\n"
" $clear_mutable_bit_builder$;\n"
" $name$Builder_ = \n"
- " com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?\n"
+ " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders ?\n"
" get$capitalized_name$FieldBuilder() : null;\n"
" } else {\n"
" $name$Builder_.addAllMessages(other.$name$_);\n"
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index e1e5496a..ff1865b1 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -79,9 +79,11 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
" throw new NullPointerException();\n"
" }\n";
(*variables)["writeString"] =
- "com.google.protobuf.GeneratedMessage.writeString";
+ "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
+ ".writeString";
(*variables)["computeStringSize"] =
- "com.google.protobuf.GeneratedMessage.computeStringSize";
+ "com.google.protobuf.GeneratedMessage" + GeneratedCodeVersionSuffix() +
+ ".computeStringSize";
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc
index 8a2633d7..58c77d00 100755
--- a/src/google/protobuf/compiler/js/js_generator.cc
+++ b/src/google/protobuf/compiler/js/js_generator.cc
@@ -768,7 +768,6 @@ string MaybeNumberString(const FieldDescriptor* field, const string& orig) {
}
string JSFieldDefault(const FieldDescriptor* field) {
- assert(field->has_default_value());
switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32:
return MaybeNumberString(
@@ -943,7 +942,7 @@ string JSFieldTypeAnnotation(const GeneratorOptions& options,
}
if (field->is_optional() && is_primitive &&
- (!field->has_default_value() || force_optional) && !force_present) {
+ force_optional && !force_present) {
jstype += "?";
} else if (field->is_required() && !is_primitive && !force_optional) {
jstype = "!" + jstype;
@@ -1258,6 +1257,10 @@ string GetPivot(const Descriptor* desc) {
// Returns true for fields that represent "null" as distinct from the default
// value. See http://go/proto3#heading=h.kozewqqcqhuz for more information.
bool HasFieldPresence(const FieldDescriptor* field) {
+ if (field->is_repeated()) {
+ return false;
+ }
+
return
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ||
(field->containing_oneof() != NULL) ||
@@ -2031,9 +2034,8 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options,
"getter", JSGetterName(options, field, BYTES_B64));
} else {
if (field->has_default_value()) {
- printer->Print("jspb.Message.getField(msg, $index$) == null ? "
- "$defaultValue$ : ",
- "index", JSFieldIndex(field),
+ printer->Print("!msg.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
"defaultValue", JSFieldDefault(field));
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
@@ -2253,25 +2255,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
" null");
}
- if (options.binary) {
- printer->Print(",\n"
- " $keyWriterFn$,\n"
- " $keyReaderFn$,\n"
- " $valueWriterFn$,\n"
- " $valueReaderFn$",
- "keyWriterFn", JSBinaryWriterMethodName(options, key_field),
- "keyReaderFn", JSBinaryReaderMethodName(options, key_field),
- "valueWriterFn", JSBinaryWriterMethodName(options, value_field),
- "valueReaderFn", JSBinaryReaderMethodName(options, value_field));
-
- if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
- printer->Print(",\n"
- " $messageType$.serializeBinaryToWriter,\n"
- " $messageType$.deserializeBinaryFromReader",
- "messageType", GetPath(options, value_field->message_type()));
- }
- }
-
printer->Print(
"));\n");
@@ -2407,10 +2390,9 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"index", JSFieldIndex(field),
"default", Proto3PrimitiveFieldDefault(field));
} else {
- if (field->has_default_value()) {
- printer->Print("jspb.Message.getField(this, $index$) == null ? "
- "$defaultValue$ : ",
- "index", JSFieldIndex(field),
+ if (!field->is_repeated()) {
+ printer->Print("!this.has$name$() ? $defaultValue$ : ",
+ "name", JSGetterName(options, field),
"defaultValue", JSFieldDefault(field));
}
if (field->cpp_type() == FieldDescriptor::CPPTYPE_FLOAT ||
@@ -2419,10 +2401,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
printer->Print("jspb.Message.getRepeatedFloatingPointField("
"this, $index$)",
"index", JSFieldIndex(field));
- } else if (field->is_optional() && !field->has_default_value()) {
- printer->Print("jspb.Message.getOptionalFloatingPointField("
- "this, $index$)",
- "index", JSFieldIndex(field));
} else {
// Convert "NaN" to NaN.
printer->Print("+jspb.Message.getField(this, $index$)",
@@ -2498,7 +2476,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"returndoc", JSReturnDoc(options, field));
}
- if (HasFieldPresence(field)) {
+ if (HasFieldPresence(field) || field->is_repeated()) {
printer->Print(
"$class$.prototype.clear$name$ = function() {\n"
" jspb.Message.set$oneoftag$Field(this, $index$$oneofgroup$, ",
@@ -2517,6 +2495,22 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"returnvalue", JSReturnClause(field));
}
}
+
+ if (HasFieldPresence(field)) {
+ printer->Print(
+ "/**\n"
+ " * Returns whether this field is set.\n"
+ " * @return{!boolean}\n"
+ " */\n"
+ "$class$.prototype.has$name$ = function() {\n"
+ " return jspb.Message.getField(this, $index$) != null;\n"
+ "};\n"
+ "\n"
+ "\n",
+ "class", GetPath(options, field->containing_type()),
+ "name", JSGetterName(options, field),
+ "index", JSFieldIndex(field));
+ }
}
void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
@@ -2543,6 +2537,29 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
"$class$.extensions = {};\n"
"\n",
"class", GetPath(options, desc));
+
+ if (options.binary) {
+ printer->Print(
+ "\n"
+ "/**\n"
+ " * The extensions registered with this message class. This is a "
+ "map of\n"
+ " * extension field number to fieldInfo object.\n"
+ " *\n"
+ " * For example:\n"
+ " * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
+ "ctor: proto.example.MyMessage} }\n"
+ " *\n"
+ " * fieldName contains the JsCompiler renamed field name property "
+ "so that it\n"
+ " * works in OPTIMIZED mode.\n"
+ " *\n"
+ " * @type {!Object.<number, jspb.ExtensionFieldInfo>}\n"
+ " */\n"
+ "$class$.extensionsBinary = {};\n"
+ "\n",
+ "class", GetPath(options, desc));
+ }
}
}
@@ -2590,7 +2607,7 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
" default:\n");
if (IsExtendable(desc)) {
printer->Print(
- " jspb.Message.readBinaryExtension(msg, reader, $extobj$,\n"
+ " jspb.Message.readBinaryExtension(msg, reader, $extobj$Binary,\n"
" $class$.prototype.getExtension,\n"
" $class$.prototype.setExtension);\n"
" break;\n",
@@ -2620,10 +2637,25 @@ void Generator::GenerateClassDeserializeBinaryField(
"num", SimpleItoa(field->number()));
if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
printer->Print(
" var value = msg.get$name$();\n"
- " reader.readMessage(value, jspb.Map.deserializeBinary);\n",
+ " reader.readMessage(value, function(message, reader) {\n",
"name", JSGetterName(options, field));
+
+ printer->Print(" jspb.Map.deserializeBinary(message, reader, "
+ "$keyReaderFn$, $valueReaderFn$",
+ "keyReaderFn", JSBinaryReaderMethodName(options, key_field),
+ "valueReaderFn", JSBinaryReaderMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.deserializeBinaryFromReader",
+ "messageType", GetPath(options, value_field->message_type()));
+ }
+
+ printer->Print(");\n");
+ printer->Print(" });\n");
} else {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer->Print(
@@ -2709,8 +2741,8 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
if (IsExtendable(desc)) {
printer->Print(
- " jspb.Message.serializeBinaryExtensions(this, writer, $extobj$,\n"
- " $class$.prototype.getExtension);\n",
+ " jspb.Message.serializeBinaryExtensions(this, writer,\n"
+ " $extobj$Binary, $class$.prototype.getExtension);\n",
"extobj", JSExtensionsObjectName(options, desc->file(), desc),
"class", GetPath(options, desc));
}
@@ -2725,11 +2757,18 @@ void Generator::GenerateClassSerializeBinaryField(
const GeneratorOptions& options,
io::Printer* printer,
const FieldDescriptor* field) const {
- printer->Print(
- " f = this.get$name$($nolazy$);\n",
- "name", JSGetterName(options, field, BYTES_U8),
- // No lazy creation for maps containers -- fastpath the empty case.
- "nolazy", (field->is_map()) ? "true" : "");
+ if (HasFieldPresence(field) &&
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ " f = jspb.Message.getField(this, $index$);\n",
+ "index", JSFieldIndex(field));
+ } else {
+ printer->Print(
+ " f = this.get$name$($nolazy$);\n",
+ "name", JSGetterName(options, field, BYTES_U8),
+ // No lazy creation for maps containers -- fastpath the empty case.
+ "nolazy", (field->is_map()) ? "true" : "");
+ }
// Print an `if (condition)` statement that evaluates to true if the field
@@ -2782,9 +2821,21 @@ void Generator::GenerateClassSerializeBinaryField(
// Write the field on the wire.
if (field->is_map()) {
+ const FieldDescriptor* key_field = MapFieldKey(field);
+ const FieldDescriptor* value_field = MapFieldValue(field);
printer->Print(
- " f.serializeBinary($index$, writer);\n",
- "index", SimpleItoa(field->number()));
+ " f.serializeBinary($index$, writer, "
+ "$keyWriterFn$, $valueWriterFn$",
+ "index", SimpleItoa(field->number()),
+ "keyWriterFn", JSBinaryWriterMethodName(options, key_field),
+ "valueWriterFn", JSBinaryWriterMethodName(options, value_field));
+
+ if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ printer->Print(", $messageType$.serializeBinaryToWriter",
+ "messageType", GetPath(options, value_field->message_type()));
+ }
+
+ printer->Print(");\n");
} else {
printer->Print(
" writer.write$method$(\n"
@@ -2866,7 +2917,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
" /** @type {?function((boolean|undefined),!jspb.Message=): "
"!Object} */ (\n"
" $toObject$),\n"
- " $repeated$",
+ " $repeated$);\n",
"index", SimpleItoa(field->number()),
"name", JSObjectFieldName(options, field),
"ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
@@ -2878,12 +2929,18 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
if (options.binary) {
printer->Print(
- ",\n"
+ "\n"
+ "$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
+ " $class$.$name$,\n"
" $binaryReaderFn$,\n"
" $binaryWriterFn$,\n"
" $binaryMessageSerializeFn$,\n"
- " $binaryMessageDeserializeFn$,\n"
- " $isPacked$);\n",
+ " $binaryMessageDeserializeFn$,\n",
+ "extendName", JSExtensionsObjectName(options, field->file(),
+ field->containing_type()),
+ "index", SimpleItoa(field->number()),
+ "class", extension_scope,
+ "name", JSObjectFieldName(options, field),
"binaryReaderFn", JSBinaryReaderMethodName(options, field),
"binaryWriterFn", JSBinaryWriterMethodName(options, field),
"binaryMessageSerializeFn",
@@ -2893,10 +2950,11 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
"binaryMessageDeserializeFn",
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
(SubmessageTypeRef(options, field) +
- ".deserializeBinaryFromReader") : "null",
+ ".deserializeBinaryFromReader") : "null");
+
+ printer->Print(
+ " $isPacked$);\n",
"isPacked", (field->is_packed() ? "true" : "false"));
- } else {
- printer->Print(");\n");
}
printer->Print(
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
index e76f8e99..34e17823 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum.cc
@@ -62,7 +62,7 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
string enum_comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
- enum_comments = BuildCommentsString(location);
+ enum_comments = BuildCommentsString(location, true);
} else {
enum_comments = "";
}
@@ -81,16 +81,18 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
if (HasPreservingUnknownEnumSemantics(descriptor_->file())) {
// Include the unknown value.
printer->Print(
- "/// Value used if any message's field encounters a value that is not defined\n"
- "/// by this enum. The message will also have C functions to get/set the rawValue\n"
- "/// of the field.\n"
+ "/**\n"
+ " * Value used if any message's field encounters a value that is not defined\n"
+ " * by this enum. The message will also have C functions to get/set the rawValue\n"
+ " * of the field.\n"
+ " **/\n"
"$name$_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,\n",
"name", name_);
}
for (int i = 0; i < all_values_.size(); i++) {
SourceLocation location;
if (all_values_[i]->GetSourceLocation(&location)) {
- string comments = BuildCommentsString(location).c_str();
+ string comments = BuildCommentsString(location, true).c_str();
if (comments.length() > 0) {
if (i > 0) {
printer->Print("\n");
@@ -111,8 +113,10 @@ void EnumGenerator::GenerateHeader(io::Printer* printer) {
"\n"
"GPBEnumDescriptor *$name$_EnumDescriptor(void);\n"
"\n"
- "/// Checks to see if the given value is defined by the enum or was not known at\n"
- "/// the time this source was generated.\n"
+ "/**\n"
+ " * Checks to see if the given value is defined by the enum or was not known at\n"
+ " * the time this source was generated.\n"
+ " **/\n"
"BOOL $name$_IsValidValue(int32_t value);\n"
"\n",
"name", name_);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
index b63bc0de..7a774a09 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc
@@ -83,12 +83,16 @@ void EnumFieldGenerator::GenerateCFunctionDeclarations(
printer->Print(
variables_,
- "/// Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
- "/// if the value was not defined by the enum at the time the code was generated.\n"
+ "/**\n"
+ " * Fetches the raw value of a @c $owning_message_class$'s @c $name$ property, even\n"
+ " * if the value was not defined by the enum at the time the code was generated.\n"
+ " **/\n"
"int32_t $owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message);\n"
- "/// Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
- "/// it to be set to a value that was not defined by the enum at the time the code\n"
- "/// was generated.\n"
+ "/**\n"
+ " * Sets the raw value of an @c $owning_message_class$'s @c $name$ property, allowing\n"
+ " * it to be set to a value that was not defined by the enum at the time the code\n"
+ " * was generated.\n"
+ " **/\n"
"void Set$owning_message_class$_$capitalized_name$_RawValue($owning_message_class$ *message, int32_t value);\n"
"\n");
}
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
index 3f7ab9d3..d0de1eca 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -63,7 +63,7 @@ void ExtensionGenerator::GenerateMembersHeader(io::Printer* printer) {
vars["method_name"] = method_name_;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
- vars["comments"] = BuildCommentsString(location);
+ vars["comments"] = BuildCommentsString(location, true);
} else {
vars["comments"] = "";
}
@@ -85,7 +85,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
if (descriptor_->containing_type()->options().message_set_wire_format())
options.push_back("GPBExtensionSetWireFormat");
- vars["options"] = BuildFlagsString(options);
+ vars["options"] = BuildFlagsString(FLAGTYPE_EXTENSION, options);
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
string singular_type;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
index 812b4a1c..527b7c0c 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc
@@ -64,7 +64,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
SourceLocation location;
if (descriptor->GetSourceLocation(&location)) {
- (*variables)["comments"] = BuildCommentsString(location);
+ (*variables)["comments"] = BuildCommentsString(location, true);
} else {
(*variables)["comments"] = "\n";
}
@@ -93,7 +93,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
field_flags.push_back("GPBFieldHasEnumDescriptor");
}
- (*variables)["fieldflags"] = BuildFlagsString(field_flags);
+ (*variables)["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
(*variables)["default"] = DefaultValue(descriptor);
(*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
@@ -335,7 +335,7 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
if (WantsHasProperty()) {
printer->Print(
variables_,
- "/// Test to see if @c $name$ has been set.\n"
+ "/** Test to see if @c $name$ has been set. */\n"
"@property(nonatomic, readwrite) BOOL has$capitalized_name$$deprecated_attribute$;\n");
}
if (IsInitName(variables_.find("name")->second)) {
@@ -387,7 +387,7 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration(
"$comments$"
"$array_comment$"
"@property(nonatomic, readwrite, strong, null_resettable) $array_property_type$ *$name$$storage_attribute$$deprecated_attribute$;\n"
- "/// The number of items in @c $name$ without causing the array to be created.\n"
+ "/** The number of items in @c $name$ without causing the array to be created. */\n"
"@property(nonatomic, readonly) NSUInteger $name$_Count$deprecated_attribute$;\n");
if (IsInitName(variables_.find("name")->second)) {
// If property name starts with init we need to annotate it to get past ARC.
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index cf8c34e1..878a3743 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -37,6 +37,7 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/stl_util.h>
#include <google/protobuf/stubs/strutil.h>
+#include <algorithm> // std::find()
#include <iostream>
#include <sstream>
@@ -45,218 +46,122 @@
namespace google {
namespace protobuf {
-
-// This is also found in GPBBootstrap.h, and needs to be kept in sync. It
-// is the version check done to ensure generated code works with the current
-// runtime being used.
-const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30001;
-
namespace compiler {
namespace objectivec {
namespace {
-class ImportWriter {
- public:
- ImportWriter(const Options& options)
- : options_(options),
- need_to_parse_mapping_file_(true) {}
-
- void AddFile(const FileGenerator* file);
- void Print(io::Printer *printer) const;
-
- private:
- class ProtoFrameworkCollector : public LineConsumer {
- public:
- ProtoFrameworkCollector(map<string, string>* inout_proto_file_to_framework_name)
- : map_(inout_proto_file_to_framework_name) {}
-
- virtual bool ConsumeLine(const StringPiece& line, string* out_error);
-
- private:
- map<string, string>* map_;
- };
-
- void ParseFrameworkMappings();
-
- const Options options_;
- map<string, string> proto_file_to_framework_name_;
- bool need_to_parse_mapping_file_;
-
- vector<string> protobuf_framework_imports_;
- vector<string> protobuf_non_framework_imports_;
- vector<string> other_framework_imports_;
- vector<string> other_imports_;
-};
+// This is also found in GPBBootstrap.h, and needs to be kept in sync. It
+// is the version check done to ensure generated code works with the current
+// runtime being used.
+const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30002;
-void ImportWriter::AddFile(const FileGenerator* file) {
- const FileDescriptor* file_descriptor = file->Descriptor();
- const string extension(".pbobjc.h");
+const char* kHeaderExtension = ".pbobjc.h";
- if (IsProtobufLibraryBundledProtoFile(file_descriptor)) {
- protobuf_framework_imports_.push_back(
- FilePathBasename(file_descriptor) + extension);
- protobuf_non_framework_imports_.push_back(file->Path() + extension);
- return;
+// Checks if a message contains any extension definitions (on the message or
+// a nested message under it).
+bool MessageContainsExtensions(const Descriptor* message) {
+ if (message->extension_count() > 0) {
+ return true;
}
-
- // Lazy parse any mappings.
- if (need_to_parse_mapping_file_) {
- ParseFrameworkMappings();
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (MessageContainsExtensions(message->nested_type(i))) {
+ return true;
+ }
}
+ return false;
+}
- map<string, string>::iterator proto_lookup =
- proto_file_to_framework_name_.find(file_descriptor->name());
- if (proto_lookup != proto_file_to_framework_name_.end()) {
- other_framework_imports_.push_back(
- proto_lookup->second + "/" +
- FilePathBasename(file_descriptor) + extension);
- return;
+// Checks if the file contains any extensions definitions (at the root or
+// nested under a message).
+bool FileContainsExtensions(const FileDescriptor* file) {
+ if (file->extension_count() > 0) {
+ return true;
}
-
- if (!options_.generate_for_named_framework.empty()) {
- other_framework_imports_.push_back(
- options_.generate_for_named_framework + "/" +
- FilePathBasename(file_descriptor) + extension);
- return;
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (MessageContainsExtensions(file->message_type(i))) {
+ return true;
+ }
}
-
- other_imports_.push_back(file->Path() + extension);
+ return false;
}
-void ImportWriter::Print(io::Printer* printer) const {
- assert(protobuf_non_framework_imports_.size() ==
- protobuf_framework_imports_.size());
-
- bool add_blank_line = false;
-
- if (protobuf_framework_imports_.size() > 0) {
- const string framework_name(ProtobufLibraryFrameworkName);
- const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
-
- printer->Print(
- "#if $cpp_symbol$\n",
- "cpp_symbol", cpp_symbol);
- for (vector<string>::const_iterator iter = protobuf_framework_imports_.begin();
- iter != protobuf_framework_imports_.end(); ++iter) {
- printer->Print(
- " #import <$framework_name$/$header$>\n",
- "framework_name", framework_name,
- "header", *iter);
- }
- printer->Print(
- "#else\n");
- for (vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin();
- iter != protobuf_non_framework_imports_.end(); ++iter) {
- printer->Print(
- " #import \"$header$\"\n",
- "header", *iter);
- }
- printer->Print(
- "#endif\n");
-
- add_blank_line = true;
+// Helper for CollectMinimalFileDepsContainingExtensionsWorker that marks all
+// deps as visited and prunes them from the needed files list.
+void PruneFileAndDepsMarkingAsVisited(
+ const FileDescriptor* file,
+ vector<const FileDescriptor*>* files,
+ set<const FileDescriptor*>* files_visited) {
+ vector<const FileDescriptor*>::iterator iter =
+ std::find(files->begin(), files->end(), file);
+ if (iter != files->end()) {
+ files->erase(iter);
}
+ files_visited->insert(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ PruneFileAndDepsMarkingAsVisited(file->dependency(i), files, files_visited);
+ }
+}
- if (other_framework_imports_.size() > 0) {
- if (add_blank_line) {
- printer->Print("\n");
- }
-
- for (vector<string>::const_iterator iter = other_framework_imports_.begin();
- iter != other_framework_imports_.end(); ++iter) {
- printer->Print(
- " #import <$header$>\n",
- "header", *iter);
- }
-
- add_blank_line = true;
+// Helper for CollectMinimalFileDepsContainingExtensions.
+void CollectMinimalFileDepsContainingExtensionsWorker(
+ const FileDescriptor* file,
+ vector<const FileDescriptor*>* files,
+ set<const FileDescriptor*>* files_visited) {
+ if (files_visited->find(file) != files_visited->end()) {
+ return;
}
+ files_visited->insert(file);
- if (other_imports_.size() > 0) {
- if (add_blank_line) {
- printer->Print("\n");
+ if (FileContainsExtensions(file)) {
+ files->push_back(file);
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ PruneFileAndDepsMarkingAsVisited(dep, files, files_visited);
}
-
- for (vector<string>::const_iterator iter = other_imports_.begin();
- iter != other_imports_.end(); ++iter) {
- printer->Print(
- " #import \"$header$\"\n",
- "header", *iter);
+ } else {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ files_visited);
}
}
}
-void ImportWriter::ParseFrameworkMappings() {
- need_to_parse_mapping_file_ = false;
- if (options_.named_framework_to_proto_path_mappings_path.empty()) {
- return; // Nothing to do.
- }
-
- ProtoFrameworkCollector collector(&proto_file_to_framework_name_);
- string parse_error;
- if (!ParseSimpleFile(options_.named_framework_to_proto_path_mappings_path,
- &collector, &parse_error)) {
- cerr << "error parsing " << options_.named_framework_to_proto_path_mappings_path
- << " : " << parse_error << endl;
- cerr.flush();
+// Collect the deps of the given file that contain extensions. This can be used to
+// create the chain of roots that need to be wired together.
+//
+// NOTE: If any changes are made to this and the supporting functions, you will
+// need to manually validate what the generated code is for the test files:
+// objectivec/Tests/unittest_extension_chain_*.proto
+// There are comments about what the expected code should be line and limited
+// testing objectivec/Tests/GPBUnittestProtos2.m around compilation (#imports
+// specifically).
+void CollectMinimalFileDepsContainingExtensions(
+ const FileDescriptor* file,
+ vector<const FileDescriptor*>* files) {
+ set<const FileDescriptor*> files_visited;
+ for (int i = 0; i < file->dependency_count(); i++) {
+ const FileDescriptor* dep = file->dependency(i);
+ CollectMinimalFileDepsContainingExtensionsWorker(dep, files,
+ &files_visited);
}
}
-bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
- const StringPiece& line, string* out_error) {
- int offset = line.find(':');
- if (offset == StringPiece::npos) {
- *out_error =
- string("Framework/proto file mapping line without colon sign: '") +
- line.ToString() + "'.";
- return false;
- }
- StringPiece framework_name(line, 0, offset);
- StringPiece proto_file_list(line, offset + 1, line.length() - offset - 1);
- StringPieceTrimWhitespace(&framework_name);
-
- int start = 0;
- while (start < proto_file_list.length()) {
- offset = proto_file_list.find(',', start);
- if (offset == StringPiece::npos) {
- offset = proto_file_list.length();
- }
-
- StringPiece proto_file(proto_file_list, start, offset);
- StringPieceTrimWhitespace(&proto_file);
- if (proto_file.size() != 0) {
- map<string, string>::iterator existing_entry =
- map_->find(proto_file.ToString());
- if (existing_entry != map_->end()) {
- cerr << "warning: duplicate proto file reference, replacing framework entry for '"
- << proto_file.ToString() << "' with '" << framework_name.ToString()
- << "' (was '" << existing_entry->second << "')." << endl;
- cerr.flush();
- }
-
- if (proto_file.find(' ') != StringPiece::npos) {
- cerr << "note: framework mapping file had a proto file with a space in, hopefully that isn't a missing comma: '"
- << proto_file.ToString() << "'" << endl;
- cerr.flush();
- }
-
- (*map_)[proto_file.ToString()] = framework_name.ToString();
+bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ if (dep == file->dependency(i)) {
+ return true;
}
-
- start = offset + 1;
}
-
- return true;
+ return false;
}
} // namespace
-
FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
: file_(file),
root_class_name_(FileClassName(file)),
- is_public_dep_(false),
options_(options) {
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
@@ -275,8 +180,6 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
}
FileGenerator::~FileGenerator() {
- STLDeleteContainerPointers(dependency_generators_.begin(),
- dependency_generators_.end());
STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
STLDeleteContainerPointers(message_generators_.begin(),
message_generators_.end());
@@ -299,14 +202,12 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
// #import any headers for "public imports" in the proto file.
{
- ImportWriter import_writer(options_);
- const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
- if ((*iter)->IsPublicDependency()) {
- import_writer.AddFile(*iter);
- }
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path);
+ const string header_extension(kHeaderExtension);
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ import_writer.AddFile(file_->public_dependency(i), header_extension);
}
import_writer.Print(printer);
}
@@ -357,14 +258,16 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
printer->Print(
"#pragma mark - $root_class_name$\n"
"\n"
- "/// Exposes the extension registry for this file.\n"
- "///\n"
- "/// The base class provides:\n"
- "/// @code\n"
- "/// + (GPBExtensionRegistry *)extensionRegistry;\n"
- "/// @endcode\n"
- "/// which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
- "/// this file and all files that it depends on.\n"
+ "/**\n"
+ " * Exposes the extension registry for this file.\n"
+ " *\n"
+ " * The base class provides:\n"
+ " * @code\n"
+ " * + (GPBExtensionRegistry *)extensionRegistry;\n"
+ " * @endcode\n"
+ " * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n"
+ " * this file and all files that it depends on.\n"
+ " **/\n"
"@interface $root_class_name$ : GPBRootObject\n"
"@end\n"
"\n",
@@ -404,21 +307,41 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
// #import the runtime support.
PrintFileRuntimePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h");
+ vector<const FileDescriptor*> deps_with_extensions;
+ CollectMinimalFileDepsContainingExtensions(file_, &deps_with_extensions);
+
{
- ImportWriter import_writer(options_);
+ ImportWriter import_writer(
+ options_.generate_for_named_framework,
+ options_.named_framework_to_proto_path_mappings_path);
+ const string header_extension(kHeaderExtension);
// #import the header for this proto file.
- import_writer.AddFile(this);
+ import_writer.AddFile(file_, header_extension);
// #import the headers for anything that a plain dependency of this proto
// file (that means they were just an include, not a "public" include).
- const vector<FileGenerator *> &dependency_generators =
- DependencyGenerators();
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
- if (!(*iter)->IsPublicDependency()) {
- import_writer.AddFile(*iter);
+ set<string> public_import_names;
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ public_import_names.insert(file_->public_dependency(i)->name());
+ }
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor *dep = file_->dependency(i);
+ bool public_import = (public_import_names.count(dep->name()) != 0);
+ if (!public_import) {
+ import_writer.AddFile(dep, header_extension);
+ }
+ }
+
+ // If any indirect dependency provided extensions, it needs to be directly
+ // imported so it can get merged into the root's extensions registry.
+ // See the Note by CollectMinimalFileDepsContainingExtensions before
+ // changing this.
+ for (vector<const FileDescriptor *>::iterator iter =
+ deps_with_extensions.begin();
+ iter != deps_with_extensions.end(); ++iter) {
+ if (!IsDirectDependency(*iter, file_)) {
+ import_writer.AddFile(*iter, header_extension);
}
}
@@ -458,29 +381,11 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"@implementation $root_class_name$\n\n",
"root_class_name", root_class_name_);
- // 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();
- }
+ const bool file_contains_extensions = FileContainsExtensions(file_);
// If there were any extensions or this file has any dependencies, output
// a registry to override to create the file specific registry.
- const string& extensions_str = extensions_stringstream.str();
- if (extensions_str.length() > 0 || file_->dependency_count() > 0) {
+ if (file_contains_extensions || !deps_with_extensions.empty()) {
printer->Print(
"+ (GPBExtensionRegistry*)extensionRegistry {\n"
" // This is called by +initialize so there is no need to worry\n"
@@ -493,11 +398,20 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
printer->Indent();
printer->Indent();
- if (extensions_str.length() > 0) {
+ if (file_contains_extensions) {
printer->Print(
"static GPBExtensionDescription descriptions[] = {\n");
printer->Indent();
- printer->Print(extensions_str.c_str());
+ for (vector<ExtensionGenerator *>::iterator iter =
+ extension_generators_.begin();
+ iter != extension_generators_.end(); ++iter) {
+ (*iter)->GenerateStaticVariablesInitialization(printer);
+ }
+ for (vector<MessageGenerator *>::iterator iter =
+ message_generators_.begin();
+ iter != message_generators_.end(); ++iter) {
+ (*iter)->GenerateStaticVariablesInitialization(printer);
+ }
printer->Outdent();
printer->Print(
"};\n"
@@ -510,14 +424,21 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"}\n");
}
- const vector<FileGenerator *> &dependency_generators =
- DependencyGenerators();
- for (vector<FileGenerator *>::const_iterator iter =
- dependency_generators.begin();
- iter != dependency_generators.end(); ++iter) {
+ if (deps_with_extensions.empty()) {
printer->Print(
- "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
- "dependency", (*iter)->RootClassName());
+ "// None of the imports (direct or indirect) defined extensions, so no need to add\n"
+ "// them to this registry.\n");
+ } else {
+ printer->Print(
+ "// Merge in the imports (direct or indirect) that defined extensions.\n");
+ for (vector<const FileDescriptor *>::iterator iter =
+ deps_with_extensions.begin();
+ iter != deps_with_extensions.end(); ++iter) {
+ const string root_class_name(FileClassName((*iter)));
+ printer->Print(
+ "[registry addExtensions:[$dependency$ extensionRegistry]];\n",
+ "dependency", root_class_name);
+ }
}
printer->Outdent();
@@ -526,27 +447,39 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
printer->Print(
" }\n"
" return registry;\n"
- "}\n"
- "\n");
+ "}\n");
+ } else {
+ if (file_->dependency_count() > 0) {
+ printer->Print(
+ "// No extensions in the file and none of the imports (direct or indirect)\n"
+ "// defined extensions, so no need to generate +extensionRegistry.\n");
+ } else {
+ printer->Print(
+ "// No extensions in the file and no imports, so no need to generate\n"
+ "// +extensionRegistry.\n");
+ }
}
- printer->Print("@end\n\n");
+ printer->Print("\n@end\n\n");
// File descriptor only needed if there are messages to use it.
if (message_generators_.size() > 0) {
- string syntax;
+ map<string, string> vars;
+ vars["root_class_name"] = root_class_name_;
+ vars["package"] = file_->package();
+ vars["objc_prefix"] = FileClassPrefix(file_);
switch (file_->syntax()) {
case FileDescriptor::SYNTAX_UNKNOWN:
- syntax = "GPBFileSyntaxUnknown";
+ vars["syntax"] = "GPBFileSyntaxUnknown";
break;
case FileDescriptor::SYNTAX_PROTO2:
- syntax = "GPBFileSyntaxProto2";
+ vars["syntax"] = "GPBFileSyntaxProto2";
break;
case FileDescriptor::SYNTAX_PROTO3:
- syntax = "GPBFileSyntaxProto3";
+ vars["syntax"] = "GPBFileSyntaxProto3";
break;
}
- printer->Print(
+ printer->Print(vars,
"#pragma mark - $root_class_name$_FileDescriptor\n"
"\n"
"static GPBFileDescriptor *$root_class_name$_FileDescriptor(void) {\n"
@@ -554,16 +487,24 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
" // 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"
+ " GPBDebugCheckRuntimeVersion();\n");
+ if (vars["objc_prefix"].size() > 0) {
+ printer->Print(
+ vars,
+ " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+ " objcPrefix:@\"$objc_prefix$\"\n"
+ " syntax:$syntax$];\n");
+ } else {
+ printer->Print(
+ vars,
+ " descriptor = [[GPBFileDescriptor alloc] initWithPackage:@\"$package$\"\n"
+ " syntax:$syntax$];\n");
+ }
+ printer->Print(
" }\n"
" return descriptor;\n"
"}\n"
- "\n",
- "root_class_name", root_class_name_,
- "package", file_->package(),
- "syntax", syntax);
+ "\n");
}
for (vector<EnumGenerator *>::iterator iter = enum_generators_.begin();
@@ -582,24 +523,6 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"// @@protoc_insertion_point(global_scope)\n");
}
-const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
- if (file_->dependency_count() != dependency_generators_.size()) {
- set<string> public_import_names;
- for (int i = 0; i < file_->public_dependency_count(); i++) {
- public_import_names.insert(file_->public_dependency(i)->name());
- }
- for (int i = 0; i < file_->dependency_count(); i++) {
- FileGenerator *generator =
- new FileGenerator(file_->dependency(i), options_);
- const string& name = file_->dependency(i)->name();
- bool public_import = (public_import_names.count(name) != 0);
- generator->SetIsPublicDependency(public_import);
- dependency_generators_.push_back(generator);
- }
- }
- return dependency_generators_;
-}
-
// Helper to print the import of the runtime support at the top of generated
// files. This currently only supports the runtime coming from a framework
// as defined by the official CocoaPod.
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h
index 8e4388d8..a60a6885 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h
@@ -62,32 +62,17 @@ class FileGenerator {
void GenerateHeader(io::Printer* printer);
const string& RootClassName() const { return root_class_name_; }
- const string Path() const { return FilePath(file_); }
- const FileDescriptor* Descriptor() const { return file_; }
-
- bool IsPublicDependency() const { return is_public_dep_; }
-
- protected:
- void SetIsPublicDependency(bool is_public_dep) {
- is_public_dep_ = is_public_dep;
- }
private:
const FileDescriptor* file_;
string root_class_name_;
- // Access this field through the DependencyGenerators accessor call below.
- // Do not reference it directly.
- vector<FileGenerator*> dependency_generators_;
-
vector<EnumGenerator*> enum_generators_;
vector<MessageGenerator*> message_generators_;
vector<ExtensionGenerator*> extension_generators_;
- bool is_public_dep_;
const Options options_;
- const vector<FileGenerator*>& DependencyGenerators();
void PrintFileRuntimePreamble(
io::Printer* printer, const string& header_to_import) const;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
index 29a8765c..36407467 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc
@@ -45,12 +45,29 @@ ObjectiveCGenerator::ObjectiveCGenerator() {}
ObjectiveCGenerator::~ObjectiveCGenerator() {}
+bool ObjectiveCGenerator::HasGenerateAll() const {
+ return true;
+}
+
bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
const string& parameter,
- OutputDirectory* output_directory,
+ GeneratorContext* context,
string* error) const {
+ *error = "Unimplemented Generate() method. Call GenerateAll() instead.";
+ return false;
+}
+
+bool ObjectiveCGenerator::GenerateAll(const vector<const FileDescriptor*>& files,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const {
// -----------------------------------------------------------------
- // Parse generator options.
+ // Parse generator options. These options are passed to the compiler using the
+ // --objc_opt flag. The options are passed as a comma separated list of
+ // options along with their values. If the option appears multiple times, only
+ // the last value will be considered.
+ //
+ // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework
Options generation_options;
@@ -70,7 +87,7 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
// (i.e. - "package=prefix # comment")
//
// There is no validation that the prefixes are good prefixes, it is
- // assume they are when you create the file.
+ // assumed that they are when you create the file.
generation_options.expected_prefixes_path = options[i].second;
} else if (options[i].first == "generate_for_named_framework") {
// The name of the framework that protos are being generated for. This
@@ -79,11 +96,12 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
//
// NOTE: If this option is used with
// named_framework_to_proto_path_mappings_path, then this is effectively
- // the "default" to use for everything that wasn't mapped by the other.
- generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
+ // the "default" framework name used for everything that wasn't mapped by
+ // the mapping file.
+ generation_options.generate_for_named_framework = options[i].second;
} else if (options[i].first == "named_framework_to_proto_path_mappings_path") {
- // Path to find a file containing the listing of framework names and
- // proto files. The generator uses this to decide if another proto file
+ // Path to find a file containing the list of framework names and proto
+ // files. The generator uses this to decide if a proto file
// referenced should use a framework style import vs. a user level import
// (#import <FRAMEWORK/file.pbobjc.h> vs #import "dir/file.pbobjc.h").
//
@@ -97,8 +115,11 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
// with commas.
//
// There can be multiple lines listing the same frameworkName incase it
- // has a lot of proto files included in it; and having multiple lines
- // makes things easier to read.
+ // has a lot of proto files included in it; having multiple lines makes
+ // things easier to read. If a proto file is not configured in the
+ // mappings file, it will use the default framework name if one was passed
+ // with generate_for_named_framework, or the relative path to it's include
+ // path otherwise.
generation_options.named_framework_to_proto_path_mappings_path = options[i].second;
} else {
*error = "error: Unknown generator option: " + options[i].first;
@@ -108,29 +129,32 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
// -----------------------------------------------------------------
- // Validate the objc prefix/package pairing.
- if (!ValidateObjCClassPrefix(file, generation_options, error)) {
+ // Validate the objc prefix/package pairings.
+ if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
// *error will have been filled in.
return false;
}
- FileGenerator file_generator(file, generation_options);
- string filepath = FilePath(file);
+ for (int i = 0; i < files.size(); i++) {
+ const FileDescriptor* file = files[i];
+ FileGenerator file_generator(file, generation_options);
+ string filepath = FilePath(file);
- // Generate header.
- {
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(filepath + ".pbobjc.h"));
- io::Printer printer(output.get(), '$');
- file_generator.GenerateHeader(&printer);
- }
+ // Generate header.
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filepath + ".pbobjc.h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateHeader(&printer);
+ }
- // Generate m file.
- {
- scoped_ptr<io::ZeroCopyOutputStream> output(
- output_directory->Open(filepath + ".pbobjc.m"));
- io::Printer printer(output.get(), '$');
- file_generator.GenerateSource(&printer);
+ // Generate m file.
+ {
+ scoped_ptr<io::ZeroCopyOutputStream> output(
+ context->Open(filepath + ".pbobjc.m"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateSource(&printer);
+ }
}
return true;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h
index 09266b04..9d801d51 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_generator.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h
@@ -47,8 +47,15 @@ class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
~ObjectiveCGenerator();
// implements CodeGenerator ----------------------------------------
- bool Generate(const FileDescriptor* file, const string& parameter,
- OutputDirectory* output_directory, string* error) const;
+ bool HasGenerateAll() const;
+ bool Generate(const FileDescriptor* file,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const;
+ bool GenerateAll(const vector<const FileDescriptor*>& files,
+ const string& parameter,
+ GeneratorContext* context,
+ string* error) const;
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 311bf35d..c7fd96ac 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -44,9 +44,10 @@
#include <google/protobuf/stubs/hash.h>
#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
+#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
@@ -209,10 +210,14 @@ const char* const kReservedWordList[] = {
hash_set<string> kReservedWords =
MakeWordsMap(kReservedWordList, GOOGLE_ARRAYSIZE(kReservedWordList));
-string SanitizeNameForObjC(const string& input, const string& extension) {
+string SanitizeNameForObjC(const string& input,
+ const string& extension,
+ string* out_suffix_added) {
if (kReservedWords.count(input) > 0) {
+ if (out_suffix_added) *out_suffix_added = extension;
return input + extension;
}
+ if (out_suffix_added) out_suffix_added->clear();
return input;
}
@@ -261,6 +266,34 @@ bool IsSpecialName(const string& name, const string* special_names,
return false;
}
+string GetZeroEnumNameForFlagType(const FlagType flag_type) {
+ switch(flag_type) {
+ case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
+ return "GPBDescriptorInitializationFlag_None";
+ case FLAGTYPE_EXTENSION:
+ return "GPBExtensionNone";
+ case FLAGTYPE_FIELD:
+ return "GPBFieldNone";
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return "0";
+ }
+}
+
+string GetEnumNameForFlagType(const FlagType flag_type) {
+ switch(flag_type) {
+ case FLAGTYPE_DESCRIPTOR_INITIALIZATION:
+ return "GPBDescriptorInitializationFlags";
+ case FLAGTYPE_EXTENSION:
+ return "GPBExtensionOptions";
+ case FLAGTYPE_FIELD:
+ return "GPBFieldFlags";
+ default:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return string();
+ }
+}
+
} // namespace
// Escape C++ trigraphs by escaping question marks to \?
@@ -307,6 +340,12 @@ string BaseFileName(const FileDescriptor* file) {
return basename;
}
+string FileClassPrefix(const FileDescriptor* file) {
+ // Default is empty string, no need to check has_objc_class_prefix.
+ string result = file->options().objc_class_prefix();
+ return result;
+}
+
string FilePath(const FileDescriptor* file) {
string output;
string basename;
@@ -337,19 +376,13 @@ string FilePathBasename(const FileDescriptor* file) {
return output;
}
-string FileClassPrefix(const FileDescriptor* file) {
- // Default is empty string, no need to check has_objc_class_prefix.
- string result = file->options().objc_class_prefix();
- return result;
-}
-
string FileClassName(const FileDescriptor* file) {
string name = FileClassPrefix(file);
name += UnderscoresToCamelCase(StripProto(BaseFileName(file)), true);
name += "Root";
// There aren't really any reserved words that end in "Root", but playing
// it safe and checking.
- return SanitizeNameForObjC(name, "_RootClass");
+ return SanitizeNameForObjC(name, "_RootClass", NULL);
}
string ClassNameWorker(const Descriptor* descriptor) {
@@ -371,11 +404,15 @@ string ClassNameWorker(const EnumDescriptor* descriptor) {
}
string ClassName(const Descriptor* descriptor) {
+ return ClassName(descriptor, NULL);
+}
+
+string ClassName(const Descriptor* descriptor, string* out_suffix_added) {
// 1. Message names are used as is (style calls for CamelCase, trust it).
// 2. Check for reserved word at the very end and then suffix things.
string prefix = FileClassPrefix(descriptor->file());
string name = ClassNameWorker(descriptor);
- return SanitizeNameForObjC(prefix + name, "_Class");
+ return SanitizeNameForObjC(prefix + name, "_Class", out_suffix_added);
}
string EnumName(const EnumDescriptor* descriptor) {
@@ -389,7 +426,7 @@ string EnumName(const EnumDescriptor* descriptor) {
// yields Fixed_Class, Fixed_Size.
string name = FileClassPrefix(descriptor->file());
name += ClassNameWorker(descriptor);
- return SanitizeNameForObjC(name, "_Enum");
+ return SanitizeNameForObjC(name, "_Enum", NULL);
}
string EnumValueName(const EnumValueDescriptor* descriptor) {
@@ -404,7 +441,7 @@ string EnumValueName(const EnumValueDescriptor* descriptor) {
const string& name = class_name + "_" + value_str;
// There aren't really any reserved words with an underscore and a leading
// capital letter, but playing it safe and checking.
- return SanitizeNameForObjC(name, "_Value");
+ return SanitizeNameForObjC(name, "_Value", NULL);
}
string EnumValueShortName(const EnumValueDescriptor* descriptor) {
@@ -441,7 +478,7 @@ string UnCamelCaseEnumShortName(const string& name) {
string ExtensionMethodName(const FieldDescriptor* descriptor) {
const string& name = NameFromFieldDescriptor(descriptor);
const string& result = UnderscoresToCamelCase(name, false);
- return SanitizeNameForObjC(result, "_Extension");
+ return SanitizeNameForObjC(result, "_Extension", NULL);
}
string FieldName(const FieldDescriptor* field) {
@@ -456,7 +493,7 @@ string FieldName(const FieldDescriptor* field) {
result += "_p";
}
}
- return SanitizeNameForObjC(result, "_p");
+ return SanitizeNameForObjC(result, "_p", NULL);
}
string FieldNameCapitalized(const FieldDescriptor* field) {
@@ -816,21 +853,26 @@ bool HasNonZeroDefaultValue(const FieldDescriptor* field) {
return false;
}
-string BuildFlagsString(const vector<string>& strings) {
+string BuildFlagsString(const FlagType flag_type,
+ const vector<string>& strings) {
if (strings.size() == 0) {
- return "0";
+ return GetZeroEnumNameForFlagType(flag_type);
+ } else if (strings.size() == 1) {
+ return strings[0];
}
- string string;
+ string string("(" + GetEnumNameForFlagType(flag_type) + ")(");
for (size_t i = 0; i != strings.size(); ++i) {
if (i > 0) {
string.append(" | ");
}
string.append(strings[i]);
}
+ string.append(")");
return string;
}
-string BuildCommentsString(const SourceLocation& location) {
+string BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line) {
const string& comments = location.leading_comments.empty()
? location.trailing_comments
: location.leading_comments;
@@ -839,15 +881,45 @@ string BuildCommentsString(const SourceLocation& location) {
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
- string prefix("///");
- string suffix("\n");
+ // If there are no comments, just return an empty string.
+ if (lines.size() == 0) {
+ return "";
+ }
+
+ string prefix;
+ string suffix;
string final_comments;
- for (int i = 0; i < lines.size(); i++) {
- // HeaderDoc uses '\' and '@' for markers; escape them.
- const string line = StringReplace(lines[i], "\\", "\\\\", true);
- final_comments +=
- prefix + StringReplace(line, "@", "\\@", true) + suffix;
+ string epilogue;
+
+ bool add_leading_space = false;
+
+ if (prefer_single_line && lines.size() == 1) {
+ prefix = "/** ";
+ suffix = " */\n";
+ } else {
+ prefix = "* ";
+ suffix = "\n";
+ final_comments += "/**\n";
+ epilogue = " **/\n";
+ add_leading_space = true;
}
+
+ for (int i = 0; i < lines.size(); i++) {
+ string line = StripPrefixString(lines[i], " ");
+ // HeaderDoc and appledoc use '\' and '@' for markers; escape them.
+ line = StringReplace(line, "\\", "\\\\", true);
+ line = StringReplace(line, "@", "\\@", true);
+ // Decouple / from * to not have inline comments inside comments.
+ line = StringReplace(line, "/*", "/\\*", true);
+ line = StringReplace(line, "*/", "*\\/", true);
+ line = prefix + line;
+ StripWhitespace(&line);
+ // If not a one line, need to add the first space before *, as
+ // StripWhitespace would have removed it.
+ line = (add_leading_space ? " " : "") + line;
+ final_comments += line + suffix;
+ }
+ final_comments += epilogue;
return final_comments;
}
@@ -948,28 +1020,20 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options,
generation_options.expected_prefixes_path, &collector, out_error);
}
-} // namespace
-
-bool ValidateObjCClassPrefix(const FileDescriptor* file,
- const Options& generation_options,
- string* out_error) {
+bool ValidateObjCClassPrefix(
+ const FileDescriptor* file,
+ const string& expected_prefixes_path,
+ const map<string, string>& expected_package_prefixes,
+ string* out_error) {
const string prefix = file->options().objc_class_prefix();
const string package = file->package();
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for warnings.
- // Load any expected package prefixes to validate against those.
- map<string, string> expected_package_prefixes;
- if (!LoadExpectedPackagePrefixes(generation_options,
- &expected_package_prefixes,
- out_error)) {
- return false;
- }
-
// Check: Error - See if there was an expected prefix for the package and
// report if it doesn't match (wrong or missing).
- map<string, string>::iterator package_match =
+ map<string, string>::const_iterator package_match =
expected_package_prefixes.find(package);
if (package_match != expected_package_prefixes.end()) {
// There was an entry, and...
@@ -990,27 +1054,11 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
}
// If there was no prefix option, we're done at this point.
- if (prefix.length() == 0) {
+ if (prefix.empty()) {
// No prefix, nothing left to check.
return true;
}
- // Check: Error - Make sure the prefix wasn't expected for a different
- // package (overlap is allowed, but it has to be listed as an expected
- // overlap).
- for (map<string, string>::iterator i = expected_package_prefixes.begin();
- i != expected_package_prefixes.end(); ++i) {
- if (i->second == prefix) {
- *out_error =
- "error: Found 'option objc_class_prefix = \"" + prefix +
- "\";' in '" + file->name() +
- "'; that prefix is already used for 'package " + i->first +
- ";'. It can only be reused by listing it in the expected file (" +
- generation_options.expected_prefixes_path + ").";
- return false; // Only report first usage of the prefix.
- }
- }
-
// Check: Warning - Make sure the prefix is is a reasonable value according
// to Apple's rules (the checks above implicitly whitelist anything that
// doesn't meet these rules).
@@ -1032,6 +1080,56 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
cerr.flush();
}
+ // Look for any other package that uses the same prefix.
+ string other_package_for_prefix;
+ for (map<string, string>::const_iterator i = expected_package_prefixes.begin();
+ i != expected_package_prefixes.end(); ++i) {
+ if (i->second == prefix) {
+ other_package_for_prefix = i->first;
+ break;
+ }
+ }
+
+ // Check: Warning - If the file does not have a package, check whether
+ // the prefix declared is being used by another package or not.
+ if (package.empty()) {
+ // The file does not have a package and ...
+ if (other_package_for_prefix.empty()) {
+ // ... no other package has declared that prefix.
+ cerr << endl
+ << "protoc:0: warning: File '" << file->name() << "' has no "
+ << "package. Consider adding a new package to the proto and adding '"
+ << "new.package = " << prefix << "' to the expected prefixes file ("
+ << expected_prefixes_path << ")." << endl;
+ cerr.flush();
+ } else {
+ // ... another package has declared the same prefix.
+ cerr << endl
+ << "protoc:0: warning: File '" << file->name() << "' has no package "
+ << "and package '" << other_package_for_prefix << "' already uses '"
+ << prefix << "' as its prefix. Consider either adding a new package "
+ << "to the proto, or reusing one of the packages already using this "
+ << "prefix in the expected prefixes file ("
+ << expected_prefixes_path << ")." << endl;
+ cerr.flush();
+ }
+ return true;
+ }
+
+ // Check: Error - Make sure the prefix wasn't expected for a different
+ // package (overlap is allowed, but it has to be listed as an expected
+ // overlap).
+ if (!other_package_for_prefix.empty()) {
+ *out_error =
+ "error: Found 'option objc_class_prefix = \"" + prefix +
+ "\";' in '" + file->name() +
+ "'; that prefix is already used for 'package " +
+ other_package_for_prefix + ";'. It can only be reused by listing " +
+ "it in the expected file (" +
+ expected_prefixes_path + ").";
+ return false; // Only report first usage of the prefix.
+ }
+
// Check: Warning - If the given package/prefix pair wasn't expected, issue a
// warning issue a warning suggesting it gets added to the file.
if (!expected_package_prefixes.empty()) {
@@ -1039,13 +1137,39 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
<< "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
<< " consider adding it to the expected prefixes file ("
- << generation_options.expected_prefixes_path << ")." << endl;
+ << expected_prefixes_path << ")." << endl;
cerr.flush();
}
return true;
}
+} // namespace
+
+bool ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files,
+ const Options& generation_options,
+ string* out_error) {
+ // Load the expected package prefixes, if available, to validate against.
+ map<string, string> expected_package_prefixes;
+ if (!LoadExpectedPackagePrefixes(generation_options,
+ &expected_package_prefixes,
+ out_error)) {
+ return false;
+ }
+
+ for (int i = 0; i < files.size(); i++) {
+ bool is_valid =
+ ValidateObjCClassPrefix(files[i],
+ generation_options.expected_prefixes_path,
+ expected_package_prefixes,
+ out_error);
+ if (!is_valid) {
+ return false;
+ }
+ }
+ return true;
+}
+
TextFormatDecodeData::TextFormatDecodeData() { }
TextFormatDecodeData::~TextFormatDecodeData() { }
@@ -1306,7 +1430,8 @@ bool Parser::Finish() {
return true;
}
// Force a newline onto the end to finish parsing.
- p_ = StringPiece(leftover_ + "\n");
+ leftover_ += "\n";
+ p_ = StringPiece(leftover_);
if (!ParseLoop()) {
return false;
}
@@ -1367,6 +1492,178 @@ bool ParseSimpleFile(
return parser.Finish();
}
+ImportWriter::ImportWriter(
+ const string& generate_for_named_framework,
+ const string& named_framework_to_proto_path_mappings_path)
+ : generate_for_named_framework_(generate_for_named_framework),
+ named_framework_to_proto_path_mappings_path_(
+ named_framework_to_proto_path_mappings_path),
+ need_to_parse_mapping_file_(true) {
+}
+
+ImportWriter::~ImportWriter() {}
+
+void ImportWriter::AddFile(const FileDescriptor* file,
+ const string& header_extension) {
+ const string file_path(FilePath(file));
+
+ if (IsProtobufLibraryBundledProtoFile(file)) {
+ protobuf_framework_imports_.push_back(
+ FilePathBasename(file) + header_extension);
+ protobuf_non_framework_imports_.push_back(file_path + header_extension);
+ return;
+ }
+
+ // Lazy parse any mappings.
+ if (need_to_parse_mapping_file_) {
+ ParseFrameworkMappings();
+ }
+
+ map<string, string>::iterator proto_lookup =
+ proto_file_to_framework_name_.find(file->name());
+ if (proto_lookup != proto_file_to_framework_name_.end()) {
+ other_framework_imports_.push_back(
+ proto_lookup->second + "/" +
+ FilePathBasename(file) + header_extension);
+ return;
+ }
+
+ if (!generate_for_named_framework_.empty()) {
+ other_framework_imports_.push_back(
+ generate_for_named_framework_ + "/" +
+ FilePathBasename(file) + header_extension);
+ return;
+ }
+
+ other_imports_.push_back(file_path + header_extension);
+}
+
+void ImportWriter::Print(io::Printer* printer) const {
+ assert(protobuf_non_framework_imports_.size() ==
+ protobuf_framework_imports_.size());
+
+ bool add_blank_line = false;
+
+ if (protobuf_framework_imports_.size() > 0) {
+ const string framework_name(ProtobufLibraryFrameworkName);
+ const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name));
+
+ printer->Print(
+ "#if $cpp_symbol$\n",
+ "cpp_symbol", cpp_symbol);
+ for (vector<string>::const_iterator iter = protobuf_framework_imports_.begin();
+ iter != protobuf_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import <$framework_name$/$header$>\n",
+ "framework_name", framework_name,
+ "header", *iter);
+ }
+ printer->Print(
+ "#else\n");
+ for (vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin();
+ iter != protobuf_non_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import \"$header$\"\n",
+ "header", *iter);
+ }
+ printer->Print(
+ "#endif\n");
+
+ add_blank_line = true;
+ }
+
+ if (other_framework_imports_.size() > 0) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (vector<string>::const_iterator iter = other_framework_imports_.begin();
+ iter != other_framework_imports_.end(); ++iter) {
+ printer->Print(
+ " #import <$header$>\n",
+ "header", *iter);
+ }
+
+ add_blank_line = true;
+ }
+
+ if (other_imports_.size() > 0) {
+ if (add_blank_line) {
+ printer->Print("\n");
+ }
+
+ for (vector<string>::const_iterator iter = other_imports_.begin();
+ iter != other_imports_.end(); ++iter) {
+ printer->Print(
+ " #import \"$header$\"\n",
+ "header", *iter);
+ }
+ }
+}
+
+void ImportWriter::ParseFrameworkMappings() {
+ need_to_parse_mapping_file_ = false;
+ if (named_framework_to_proto_path_mappings_path_.empty()) {
+ return; // Nothing to do.
+ }
+
+ ProtoFrameworkCollector collector(&proto_file_to_framework_name_);
+ string parse_error;
+ if (!ParseSimpleFile(named_framework_to_proto_path_mappings_path_,
+ &collector, &parse_error)) {
+ cerr << "error parsing " << named_framework_to_proto_path_mappings_path_
+ << " : " << parse_error << endl;
+ cerr.flush();
+ }
+}
+
+bool ImportWriter::ProtoFrameworkCollector::ConsumeLine(
+ const StringPiece& line, string* out_error) {
+ int offset = line.find(':');
+ if (offset == StringPiece::npos) {
+ *out_error =
+ string("Framework/proto file mapping line without colon sign: '") +
+ line.ToString() + "'.";
+ return false;
+ }
+ StringPiece framework_name(line, 0, offset);
+ StringPiece proto_file_list(line, offset + 1, line.length() - offset - 1);
+ StringPieceTrimWhitespace(&framework_name);
+
+ int start = 0;
+ while (start < proto_file_list.length()) {
+ offset = proto_file_list.find(',', start);
+ if (offset == StringPiece::npos) {
+ offset = proto_file_list.length();
+ }
+
+ StringPiece proto_file(proto_file_list, start, offset - start);
+ StringPieceTrimWhitespace(&proto_file);
+ if (proto_file.size() != 0) {
+ map<string, string>::iterator existing_entry =
+ map_->find(proto_file.ToString());
+ if (existing_entry != map_->end()) {
+ cerr << "warning: duplicate proto file reference, replacing framework entry for '"
+ << proto_file.ToString() << "' with '" << framework_name.ToString()
+ << "' (was '" << existing_entry->second << "')." << endl;
+ cerr.flush();
+ }
+
+ if (proto_file.find(' ') != StringPiece::npos) {
+ cerr << "note: framework mapping file had a proto file with a space in, hopefully that isn't a missing comma: '"
+ << proto_file.ToString() << "'" << endl;
+ cerr.flush();
+ }
+
+ (*map_)[proto_file.ToString()] = framework_name.ToString();
+ }
+
+ start = offset + 1;
+ }
+
+ return true;
+}
+
} // namespace objectivec
} // namespace compiler
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index be20beee..d17d44aa 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -67,6 +67,9 @@ bool IsRetainedName(const string& name);
// handling under ARC.
bool IsInitName(const string& name);
+// Gets the objc_class_prefix.
+string FileClassPrefix(const FileDescriptor* file);
+
// Gets the path of the file we're going to generate (sans the .pb.h
// extension). The path will be dependent on the objectivec package
// declared in the proto package.
@@ -83,6 +86,7 @@ string FileClassName(const FileDescriptor* file);
// These return the fully-qualified class name corresponding to the given
// descriptor.
string ClassName(const Descriptor* descriptor);
+string ClassName(const Descriptor* descriptor, string* out_suffix_added);
string EnumName(const EnumDescriptor* descriptor);
// Returns the fully-qualified name of the enum value corresponding to the
@@ -137,6 +141,12 @@ enum ObjectiveCType {
OBJECTIVECTYPE_MESSAGE
};
+enum FlagType {
+ FLAGTYPE_DESCRIPTOR_INITIALIZATION,
+ FLAGTYPE_EXTENSION,
+ FLAGTYPE_FIELD
+};
+
template<class TDescriptor>
string GetOptionalDeprecatedAttribute(const TDescriptor* descriptor, bool preSpace = true, bool postNewline = false) {
if (descriptor->options().deprecated()) {
@@ -168,10 +178,12 @@ string GPBGenericValueFieldName(const FieldDescriptor* field);
string DefaultValue(const FieldDescriptor* field);
bool HasNonZeroDefaultValue(const FieldDescriptor* field);
-string BuildFlagsString(const vector<string>& strings);
+string BuildFlagsString(const FlagType type, const vector<string>& strings);
-// Builds a HeaderDoc style comment out of the comments in the .proto file.
-string BuildCommentsString(const SourceLocation& location);
+// Builds HeaderDoc/appledoc style comments out of the comments in the .proto
+// file.
+string BuildCommentsString(const SourceLocation& location,
+ bool prefer_single_line);
// The name the commonly used by the library when built as a framework.
// This lines up to the name used in the CocoaPod.
@@ -183,12 +195,12 @@ string ProtobufFrameworkImportSymbol(const string& framework_name);
// Checks if the file is one of the proto's bundled with the library.
bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
-// Checks the prefix for a given file and outputs any warnings needed, if
-// there are flat out errors, then out_error is filled in and the result is
-// false.
-bool ValidateObjCClassPrefix(const FileDescriptor* file,
- const Options& generation_options,
- string* out_error);
+// Checks the prefix for the given files and outputs any warnings as needed. If
+// there are flat out errors, then out_error is filled in with the first error
+// and the result is false.
+bool ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files,
+ const Options& generation_options,
+ string* out_error);
// Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform
// the input into the expected output.
@@ -223,6 +235,43 @@ class LIBPROTOC_EXPORT LineConsumer {
bool ParseSimpleFile(
const string& path, LineConsumer* line_consumer, string* out_error);
+
+// Helper class for parsing framework import mappings and generating
+// import statements.
+class LIBPROTOC_EXPORT ImportWriter {
+ public:
+ ImportWriter(const string& generate_for_named_framework,
+ const string& named_framework_to_proto_path_mappings_path);
+ ~ImportWriter();
+
+ void AddFile(const FileDescriptor* file, const string& header_extension);
+ void Print(io::Printer *printer) const;
+
+ private:
+ class ProtoFrameworkCollector : public LineConsumer {
+ public:
+ ProtoFrameworkCollector(map<string, string>* inout_proto_file_to_framework_name)
+ : map_(inout_proto_file_to_framework_name) {}
+
+ virtual bool ConsumeLine(const StringPiece& line, string* out_error);
+
+ private:
+ map<string, string>* map_;
+ };
+
+ void ParseFrameworkMappings();
+
+ const string generate_for_named_framework_;
+ const string named_framework_to_proto_path_mappings_path_;
+ map<string, string> proto_file_to_framework_name_;
+ bool need_to_parse_mapping_file_;
+
+ vector<string> protobuf_framework_imports_;
+ vector<string> protobuf_non_framework_imports_;
+ vector<string> other_framework_imports_;
+ vector<string> other_imports_;
+};
+
} // namespace objectivec
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
index ac5d8aea..0bc9dc10 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -115,7 +115,7 @@ MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor,
if (value_field_flags.find("GPBFieldHasEnumDescriptor") != string::npos) {
field_flags.push_back("GPBFieldHasEnumDescriptor");
}
- variables_["fieldflags"] = BuildFlagsString(field_flags);
+ variables_["fieldflags"] = BuildFlagsString(FLAGTYPE_FIELD, field_flags);
ObjectiveCType value_objc_type = GetObjectiveCType(value_descriptor);
const bool value_is_object_type =
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
index e1a78619..4c6e1b55 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
@@ -331,7 +331,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
string message_comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
- message_comments = BuildCommentsString(location);
+ message_comments = BuildCommentsString(location, false);
} else {
message_comments = "";
}
@@ -521,7 +521,8 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
if (descriptor_->options().message_set_wire_format()) {
init_flags.push_back("GPBDescriptorInitializationFlag_WireFormat");
}
- vars["init_flags"] = BuildFlagsString(init_flags);
+ vars["init_flags"] = BuildFlagsString(FLAGTYPE_DESCRIPTOR_INITIALIZATION,
+ init_flags);
printer->Print(
vars,
@@ -579,6 +580,19 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
" [localDescriptor setupExtensionRanges:ranges\n"
" count:(uint32_t)(sizeof(ranges) / sizeof(GPBExtensionRange))];\n");
}
+ if (descriptor_->containing_type() != NULL) {
+ string parent_class_name = ClassName(descriptor_->containing_type());
+ printer->Print(
+ " [localDescriptor setupContainingMessageClassName:GPBStringifySymbol($parent_name$)];\n",
+ "parent_name", parent_class_name);
+ }
+ string suffix_added;
+ ClassName(descriptor_, &suffix_added);
+ if (suffix_added.size() > 0) {
+ printer->Print(
+ " [localDescriptor setupMessageClassNameSuffix:@\"$suffix$\"];\n",
+ "suffix", suffix_added);
+ }
printer->Print(
" NSAssert(descriptor == nil, @\"Startup recursed!\");\n"
" descriptor = localDescriptor;\n"
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
index 44bafd7f..5531ae24 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_oneof.cc
@@ -53,7 +53,7 @@ OneofGenerator::OneofGenerator(const OneofDescriptor* descriptor)
string comments;
SourceLocation location;
if (descriptor_->GetSourceLocation(&location)) {
- comments = BuildCommentsString(location);
+ comments = BuildCommentsString(location, true);
} else {
comments = "";
}
@@ -104,7 +104,9 @@ void OneofGenerator::GeneratePublicCasePropertyDeclaration(
void OneofGenerator::GenerateClearFunctionDeclaration(io::Printer* printer) {
printer->Print(
variables_,
- "/// Clears whatever value was set for the oneof '$name$'.\n"
+ "/**\n"
+ " * Clears whatever value was set for the oneof '$name$'.\n"
+ " **/\n"
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message);\n");
}
@@ -119,7 +121,7 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
variables_,
"void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
" GPBDescriptor *descriptor = [message descriptor];\n"
- " GPBOneofDescriptor *oneof = descriptor->oneofs_[$raw_index$];\n"
+ " GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
" GPBMaybeClearOneof(message, oneof, $index$, 0);\n"
"}\n");
}
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 214d7c9c..519ed8fc 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -525,7 +525,6 @@ bool Parser::Parse(io::Tokenizer* input, FileDescriptorProto* file) {
SourceCodeInfo source_code_info;
source_code_info_ = &source_code_info;
- vector<string> top_doc_comments;
if (LookingAtType(io::Tokenizer::TYPE_START)) {
// Advance to first token.
input_->NextWithComments(NULL, &upcoming_detached_comments_,
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index c4d48fc6..9064c382 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -36,6 +36,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -102,6 +103,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -123,6 +125,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
delete CodeGeneratorResponse_File_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fcompiler_2fplugin_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -161,16 +164,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fcompiler_2fplugin_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -451,7 +444,9 @@ int CodeGeneratorRequest::ByteSize() const {
void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorRequest* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorRequest>(
&from);
@@ -466,7 +461,9 @@ void CodeGeneratorRequest::MergeFrom(const ::google::protobuf::Message& from) {
void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_to_generate_.MergeFrom(from.file_to_generate_);
proto_file_.MergeFrom(from.proto_file_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
@@ -962,7 +959,9 @@ int CodeGeneratorResponse_File::ByteSize() const {
void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse_File* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse_File>(
&from);
@@ -977,7 +976,9 @@ void CodeGeneratorResponse_File::MergeFrom(const ::google::protobuf::Message& fr
void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -1269,7 +1270,9 @@ int CodeGeneratorResponse::ByteSize() const {
void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const CodeGeneratorResponse* source =
::google::protobuf::internal::DynamicCastToGenerated<const CodeGeneratorResponse>(
&from);
@@ -1284,7 +1287,9 @@ void CodeGeneratorResponse::MergeFrom(const ::google::protobuf::Message& from) {
void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_.MergeFrom(from.file_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_error()) {
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index cc54a8ab..d5468a0c 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -44,6 +44,7 @@
// performance-minded Python code leverage the fast C++ implementation
// directly.
+#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <map>
@@ -107,20 +108,25 @@ string ModuleAlias(const string& filename) {
return module_name;
}
-
-// Returns an import statement of form "from X.Y.Z import T" for the given
-// .proto filename.
-string ModuleImportStatement(const string& filename) {
- string module_name = ModuleName(filename);
- int last_dot_pos = module_name.rfind('.');
- if (last_dot_pos == string::npos) {
- // NOTE(petya): this is not tested as it would require a protocol buffer
- // outside of any package, and I don't think that is easily achievable.
- return "import " + module_name;
- } else {
- return "from " + module_name.substr(0, last_dot_pos) + " import " +
- module_name.substr(last_dot_pos + 1);
+// Keywords reserved by the Python language.
+const char* const kKeywords[] = {
+ "False", "None", "True", "and", "as", "assert", "break",
+ "class", "continue", "def", "del", "elif", "else", "except",
+ "finally", "for", "from", "global", "if", "import", "in",
+ "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
+ "return", "try", "while", "with", "yield",
+};
+const char* const* kKeywordsEnd =
+ kKeywords + (sizeof(kKeywords) / sizeof(kKeywords[0]));
+
+bool ContainsPythonKeyword(const string& module_name) {
+ vector<string> tokens = Split(module_name, ".");
+ for (int i = 0; i < tokens.size(); ++i) {
+ if (std::find(kKeywords, kKeywordsEnd, tokens[i]) != kKeywordsEnd) {
+ return true;
+ }
}
+ return false;
}
@@ -359,10 +365,32 @@ bool Generator::Generate(const FileDescriptor* file,
void Generator::PrintImports() const {
for (int i = 0; i < file_->dependency_count(); ++i) {
const string& filename = file_->dependency(i)->name();
- string import_statement = ModuleImportStatement(filename);
+
+ string module_name = ModuleName(filename);
string module_alias = ModuleAlias(filename);
- printer_->Print("$statement$ as $alias$\n", "statement",
- import_statement, "alias", module_alias);
+ if (ContainsPythonKeyword(module_name)) {
+ // If the module path contains a Python keyword, we have to quote the
+ // module name and import it using importlib. Otherwise the usual kind of
+ // import statement would result in a syntax error from the presence of
+ // the keyword.
+ printer_->Print("import importlib\n");
+ printer_->Print("$alias$ = importlib.import_module('$name$')\n", "alias",
+ module_alias, "name", module_name);
+ } else {
+ int last_dot_pos = module_name.rfind('.');
+ string import_statement;
+ if (last_dot_pos == string::npos) {
+ // NOTE(petya): this is not tested as it would require a protocol buffer
+ // outside of any package, and I don't think that is easily achievable.
+ import_statement = "import " + module_name;
+ } else {
+ import_statement = "from " + module_name.substr(0, last_dot_pos) +
+ " import " + module_name.substr(last_dot_pos + 1);
+ }
+ printer_->Print("$statement$ as $alias$\n", "statement", import_statement,
+ "alias", module_alias);
+ }
+
CopyPublicDependenciesAliases(module_alias, file_->dependency(i));
}
printer_->Print("\n");
diff --git a/src/google/protobuf/compiler/python/python_plugin_unittest.cc b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
index 23f2449c..34f857fd 100644
--- a/src/google/protobuf/compiler/python/python_plugin_unittest.cc
+++ b/src/google/protobuf/compiler/python/python_plugin_unittest.cc
@@ -46,6 +46,7 @@
#include <google/protobuf/testing/file.h>
#include <google/protobuf/testing/file.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -115,6 +116,53 @@ TEST(PythonPluginTest, PluginTest) {
EXPECT_EQ(0, cli.Run(5, argv));
}
+// This test verifies that the generated Python output uses regular imports (as
+// opposed to importlib) in the usual case where the .proto file paths do not
+// not contain any Python keywords.
+TEST(PythonPluginTest, ImportTest) {
+ // Create files test1.proto and test2.proto with the former importing the
+ // latter.
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test1.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "import \"test2.proto\";"
+ "message Message1 {\n"
+ " Message2 message_2 = 1;\n"
+ "}\n",
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(TestTempDir() + "/test2.proto",
+ "syntax = \"proto3\";\n"
+ "package foo;\n"
+ "message Message2 {}\n",
+ true));
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+ python::Generator python_generator;
+ cli.RegisterGenerator("--python_out", &python_generator, "");
+ string proto_path = "-I" + TestTempDir();
+ string python_out = "--python_out=" + TestTempDir();
+ const char* argv[] = {"protoc", proto_path.c_str(), "-I.", python_out.c_str(),
+ "test1.proto"};
+ ASSERT_EQ(0, cli.Run(5, argv));
+
+ // Loop over the lines of the generated code and verify that we find an
+ // ordinary Python import but do not find the string "importlib".
+ string output;
+ GOOGLE_CHECK_OK(File::GetContents(TestTempDir() + "/test1_pb2.py", &output,
+ true));
+ std::vector<string> lines = Split(output, "\n");
+ string expected_import = "import test2_pb2";
+ bool found_expected_import = false;
+ for (int i = 0; i < lines.size(); ++i) {
+ if (lines[i].find(expected_import) != string::npos) {
+ found_expected_import = true;
+ }
+ EXPECT_EQ(string::npos, lines[i].find("importlib"));
+ }
+ EXPECT_TRUE(found_expected_import);
+}
+
} // namespace
} // namespace python
} // namespace compiler
diff --git a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
index 49b23fbe..49b23fbe 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generated_code.rb
+++ b/src/google/protobuf/compiler/ruby/ruby_generated_code_pb.rb
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator.cc b/src/google/protobuf/compiler/ruby/ruby_generator.cc
index 92c76fb0..fbe3b4cb 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator.cc
@@ -48,7 +48,7 @@ namespace ruby {
// Forward decls.
std::string IntToString(int32 value);
-std::string StripDotProto(const std::string& proto_file);
+std::string GetRequireName(const std::string& proto_file);
std::string LabelForField(google::protobuf::FieldDescriptor* field);
std::string TypeName(google::protobuf::FieldDescriptor* field);
void GenerateMessage(const google::protobuf::Descriptor* message,
@@ -70,13 +70,13 @@ std::string IntToString(int32 value) {
return os.str();
}
-std::string StripDotProto(const std::string& proto_file) {
+std::string GetRequireName(const std::string& proto_file) {
int lastindex = proto_file.find_last_of(".");
- return proto_file.substr(0, lastindex);
+ return proto_file.substr(0, lastindex) + "_pb";
}
std::string GetOutputFilename(const std::string& proto_file) {
- return StripDotProto(proto_file) + ".rb";
+ return GetRequireName(proto_file) + ".rb";
}
std::string LabelForField(const google::protobuf::FieldDescriptor* field) {
@@ -237,15 +237,52 @@ void GenerateEnum(const google::protobuf::EnumDescriptor* en,
"end\n");
}
-// Module names, class names, and enum value names need to be Ruby constants,
-// which must start with a capital letter.
+// Locale-agnostic utility functions.
+bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; }
+
+bool IsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; }
+
+bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); }
+
+char ToUpper(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; }
+
+
+// Package names in protobuf are snake_case by convention, but Ruby module
+// names must be PascalCased.
+//
+// foo_bar_baz -> FooBarBaz
+std::string PackageToModule(const std::string& name) {
+ bool next_upper = true;
+ std::string result;
+ result.reserve(name.size());
+
+ for (int i = 0; i < name.size(); i++) {
+ if (name[i] == '_') {
+ next_upper = true;
+ } else {
+ if (next_upper) {
+ result.push_back(ToUpper(name[i]));
+ } else {
+ result.push_back(name[i]);
+ }
+ next_upper = false;
+ }
+ }
+
+ return result;
+}
+
+// Class and enum names in protobuf should be PascalCased by convention, but
+// since there is nothing enforcing this we need to ensure that they are valid
+// Ruby constants. That mainly means making sure that the first character is
+// an upper-case letter.
std::string RubifyConstant(const std::string& name) {
std::string ret = name;
if (!ret.empty()) {
- if (ret[0] >= 'a' && ret[0] <= 'z') {
+ if (IsLower(ret[0])) {
// If it starts with a lowercase letter, capitalize it.
- ret[0] = ret[0] - 'a' + 'A';
- } else if (ret[0] < 'A' || ret[0] > 'Z') {
+ ret[0] = ToUpper(ret[0]);
+ } else if (!IsAlpha(ret[0])) {
// Otherwise (e.g. if it begins with an underscore), we need to come up
// with some prefix that starts with a capital letter. We could be smarter
// here, e.g. try to strip leading underscores, but this may cause other
@@ -254,6 +291,7 @@ std::string RubifyConstant(const std::string& name) {
ret = "PB_" + ret;
}
}
+
return ret;
}
@@ -314,7 +352,7 @@ int GeneratePackageModules(
component = package_name.substr(0, dot_index);
package_name = package_name.substr(dot_index + 1);
}
- component = RubifyConstant(component);
+ component = PackageToModule(component);
printer->Print(
"module $name$\n",
"name", component);
@@ -391,7 +429,7 @@ bool MaybeEmitDependency(const FileDescriptor* import,
return true;
} else {
printer->Print(
- "require '$name$'\n", "name", StripDotProto(import->name()));
+ "require '$name$'\n", "name", GetRequireName(import->name()));
return true;
}
}
diff --git a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
index c0acb407..1aabe8aa 100644
--- a/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
+++ b/src/google/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -91,12 +91,12 @@ TEST(RubyGeneratorTest, GeneratorTest) {
// Load the generated output and compare to the expected result.
string output;
GOOGLE_CHECK_OK(File::GetContents(
- TestTempDir() + "/ruby_generated_code.rb",
+ TestTempDir() + "/ruby_generated_code_pb.rb",
&output,
true));
string expected_output;
GOOGLE_CHECK_OK(File::GetContents(
- ruby_tests + "/ruby_generated_code.rb",
+ ruby_tests + "/ruby_generated_code_pb.rb",
&expected_output,
true));
EXPECT_EQ(expected_output, output);
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index 6e258664..e929e4fb 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -261,12 +261,12 @@ string Subprocess::Win32ErrorMessage(DWORD error_code) {
char* message;
// WTF?
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, error_code, 0,
- (LPTSTR)&message, // NOT A BUG!
- 0, NULL);
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error_code, 0,
+ (LPSTR)&message, // NOT A BUG!
+ 0, NULL);
string result = message;
LocalFree(message);
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 4e2c9dcf..92c70c0d 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -106,6 +106,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -588,6 +589,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -697,6 +699,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
delete GeneratedCodeInfo_Annotation_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -834,9 +837,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
".protobuf.GeneratedCodeInfo.Annotation\032O"
"\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source"
"_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B"
- "X\n\023com.google.protobufB\020DescriptorProtos"
- "H\001Z\ndescriptor\242\002\003GPB\252\002\032Google.Protobuf.R"
- "eflection", 5289);
+ "[\n\023com.google.protobufB\020DescriptorProtos"
+ "H\001Z\ndescriptor\240\001\001\242\002\003GPB\252\002\032Google.Protobu"
+ "f.Reflection", 5292);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -899,16 +902,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -1088,7 +1081,9 @@ int FileDescriptorSet::ByteSize() const {
void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorSet)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileDescriptorSet* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorSet>(
&from);
@@ -1103,7 +1098,9 @@ void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
file_.MergeFrom(from.file_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -1856,7 +1853,9 @@ int FileDescriptorProto::ByteSize() const {
void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorProto>(
&from);
@@ -1871,7 +1870,9 @@ void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
dependency_.MergeFrom(from.dependency_);
public_dependency_.MergeFrom(from.public_dependency_);
weak_dependency_.MergeFrom(from.weak_dependency_);
@@ -2532,7 +2533,7 @@ void DescriptorProto_ExtensionRange::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -2682,7 +2683,9 @@ int DescriptorProto_ExtensionRange::ByteSize() const {
void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto_ExtensionRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ExtensionRange>(
&from);
@@ -2697,7 +2700,9 @@ void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message
void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_start()) {
set_start(from.start());
@@ -2831,7 +2836,7 @@ void DescriptorProto_ReservedRange::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -2981,7 +2986,9 @@ int DescriptorProto_ReservedRange::ByteSize() const {
void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto_ReservedRange* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto_ReservedRange>(
&from);
@@ -2996,7 +3003,9 @@ void DescriptorProto_ReservedRange::MergeFrom(const ::google::protobuf::Message&
void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRange& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_start()) {
set_start(from.start());
@@ -3608,7 +3617,9 @@ int DescriptorProto::ByteSize() const {
void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const DescriptorProto>(
&from);
@@ -3623,7 +3634,9 @@ void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void DescriptorProto::MergeFrom(const DescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
field_.MergeFrom(from.field_);
extension_.MergeFrom(from.extension_);
nested_type_.MergeFrom(from.nested_type_);
@@ -4844,7 +4857,9 @@ int FieldDescriptorProto::ByteSize() const {
void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldDescriptorProto>(
&from);
@@ -4859,7 +4874,9 @@ void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -5606,7 +5623,9 @@ int OneofDescriptorProto::ByteSize() const {
void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const OneofDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const OneofDescriptorProto>(
&from);
@@ -5621,7 +5640,9 @@ void OneofDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -6056,7 +6077,9 @@ int EnumDescriptorProto::ByteSize() const {
void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumDescriptorProto>(
&from);
@@ -6071,7 +6094,9 @@ void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
value_.MergeFrom(from.value_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@@ -6534,7 +6559,9 @@ int EnumValueDescriptorProto::ByteSize() const {
void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValueDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueDescriptorProto>(
&from);
@@ -6549,7 +6576,9 @@ void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from
void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -7012,7 +7041,9 @@ int ServiceDescriptorProto::ByteSize() const {
void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ServiceDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceDescriptorProto>(
&from);
@@ -7027,7 +7058,9 @@ void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from)
void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
method_.MergeFrom(from.method_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
@@ -7314,7 +7347,7 @@ void MethodDescriptorProto::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -7642,7 +7675,9 @@ int MethodDescriptorProto::ByteSize() const {
void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MethodDescriptorProto* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodDescriptorProto>(
&from);
@@ -7657,7 +7692,9 @@ void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name()) {
set_has_name();
@@ -8126,7 +8163,7 @@ void FileOptions::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -8792,7 +8829,9 @@ int FileOptions::ByteSize() const {
void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FileOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FileOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FileOptions>(
&from);
@@ -8807,7 +8846,9 @@ void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
void FileOptions::MergeFrom(const FileOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_java_package()) {
@@ -9529,7 +9570,7 @@ void MessageOptions::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -9789,7 +9830,9 @@ int MessageOptions::ByteSize() const {
void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MessageOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MessageOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MessageOptions>(
&from);
@@ -9804,7 +9847,9 @@ void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
void MessageOptions::MergeFrom(const MessageOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MessageOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_message_set_wire_format()) {
@@ -10138,7 +10183,7 @@ void FieldOptions::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -10477,7 +10522,9 @@ int FieldOptions::ByteSize() const {
void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldOptions>(
&from);
@@ -10492,7 +10539,9 @@ void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
void FieldOptions::MergeFrom(const FieldOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_ctype()) {
@@ -10943,7 +10992,9 @@ int OneofOptions::ByteSize() const {
void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.OneofOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const OneofOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const OneofOptions>(
&from);
@@ -10958,7 +11009,9 @@ void OneofOptions::MergeFrom(const ::google::protobuf::Message& from) {
void OneofOptions::MergeFrom(const OneofOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
_extensions_.MergeFrom(from._extensions_);
if (from._internal_metadata_.have_unknown_fields()) {
@@ -11124,7 +11177,7 @@ void EnumOptions::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -11324,7 +11377,9 @@ int EnumOptions::ByteSize() const {
void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumOptions>(
&from);
@@ -11339,7 +11394,9 @@ void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumOptions::MergeFrom(const EnumOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_allow_alias()) {
@@ -11709,7 +11766,9 @@ int EnumValueOptions::ByteSize() const {
void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValueOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValueOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValueOptions>(
&from);
@@ -11724,7 +11783,9 @@ void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -12066,7 +12127,9 @@ int ServiceOptions::ByteSize() const {
void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ServiceOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ServiceOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const ServiceOptions>(
&from);
@@ -12081,7 +12144,9 @@ void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
void ServiceOptions::MergeFrom(const ServiceOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -12423,7 +12488,9 @@ int MethodOptions::ByteSize() const {
void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.MethodOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const MethodOptions* source =
::google::protobuf::internal::DynamicCastToGenerated<const MethodOptions>(
&from);
@@ -12438,7 +12505,9 @@ void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
void MethodOptions::MergeFrom(const MethodOptions& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodOptions)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_deprecated()) {
@@ -12796,7 +12865,9 @@ int UninterpretedOption_NamePart::ByteSize() const {
void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UninterpretedOption_NamePart* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption_NamePart>(
&from);
@@ -12811,7 +12882,9 @@ void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message&
void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
if (from.has_name_part()) {
set_has_name_part();
@@ -12960,7 +13033,7 @@ void UninterpretedOption::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -13313,7 +13386,9 @@ int UninterpretedOption::ByteSize() const {
void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UninterpretedOption)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UninterpretedOption* source =
::google::protobuf::internal::DynamicCastToGenerated<const UninterpretedOption>(
&from);
@@ -13328,7 +13403,9 @@ void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
name_.MergeFrom(from.name_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_identifier_value()) {
@@ -14170,7 +14247,9 @@ int SourceCodeInfo_Location::ByteSize() const {
void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo.Location)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceCodeInfo_Location* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo_Location>(
&from);
@@ -14185,7 +14264,9 @@ void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from)
void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
path_.MergeFrom(from.path_);
span_.MergeFrom(from.span_);
leading_detached_comments_.MergeFrom(from.leading_detached_comments_);
@@ -14426,7 +14507,9 @@ int SourceCodeInfo::ByteSize() const {
void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceCodeInfo)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceCodeInfo* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceCodeInfo>(
&from);
@@ -14441,7 +14524,9 @@ void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
location_.MergeFrom(from.location_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
@@ -14833,7 +14918,7 @@ void GeneratedCodeInfo_Annotation::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -15093,7 +15178,9 @@ int GeneratedCodeInfo_Annotation::ByteSize() const {
void GeneratedCodeInfo_Annotation::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const GeneratedCodeInfo_Annotation* source =
::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo_Annotation>(
&from);
@@ -15108,7 +15195,9 @@ void GeneratedCodeInfo_Annotation::MergeFrom(const ::google::protobuf::Message&
void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
path_.MergeFrom(from.path_);
if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
if (from.has_source_file()) {
@@ -15348,7 +15437,9 @@ int GeneratedCodeInfo::ByteSize() const {
void GeneratedCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.GeneratedCodeInfo)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const GeneratedCodeInfo* source =
::google::protobuf::internal::DynamicCastToGenerated<const GeneratedCodeInfo>(
&from);
@@ -15363,7 +15454,9 @@ void GeneratedCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
annotation_.MergeFrom(from.annotation_);
if (from._internal_metadata_.have_unknown_fields()) {
mutable_unknown_fields()->MergeFrom(from.unknown_fields());
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index da853dbc..28410d4a 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -45,6 +45,7 @@ option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
option csharp_namespace = "Google.Protobuf.Reflection";
option objc_class_prefix = "GPB";
+option java_generate_equals_and_hash = true;
// descriptor.proto must be optimized for speed because reflection-based
// algorithms don't work during bootstrapping.
diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc
index b0c641bf..ed5cca4b 100644
--- a/src/google/protobuf/duration.pb.cc
+++ b/src/google/protobuf/duration.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fduration_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -74,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fduration_2eproto() {
delete Duration_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fduration_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fduration_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fduration_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -192,7 +185,7 @@ void Duration::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -322,7 +315,9 @@ int Duration::ByteSize() const {
void Duration::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Duration)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Duration* source =
::google::protobuf::internal::DynamicCastToGenerated<const Duration>(
&from);
@@ -337,7 +332,9 @@ void Duration::MergeFrom(const ::google::protobuf::Message& from) {
void Duration::MergeFrom(const Duration& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.seconds() != 0) {
set_seconds(from.seconds());
}
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 8b461201..83775753 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -59,6 +60,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fempty_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -72,6 +74,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fempty_2eproto() {
delete Empty_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -98,16 +101,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fempty_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fempty_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -240,7 +233,9 @@ int Empty::ByteSize() const {
void Empty::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Empty)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Empty* source =
::google::protobuf::internal::DynamicCastToGenerated<const Empty>(
&from);
@@ -255,7 +250,9 @@ void Empty::MergeFrom(const ::google::protobuf::Message& from) {
void Empty::MergeFrom(const Empty& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
}
void Empty::CopyFrom(const ::google::protobuf::Message& from) {
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 5dd171ed..b26a246c 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -341,7 +341,7 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
int ExtensionSet::SpaceUsedExcludingSelf() const {
int total_size =
- extensions_.size() * sizeof(map<int, Extension>::value_type);
+ extensions_.size() * sizeof(ExtensionMap::value_type);
for (ExtensionMap::const_iterator iter = extensions_.begin(),
end = extensions_.end();
iter != end;
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index d197b406..ed05fe57 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -60,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ffield_5fmask_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -73,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ffield_5fmask_2eproto() {
delete FieldMask_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -99,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ffield_5fmask_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ffield_5fmask_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -281,7 +274,9 @@ int FieldMask::ByteSize() const {
void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FieldMask)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FieldMask* source =
::google::protobuf::internal::DynamicCastToGenerated<const FieldMask>(
&from);
@@ -296,7 +291,9 @@ void FieldMask::MergeFrom(const ::google::protobuf::Message& from) {
void FieldMask::MergeFrom(const FieldMask& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
paths_.MergeFrom(from.paths_);
}
diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc
index 7b813f8a..7ad6d61c 100644
--- a/src/google/protobuf/generated_message_util.cc
+++ b/src/google/protobuf/generated_message_util.cc
@@ -73,6 +73,12 @@ int StringSpaceUsedExcludingSelf(const string& str) {
+void MergeFromFail(const char* file, int line) {
+ GOOGLE_CHECK(false) << file << ":" << line;
+ // Open-source GOOGLE_CHECK(false) is not NORETURN.
+ exit(1);
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h
index 56f5afd2..8967726e 100644
--- a/src/google/protobuf/generated_message_util.h
+++ b/src/google/protobuf/generated_message_util.h
@@ -41,8 +41,8 @@
#include <assert.h>
#include <string>
-#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/once.h>
namespace google {
@@ -112,8 +112,13 @@ class ArenaString;
// pointer to a copy of the string that resides in *arena. Requires both
// args to be non-NULL. If something goes wrong while reading the data
// then NULL is returned (e.g., input does not start with a valid varint).
-ArenaString* ReadArenaString(::google::protobuf::io::CodedInputStream* input,
- ::google::protobuf::Arena* arena);
+LIBPROTOBUF_EXPORT ArenaString* ReadArenaString(
+ ::google::protobuf::io::CodedInputStream* input,
+ ::google::protobuf::Arena* arena);
+
+// Helper function to crash on merge failure.
+// Moved out of generated code to reduce binary size.
+LIBPROTOBUF_EXPORT void MergeFromFail(const char* file, int line) GOOGLE_ATTRIBUTE_NORETURN;
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 148eee0e..a5675e79 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -649,13 +649,16 @@ bool CodedInputStream::Refresh() {
// CodedOutputStream =================================================
+bool CodedOutputStream::default_serialization_deterministic_ = false;
+
CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output)
: output_(output),
buffer_(NULL),
buffer_size_(0),
total_bytes_(0),
had_error_(false),
- aliasing_enabled_(false) {
+ aliasing_enabled_(false),
+ serialization_deterministic_is_overridden_(false) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
// The Refresh() may have failed. If the client doesn't write any data,
@@ -671,7 +674,8 @@ CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output,
buffer_size_(0),
total_bytes_(0),
had_error_(false),
- aliasing_enabled_(false) {
+ aliasing_enabled_(false),
+ serialization_deterministic_is_overridden_(false) {
if (do_eager_refresh) {
// Eagerly Refresh() so buffer space is immediately available.
Refresh();
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index eb320745..316da765 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -813,6 +813,44 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// created.
bool HadError() const { return had_error_; }
+ // Deterministic serialization, if requested, guarantees that for a given
+ // binary, equal messages will always be serialized to the same bytes. This
+ // implies:
+ // . repeated serialization of a message will return the same bytes
+ // . different processes of the same binary (which may be executing on
+ // different machines) will serialize equal messages to the same bytes.
+ //
+ // Note the deterministic serialization is NOT canonical across languages; it
+ // is also unstable across different builds with schema changes due to unknown
+ // fields. Users who need canonical serialization, e.g., persistent storage in
+ // a canonical form, fingerprinting, etc., should define their own
+ // canonicalization specification and implement the serializer using
+ // reflection APIs rather than relying on this API.
+ //
+ // If determinisitc serialization is requested, the serializer will
+ // sort map entries by keys in lexicographical order or numerical order.
+ // (This is an implementation detail and may subject to change.)
+ //
+ // There are two ways to determine whether serialization should be
+ // deterministic for this CodedOutputStream. If SetSerializationDeterministic
+ // has not yet been called, then the default comes from the global default,
+ // which is false, until SetDefaultSerializationDeterministic has been called.
+ // Otherwise, SetSerializationDeterministic has been called, and the last
+ // value passed to it is all that matters.
+ void SetSerializationDeterministic(bool value) {
+ serialization_deterministic_is_overridden_ = true;
+ serialization_deterministic_override_ = value;
+ }
+ // See above. Also, note that users of this CodedOutputStream may need to
+ // call IsSerializationDeterminstic() to serialize in the intended way. This
+ // CodedOutputStream cannot enforce a desire for deterministic serialization
+ // by itself.
+ bool IsSerializationDeterminstic() const {
+ return serialization_deterministic_is_overridden_ ?
+ serialization_deterministic_override_ :
+ default_serialization_deterministic_;
+ }
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CodedOutputStream);
@@ -822,6 +860,10 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
int total_bytes_; // Sum of sizes of all buffers seen so far.
bool had_error_; // Whether an error occurred during output.
bool aliasing_enabled_; // See EnableAliasing().
+ // See SetSerializationDeterministic() regarding these three fields.
+ bool serialization_deterministic_is_overridden_;
+ bool serialization_deterministic_override_;
+ static bool default_serialization_deterministic_;
// Advance the buffer by a given number of bytes.
void Advance(int amount);
@@ -849,6 +891,11 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
uint64 value, uint8* target);
static int VarintSize32Fallback(uint32 value);
+
+ // See above. Other projects may use "friend" to allow them to call this.
+ static void SetDefaultSerializationDeterministic() {
+ default_serialization_deterministic_ = true;
+ }
};
// inline methods ====================================================
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index 42bcfd94..1b9aa703 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -1250,7 +1250,7 @@ class Map {
// Return whether table_[b] is a linked list that seems awfully long.
// Requires table_[b] to point to a non-empty linked list.
bool TableEntryIsTooLong(size_type b) {
- const int kMaxLength = 8;
+ const size_type kMaxLength = 8;
size_type count = 0;
Node* node = static_cast<Node*>(table_[b]);
do {
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 23ac7b8a..4dedfd57 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -535,6 +535,32 @@ class MapEntryLite : public MessageLite {
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite);
};
+// Helpers for deterministic serialization =============================
+
+// This struct can be used with any generic sorting algorithm. If the Key
+// type is relatively small and easy to copy then copying Keys into an
+// array of SortItems can be beneficial. Then all the data the sorting
+// algorithm needs to touch is in that one array.
+template <typename Key, typename PtrToKeyValuePair> struct SortItem {
+ SortItem() {}
+ explicit SortItem(PtrToKeyValuePair p) : first(p->first), second(p) {}
+
+ Key first;
+ PtrToKeyValuePair second;
+};
+
+template <typename T> struct CompareByFirstField {
+ bool operator()(const T& a, const T& b) const {
+ return a.first < b.first;
+ }
+};
+
+template <typename T> struct CompareByDerefFirst {
+ bool operator()(const T& a, const T& b) const {
+ return a->first < b->first;
+ }
+};
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto
index 916cc546..ddc2a582 100644
--- a/src/google/protobuf/map_proto2_unittest.proto
+++ b/src/google/protobuf/map_proto2_unittest.proto
@@ -64,3 +64,23 @@ message TestEnumMapPlusExtra {
message TestImportEnumMap {
map<int32, protobuf_unittest_import.ImportEnumForMap> import_enum_amp = 1;
}
+
+message TestIntIntMap {
+ map<int32, int32> m = 1;
+}
+
+// Test all key types: string, plus the non-floating-point scalars.
+message TestMaps {
+ map<int32, TestIntIntMap> m_int32 = 1;
+ map<int64, TestIntIntMap> m_int64 = 2;
+ map<uint32, TestIntIntMap> m_uint32 = 3;
+ map<uint64, TestIntIntMap> m_uint64 = 4;
+ map<sint32, TestIntIntMap> m_sint32 = 5;
+ map<sint64, TestIntIntMap> m_sint64 = 6;
+ map<fixed32, TestIntIntMap> m_fixed32 = 7;
+ map<fixed64, TestIntIntMap> m_fixed64 = 8;
+ map<sfixed32, TestIntIntMap> m_sfixed32 = 9;
+ map<sfixed64, TestIntIntMap> m_sfixed64 = 10;
+ map<bool, TestIntIntMap> m_bool = 11;
+ map<string, TestIntIntMap> m_string = 12;
+}
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index cdd1ccd5..03954e75 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -74,6 +74,7 @@
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/util/time_util.h>
+#include <google/protobuf/util/message_differencer.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <gmock/gmock.h>
@@ -2869,6 +2870,82 @@ TEST(WireFormatForMapFieldTest, MapParseHelpers) {
}
}
+// Deterministic Serialization Test ==========================================
+
+template <typename T>
+static string DeterministicSerialization(const T& t) {
+ const int size = t.ByteSize();
+ string result(size, '\0');
+ io::ArrayOutputStream array_stream(string_as_array(&result), size);
+ io::CodedOutputStream output_stream(&array_stream);
+ output_stream.SetSerializationDeterministic(true);
+ t.SerializeWithCachedSizes(&output_stream);
+ EXPECT_FALSE(output_stream.HadError());
+ EXPECT_EQ(size, output_stream.ByteCount());
+ return result;
+}
+
+// Helper to test the serialization of the first arg against a golden file.
+static void TestDeterministicSerialization(const protobuf_unittest::TestMaps& t,
+ const string& filename) {
+ string expected;
+ GOOGLE_CHECK_OK(File::GetContents(
+ TestSourceDir() + "/google/protobuf/testdata/" + filename,
+ &expected, true));
+ const string actual = DeterministicSerialization(t);
+ EXPECT_EQ(expected, actual);
+ protobuf_unittest::TestMaps u;
+ EXPECT_TRUE(u.ParseFromString(actual));
+ EXPECT_TRUE(google::protobuf::util::MessageDifferencer::Equals(u, t));
+}
+
+// Helper for MapSerializationTest. Return a 7-bit ASCII string.
+static string ConstructKey(uint64 n) {
+ string s(n % static_cast<uint64>(9), '\0');
+ if (s.empty()) {
+ return StrCat(n);
+ } else {
+ while (n != 0) {
+ s[n % s.size()] = (n >> 10) & 0x7f;
+ n /= 888;
+ }
+ return s;
+ }
+}
+
+TEST(MapSerializationTest, Deterministic) {
+ const int kIters = 25;
+ protobuf_unittest::TestMaps t;
+ protobuf_unittest::TestIntIntMap inner;
+ (*inner.mutable_m())[0] = (*inner.mutable_m())[10] =
+ (*inner.mutable_m())[-200] = 0;
+ uint64 frog = 9;
+ const uint64 multiplier = 0xa29cd16f;
+ for (int i = 0; i < kIters; i++) {
+ const int32 i32 = static_cast<int32>(frog & 0xffffffff);
+ const uint32 u32 = static_cast<uint32>(i32) * 91919;
+ const int64 i64 = static_cast<int64>(frog);
+ const uint64 u64 = frog * static_cast<uint64>(187321);
+ const bool b = i32 > 0;
+ const string s = ConstructKey(frog);
+ (*inner.mutable_m())[i] = i32;
+ (*t.mutable_m_int32())[i32] = (*t.mutable_m_sint32())[i32] =
+ (*t.mutable_m_sfixed32())[i32] = inner;
+ (*t.mutable_m_uint32())[u32] = (*t.mutable_m_fixed32())[u32] = inner;
+ (*t.mutable_m_int64())[i64] = (*t.mutable_m_sint64())[i64] =
+ (*t.mutable_m_sfixed64())[i64] = inner;
+ (*t.mutable_m_uint64())[u64] = (*t.mutable_m_fixed64())[u64] = inner;
+ (*t.mutable_m_bool())[b] = inner;
+ (*t.mutable_m_string())[s] = inner;
+ (*t.mutable_m_string())[s + string(1 << (u32 % static_cast<uint32>(9)),
+ b)] = inner;
+ inner.mutable_m()->erase(i);
+ frog = frog * multiplier + i;
+ frog ^= (frog >> 41);
+ }
+ TestDeterministicSerialization(t, "golden_message_maps");
+}
+
// Text Format Test =================================================
TEST(TextFormatMapTest, SerializeAndParse) {
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index 74e8bb50..685a770f 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -166,10 +166,10 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
io::CodedOutputStream* output);
static inline uint8* InternalWriteToArray(int field,
const MapEntryAccessorType& value,
- bool deterministic, uint8* output);
+ bool deterministic, uint8* target);
static inline uint8* WriteToArray(int field,
const MapEntryAccessorType& value,
- uint8* output);
+ uint8* target);
// Functions to manipulate data on memory. ========================
static inline const Type& GetExternalReference(const Type* value);
@@ -227,11 +227,11 @@ class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
int field, \
const MapEntryAccessorType& value, \
bool deterministic, \
- uint8* output); \
+ uint8* target); \
static inline uint8* WriteToArray(int field, \
const MapEntryAccessorType& value, \
- uint8* output) { \
- return InternalWriteToArray(field, value, false, output); \
+ uint8* target) { \
+ return InternalWriteToArray(field, value, false, target); \
} \
static inline const MapEntryAccessorType& GetExternalReference( \
const TypeOnMemory& value); \
@@ -374,9 +374,9 @@ template <typename Type>
inline uint8*
MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::InternalWriteToArray(
int field, const MapEntryAccessorType& value, bool deterministic,
- uint8* output) {
+ uint8* target) {
return WireFormatLite::InternalWriteMessageToArray(field, value,
- deterministic, output);
+ deterministic, target);
}
#define WRITE_METHOD(FieldType, DeclaredType) \
@@ -390,8 +390,8 @@ MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::InternalWriteToArray(
inline uint8* \
MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
Type>::InternalWriteToArray( \
- int field, const MapEntryAccessorType& value, bool, uint8* output) { \
- return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
+ int field, const MapEntryAccessorType& value, bool, uint8* target) { \
+ return WireFormatLite::Write##DeclaredType##ToArray(field, value, target); \
}
WRITE_METHOD(STRING , String)
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index d62ca79c..f18077dd 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -62,8 +62,6 @@ namespace protobuf {
using internal::WireFormat;
using internal::ReflectionOps;
-Message::~Message() {}
-
void Message::MergeFrom(const Message& from) {
const Descriptor* descriptor = GetDescriptor();
GOOGLE_CHECK_EQ(from.GetDescriptor(), descriptor)
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index dcdffe1c..9705e97e 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -179,7 +179,7 @@ struct Metadata {
class LIBPROTOBUF_EXPORT Message : public MessageLite {
public:
inline Message() {}
- virtual ~Message();
+ virtual ~Message() {}
// Basic Operations ------------------------------------------------
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 3913be1b..ba56db95 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -46,8 +46,6 @@
namespace google {
namespace protobuf {
-MessageLite::~MessageLite() {}
-
string MessageLite::InitializationErrorString() const {
return "(cannot determine missing fields for lite message)";
}
diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h
index f606aeec..2bdfe496 100644
--- a/src/google/protobuf/message_lite.h
+++ b/src/google/protobuf/message_lite.h
@@ -81,7 +81,7 @@ namespace internal {
class LIBPROTOBUF_EXPORT MessageLite {
public:
inline MessageLite() {}
- virtual ~MessageLite();
+ virtual ~MessageLite() {}
// Basic Operations ------------------------------------------------
diff --git a/src/google/protobuf/repeated_field_reflection.h b/src/google/protobuf/repeated_field_reflection.h
deleted file mode 100644
index 512c0f1d..00000000
--- a/src/google/protobuf/repeated_field_reflection.h
+++ /dev/null
@@ -1,337 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// This header file is protobuf internal. Users should not include this
-// file directly.
-#ifndef GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
-#define GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
-
-#include <memory>
-#ifndef _SHARED_PTR_H
-#include <google/protobuf/stubs/shared_ptr.h>
-#endif
-
-#include <google/protobuf/generated_enum_reflection.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-// Interfaces used to implement reflection RepeatedFieldRef API.
-// Reflection::GetRepeatedAccessor() should return a pointer to an singleton
-// object that implements the below interface.
-//
-// This interface passes/returns values using void pointers. The actual type
-// of the value depends on the field's cpp_type. Following is a mapping from
-// cpp_type to the type that should be used in this interface:
-//
-// field->cpp_type() T Actual type of void*
-// CPPTYPE_INT32 int32 int32
-// CPPTYPE_UINT32 uint32 uint32
-// CPPTYPE_INT64 int64 int64
-// CPPTYPE_UINT64 uint64 uint64
-// CPPTYPE_DOUBLE double double
-// CPPTYPE_FLOAT float float
-// CPPTYPE_BOOL bool bool
-// CPPTYPE_ENUM generated enum type int32
-// CPPTYPE_STRING string string
-// CPPTYPE_MESSAGE generated message type google::protobuf::Message
-// or google::protobuf::Message
-//
-// Note that for enums we use int32 in the interface.
-//
-// You can map from T to the actual type using RefTypeTraits:
-// typedef RefTypeTraits<T>::AccessorValueType ActualType;
-class LIBPROTOBUF_EXPORT RepeatedFieldAccessor {
- public:
- // Typedefs for clarity.
- typedef void Field;
- typedef void Value;
- typedef void Iterator;
-
- virtual ~RepeatedFieldAccessor();
- virtual bool IsEmpty(const Field* data) const = 0;
- virtual int Size(const Field* data) const = 0;
- // Depends on the underlying representation of the repeated field, this
- // method can return a pointer to the underlying object if such an object
- // exists, or fill the data into scratch_space and return scratch_space.
- // Callers of this method must ensure scratch_space is a valid pointer
- // to a mutable object of the correct type.
- virtual const Value* Get(
- const Field* data, int index, Value* scratch_space) const = 0;
-
- virtual void Clear(Field* data) const = 0;
- virtual void Set(Field* data, int index, const Value* value) const = 0;
- virtual void Add(Field* data, const Value* value) const = 0;
- virtual void RemoveLast(Field* data) const = 0;
- virtual void SwapElements(Field* data, int index1, int index2) const = 0;
- virtual void Swap(Field* data, const RepeatedFieldAccessor* other_mutator,
- Field* other_data) const = 0;
-
- // Create an iterator that points at the beginning of the repeated field.
- virtual Iterator* BeginIterator(const Field* data) const = 0;
- // Create an iterator that points at the end of the repeated field.
- virtual Iterator* EndIterator(const Field* data) const = 0;
- // Make a copy of an iterator and return the new copy.
- virtual Iterator* CopyIterator(const Field* data,
- const Iterator* iterator) const = 0;
- // Move an iterator to point to the next element.
- virtual Iterator* AdvanceIterator(const Field* data,
- Iterator* iterator) const = 0;
- // Compare whether two iterators point to the same element.
- virtual bool EqualsIterator(const Field* data, const Iterator* a,
- const Iterator* b) const = 0;
- // Delete an iterator created by BeginIterator(), EndIterator() and
- // CopyIterator().
- virtual void DeleteIterator(const Field* data, Iterator* iterator) const = 0;
- // Like Get() but for iterators.
- virtual const Value* GetIteratorValue(const Field* data,
- const Iterator* iterator,
- Value* scratch_space) const = 0;
-
- // Templated methods that make using this interface easier for non-message
- // types.
- template<typename T>
- T Get(const Field* data, int index) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- ActualType scratch_space;
- return static_cast<T>(
- *reinterpret_cast<const ActualType*>(
- Get(data, index, static_cast<Value*>(&scratch_space))));
- }
-
- template<typename T, typename ValueType>
- void Set(Field* data, int index, const ValueType& value) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- // In this RepeatedFieldAccessor interface we pass/return data using
- // raw pointers. Type of the data these raw pointers point to should
- // be ActualType. Here we have a ValueType object and want a ActualType
- // pointer. We can't cast a ValueType pointer to an ActualType pointer
- // directly because their type might be different (for enums ValueType
- // may be a generated enum type while ActualType is int32). To be safe
- // we make a copy to get a temporary ActualType object and use it.
- ActualType tmp = static_cast<ActualType>(value);
- Set(data, index, static_cast<const Value*>(&tmp));
- }
-
- template<typename T, typename ValueType>
- void Add(Field* data, const ValueType& value) const {
- typedef typename RefTypeTraits<T>::AccessorValueType ActualType;
- // In this RepeatedFieldAccessor interface we pass/return data using
- // raw pointers. Type of the data these raw pointers point to should
- // be ActualType. Here we have a ValueType object and want a ActualType
- // pointer. We can't cast a ValueType pointer to an ActualType pointer
- // directly because their type might be different (for enums ValueType
- // may be a generated enum type while ActualType is int32). To be safe
- // we make a copy to get a temporary ActualType object and use it.
- ActualType tmp = static_cast<ActualType>(value);
- Add(data, static_cast<const Value*>(&tmp));
- }
-};
-
-// Implement (Mutable)RepeatedFieldRef::iterator
-template<typename T>
-class RepeatedFieldRefIterator
- : public std::iterator<std::forward_iterator_tag, T> {
- typedef typename RefTypeTraits<T>::AccessorValueType AccessorValueType;
- typedef typename RefTypeTraits<T>::IteratorValueType IteratorValueType;
- typedef typename RefTypeTraits<T>::IteratorPointerType IteratorPointerType;
-
- public:
- // Constructor for non-message fields.
- RepeatedFieldRefIterator(const void* data,
- const RepeatedFieldAccessor* accessor,
- bool begin)
- : data_(data), accessor_(accessor),
- iterator_(begin ? accessor->BeginIterator(data) :
- accessor->EndIterator(data)),
- scratch_space_(new AccessorValueType) {
- }
- // Constructor for message fields.
- RepeatedFieldRefIterator(const void* data,
- const RepeatedFieldAccessor* accessor,
- bool begin,
- AccessorValueType* scratch_space)
- : data_(data), accessor_(accessor),
- iterator_(begin ? accessor->BeginIterator(data) :
- accessor->EndIterator(data)),
- scratch_space_(scratch_space) {
- }
- ~RepeatedFieldRefIterator() {
- accessor_->DeleteIterator(data_, iterator_);
- }
- RepeatedFieldRefIterator operator++(int) {
- RepeatedFieldRefIterator tmp(*this);
- iterator_ = accessor_->AdvanceIterator(data_, iterator_);
- return tmp;
- }
- RepeatedFieldRefIterator& operator++() {
- iterator_ = accessor_->AdvanceIterator(data_, iterator_);
- return *this;
- }
- IteratorValueType operator*() const {
- return static_cast<IteratorValueType>(
- *static_cast<const AccessorValueType*>(
- accessor_->GetIteratorValue(
- data_, iterator_, scratch_space_.get())));
- }
- IteratorPointerType operator->() const {
- return static_cast<IteratorPointerType>(
- accessor_->GetIteratorValue(
- data_, iterator_, scratch_space_.get()));
- }
- bool operator!=(const RepeatedFieldRefIterator& other) const {
- assert(data_ == other.data_);
- assert(accessor_ == other.accessor_);
- return !accessor_->EqualsIterator(data_, iterator_, other.iterator_);
- }
- bool operator==(const RepeatedFieldRefIterator& other) const {
- return !this->operator!=(other);
- }
-
- RepeatedFieldRefIterator(const RepeatedFieldRefIterator& other)
- : data_(other.data_), accessor_(other.accessor_),
- iterator_(accessor_->CopyIterator(data_, other.iterator_)) {
- }
- RepeatedFieldRefIterator& operator=(const RepeatedFieldRefIterator& other) {
- if (this != &other) {
- accessor_->DeleteIterator(data_, iterator_);
- data_ = other.data_;
- accessor_ = other.accessor_;
- iterator_ = accessor_->CopyIterator(data_, other.iterator_);
- }
- return *this;
- }
-
- protected:
- const void* data_;
- const RepeatedFieldAccessor* accessor_;
- void* iterator_;
- google::protobuf::scoped_ptr<AccessorValueType> scratch_space_;
-};
-
-// TypeTraits that maps the type parameter T of RepeatedFieldRef or
-// MutableRepeatedFieldRef to corresponding iterator type,
-// RepeatedFieldAccessor type, etc.
-template<typename T>
-struct PrimitiveTraits {
- static const bool is_primitive = false;
-};
-#define DEFINE_PRIMITIVE(TYPE, type) \
- template<> struct PrimitiveTraits<type> { \
- static const bool is_primitive = true; \
- static const FieldDescriptor::CppType cpp_type = \
- FieldDescriptor::CPPTYPE_ ## TYPE; \
- };
-DEFINE_PRIMITIVE(INT32, int32)
-DEFINE_PRIMITIVE(UINT32, uint32)
-DEFINE_PRIMITIVE(INT64, int64)
-DEFINE_PRIMITIVE(UINT64, uint64)
-DEFINE_PRIMITIVE(FLOAT, float)
-DEFINE_PRIMITIVE(DOUBLE, double)
-DEFINE_PRIMITIVE(BOOL, bool)
-#undef DEFINE_PRIMITIVE
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<PrimitiveTraits<T>::is_primitive>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef T AccessorValueType;
- typedef T IteratorValueType;
- typedef T* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- PrimitiveTraits<T>::cpp_type;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<is_proto_enum<T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- // We use int32 for repeated enums in RepeatedFieldAccessor.
- typedef int32 AccessorValueType;
- typedef T IteratorValueType;
- typedef int32* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_ENUM;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<internal::is_same<string, T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef string AccessorValueType;
- typedef string IteratorValueType;
- typedef string* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_STRING;
- static const Descriptor* GetMessageFieldDescriptor() {
- return NULL;
- }
-};
-
-template<typename T>
-struct MessageDescriptorGetter {
- static const Descriptor* get() {
- return T::default_instance().GetDescriptor();
- }
-};
-template<>
-struct MessageDescriptorGetter<Message> {
- static const Descriptor* get() {
- return NULL;
- }
-};
-
-template<typename T>
-struct RefTypeTraits<
- T, typename internal::enable_if<internal::is_base_of<Message, T>::value>::type> {
- typedef RepeatedFieldRefIterator<T> iterator;
- typedef RepeatedFieldAccessor AccessorType;
- typedef Message AccessorValueType;
- typedef const T& IteratorValueType;
- typedef const T* IteratorPointerType;
- static const FieldDescriptor::CppType cpp_type =
- FieldDescriptor::CPPTYPE_MESSAGE;
- static const Descriptor* GetMessageFieldDescriptor() {
- return MessageDescriptorGetter<T>::get();
- }
-};
-} // namespace internal
-} // namespace protobuf
-} // namespace google
-#endif // GOOGLE_PROTOBUF_REPEATED_FIELD_REFLECTION_H__
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 4d8e77ce..5cc77bf3 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -60,6 +61,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fsource_5fcontext_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -73,6 +75,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fsource_5fcontext_2eproto() {
delete SourceContext_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -99,16 +102,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fsource_5fcontext_2eproto
}
} static_descriptor_initializer_google_2fprotobuf_2fsource_5fcontext_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -281,7 +274,9 @@ int SourceContext::ByteSize() const {
void SourceContext::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.SourceContext)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const SourceContext* source =
::google::protobuf::internal::DynamicCastToGenerated<const SourceContext>(
&from);
@@ -296,7 +291,9 @@ void SourceContext::MergeFrom(const ::google::protobuf::Message& from) {
void SourceContext::MergeFrom(const SourceContext& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.file_name().size() > 0) {
file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_);
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index dd6b78d1..a551384c 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -45,6 +45,7 @@ const ::google::protobuf::EnumDescriptor* NullValue_descriptor_ = NULL;
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -116,6 +117,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -147,6 +149,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto() {
delete ListValue_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -203,16 +206,6 @@ bool NullValue_IsValid(int value) {
}
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -348,18 +341,51 @@ void Struct::SerializeWithCachedSizes(
::google::protobuf::io::CodedOutputStream* output) const {
// @@protoc_insertion_point(serialize_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
- {
- ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
- for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
- it = this->fields().begin();
- it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
- 1, *entry, output);
- ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- it->first.data(), it->first.length(),
- ::google::protobuf::internal::WireFormatLite::SERIALIZE,
- "google.protobuf.Struct.FieldsEntry.key");
+ if (!this->fields().empty()) {
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
+ ConstPtr;
+ typedef ConstPtr SortItem;
+ typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
+ struct Utf8Check {
+ static void Check(ConstPtr p) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ p->first.data(), p->first.length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ }
+ };
+
+ if (output->IsSerializationDeterminstic() &&
+ this->fields().size() > 1) {
+ ::google::protobuf::scoped_array<SortItem> items(
+ new SortItem[this->fields().size()]);
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
+ size_type n = 0;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it, ++n) {
+ items[n] = SortItem(&*it);
+ }
+ ::std::sort(&items[0], &items[n], Less());
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (size_type i = 0; i < n; i++) {
+ entry.reset(fields_.NewEntryWrapper(
+ items[i]->first, items[i]->second));
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, *entry, output);
+ Utf8Check::Check(items[i]);
+ }
+ } else {
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it) {
+ entry.reset(fields_.NewEntryWrapper(
+ it->first, it->second));
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 1, *entry, output);
+ Utf8Check::Check(&*it);
+ }
}
}
@@ -370,19 +396,55 @@ void Struct::SerializeWithCachedSizes(
bool deterministic, ::google::protobuf::uint8* target) const {
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct)
// map<string, .google.protobuf.Value> fields = 1;
- {
- ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
- for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
- it = this->fields().begin();
- it != this->fields().end(); ++it) {
- entry.reset(fields_.NewEntryWrapper(it->first, it->second));
- target = ::google::protobuf::internal::WireFormatLite::
- InternalWriteMessageNoVirtualToArray(
- 1, *entry, false, target);
- ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
- it->first.data(), it->first.length(),
- ::google::protobuf::internal::WireFormatLite::SERIALIZE,
- "google.protobuf.Struct.FieldsEntry.key");
+ if (!this->fields().empty()) {
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer
+ ConstPtr;
+ typedef ConstPtr SortItem;
+ typedef ::google::protobuf::internal::CompareByDerefFirst<SortItem> Less;
+ struct Utf8Check {
+ static void Check(ConstPtr p) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ p->first.data(), p->first.length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
+ }
+ };
+
+ if (deterministic &&
+ this->fields().size() > 1) {
+ ::google::protobuf::scoped_array<SortItem> items(
+ new SortItem[this->fields().size()]);
+ typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::size_type size_type;
+ size_type n = 0;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it, ++n) {
+ items[n] = SortItem(&*it);
+ }
+ ::std::sort(&items[0], &items[n], Less());
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (size_type i = 0; i < n; i++) {
+ entry.reset(fields_.NewEntryWrapper(
+ items[i]->first, items[i]->second));
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 1, *entry, deterministic, target);
+;
+ Utf8Check::Check(items[i]);
+ }
+ } else {
+ ::google::protobuf::scoped_ptr<Struct_FieldsEntry> entry;
+ for (::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_iterator
+ it = this->fields().begin();
+ it != this->fields().end(); ++it) {
+ entry.reset(fields_.NewEntryWrapper(
+ it->first, it->second));
+ target = ::google::protobuf::internal::WireFormatLite::
+ InternalWriteMessageNoVirtualToArray(
+ 1, *entry, deterministic, target);
+;
+ Utf8Check::Check(&*it);
+ }
}
}
@@ -415,7 +477,9 @@ int Struct::ByteSize() const {
void Struct::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Struct)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Struct* source =
::google::protobuf::internal::DynamicCastToGenerated<const Struct>(
&from);
@@ -430,7 +494,9 @@ void Struct::MergeFrom(const ::google::protobuf::Message& from) {
void Struct::MergeFrom(const Struct& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
fields_.MergeFrom(from.fields_);
}
@@ -881,7 +947,9 @@ int Value::ByteSize() const {
void Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Value>(
&from);
@@ -896,7 +964,9 @@ void Value::MergeFrom(const ::google::protobuf::Message& from) {
void Value::MergeFrom(const Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
switch (from.kind_case()) {
case kNullValue: {
set_null_value(from.null_value());
@@ -1406,7 +1476,9 @@ int ListValue::ByteSize() const {
void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.ListValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const ListValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const ListValue>(
&from);
@@ -1421,7 +1493,9 @@ void ListValue::MergeFrom(const ::google::protobuf::Message& from) {
void ListValue::MergeFrom(const ListValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
values_.MergeFrom(from.values_);
}
diff --git a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
index a0116a60..7314ee4f 100644
--- a/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
+++ b/src/google/protobuf/stubs/atomicops_internals_generic_gcc.h
@@ -128,6 +128,24 @@ inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
return old_value;
}
+inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr,
+ Atomic64 increment) {
+ return __atomic_add_fetch(ptr, increment, __ATOMIC_RELAXED);
+}
+
+inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
+ __atomic_store_n(ptr, value, __ATOMIC_RELAXED);
+}
+
+inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr,
+ Atomic64 new_value) {
+ return __atomic_exchange_n(ptr, new_value, __ATOMIC_RELAXED);
+}
+
+inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
+ return __atomic_load_n(ptr, __ATOMIC_RELAXED);
+}
+
#endif // defined(__LP64__)
} // namespace internal
diff --git a/src/google/protobuf/stubs/callback.h b/src/google/protobuf/stubs/callback.h
index 87271c5e..bbd507a8 100644
--- a/src/google/protobuf/stubs/callback.h
+++ b/src/google/protobuf/stubs/callback.h
@@ -381,6 +381,8 @@ class MethodResultCallback_5_2 : public ResultCallback2<R, A1, A2> {
typename remove_reference<P5>::type p5_;
};
+} // namespace internal
+
// See Closure.
inline Closure* NewCallback(void (*function)()) {
return new internal::FunctionClosure0(function, true);
@@ -533,8 +535,6 @@ inline ResultCallback2<R, A1, A2>* NewPermanentCallback(
p2, p3, p4, p5);
}
-} // namespace internal
-
// A function which does nothing. Useful for creating no-op callbacks, e.g.:
// Closure* nothing = NewCallback(&DoNothing);
void LIBPROTOBUF_EXPORT DoNothing();
diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc
index 25bae9b0..f9e2cfd4 100644
--- a/src/google/protobuf/stubs/common_unittest.cc
+++ b/src/google/protobuf/stubs/common_unittest.cc
@@ -41,8 +41,6 @@
namespace google {
namespace protobuf {
-using internal::NewCallback;
-using internal::NewPermanentCallback;
namespace {
// TODO(kenton): More tests.
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
index 3a36b4b1..a5090801 100644
--- a/src/google/protobuf/stubs/int128.cc
+++ b/src/google/protobuf/stubs/int128.cc
@@ -145,15 +145,15 @@ std::ostream& operator<<(std::ostream& o, const uint128& b) {
std::streamsize div_base_log;
switch (flags & std::ios::basefield) {
case std::ios::hex:
- div = GOOGLE_ULONGLONG(0x1000000000000000); // 16^15
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(0x1000000000000000)); // 16^15
div_base_log = 15;
break;
case std::ios::oct:
- div = GOOGLE_ULONGLONG(01000000000000000000000); // 8^21
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(01000000000000000000000)); // 8^21
div_base_log = 21;
break;
default: // std::ios::dec
- div = GOOGLE_ULONGLONG(10000000000000000000); // 10^19
+ div = static_cast<uint64>(GOOGLE_ULONGLONG(10000000000000000000)); // 10^19
div_base_log = 19;
break;
}
diff --git a/src/google/protobuf/stubs/map_util.h b/src/google/protobuf/stubs/map_util.h
index 4cccbbed..887f12a6 100644
--- a/src/google/protobuf/stubs/map_util.h
+++ b/src/google/protobuf/stubs/map_util.h
@@ -208,7 +208,7 @@ typename Collection::value_type::second_type::element_type&
FindLinkedPtrOrDie(const Collection& collection,
const typename Collection::value_type::first_type& key) {
typename Collection::const_iterator it = collection.find(key);
- CHECK(it != collection.end()) << "key not found: " << key;
+ GOOGLE_CHECK(it != collection.end()) << "key not found: " << key;
// Since linked_ptr::operator*() is a const member returning a non const,
// we do not need a version of this function taking a non const collection.
return *it->second;
@@ -337,14 +337,15 @@ bool InsertIfNotPresent(
template <class Collection>
void InsertOrDie(Collection* const collection,
const typename Collection::value_type& value) {
- CHECK(InsertIfNotPresent(collection, value)) << "duplicate value: " << value;
+ GOOGLE_CHECK(InsertIfNotPresent(collection, value))
+ << "duplicate value: " << value;
}
// Same as above except doesn't log the value on error.
template <class Collection>
void InsertOrDieNoPrint(Collection* const collection,
const typename Collection::value_type& value) {
- CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
+ GOOGLE_CHECK(InsertIfNotPresent(collection, value)) << "duplicate value.";
}
// Inserts the key-value pair into the collection. Dies if key was already
diff --git a/src/google/protobuf/stubs/once_unittest.cc b/src/google/protobuf/stubs/once_unittest.cc
index 37def58d..d5f7779e 100644
--- a/src/google/protobuf/stubs/once_unittest.cc
+++ b/src/google/protobuf/stubs/once_unittest.cc
@@ -43,7 +43,6 @@
namespace google {
namespace protobuf {
-using internal::NewCallback;
namespace {
class OnceInitTest : public testing::Test {
@@ -128,11 +127,11 @@ class OnceInitTest : public testing::Test {
};
TestThread* RunInitOnceInNewThread() {
- return new TestThread(internal::NewCallback(this, &OnceInitTest::InitOnce));
+ return new TestThread(NewCallback(this, &OnceInitTest::InitOnce));
}
TestThread* RunInitRecursiveOnceInNewThread() {
return new TestThread(
- internal::NewCallback(this, &OnceInitTest::InitRecursiveOnce));
+ NewCallback(this, &OnceInitTest::InitRecursiveOnce));
}
enum State {
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index 328258b7..d7f93b4c 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -109,15 +109,15 @@ typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef unsigned __int64 uint64;
#else
-typedef signed char int8;
-typedef short int16;
-typedef int int32;
-typedef long long int64;
-
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-typedef unsigned long long uint64;
+typedef int8_t int8;
+typedef int16_t int16;
+typedef int32_t int32;
+typedef int64_t int64;
+
+typedef uint8_t uint8;
+typedef uint16_t uint16;
+typedef uint32_t uint32;
+typedef uint64_t uint64;
#endif
// long long macros to be used because gcc and vc++ use different suffixes,
@@ -131,8 +131,10 @@ typedef unsigned long long uint64;
#define GOOGLE_ULONGLONG(x) x##UI64
#define GOOGLE_LL_FORMAT "I64" // As in printf("%I64d", ...)
#else
+// By long long, we actually mean int64.
#define GOOGLE_LONGLONG(x) x##LL
#define GOOGLE_ULONGLONG(x) x##ULL
+// Used to format real long long integers.
#define GOOGLE_LL_FORMAT "ll" // As in "%lld". Note that "q" is poor form also.
#endif
diff --git a/src/google/protobuf/testdata/golden_message_maps b/src/google/protobuf/testdata/golden_message_maps
new file mode 100644
index 00000000..c70a4d7c
--- /dev/null
+++ b/src/google/protobuf/testdata/golden_message_maps
Binary files differ
diff --git a/src/google/protobuf/testing/file.cc b/src/google/protobuf/testing/file.cc
index 3d07b127..470512ed 100644
--- a/src/google/protobuf/testing/file.cc
+++ b/src/google/protobuf/testing/file.cc
@@ -91,6 +91,7 @@ bool File::WriteStringToFile(const string& contents, const string& name) {
if (fwrite(contents.data(), 1, contents.size(), file) != contents.size()) {
GOOGLE_LOG(ERROR) << "fwrite(" << name << "): " << strerror(errno);
+ fclose(file);
return false;
}
@@ -140,12 +141,12 @@ void File::DeleteRecursively(const string& name,
#ifdef _MSC_VER
// This interface is so weird.
- WIN32_FIND_DATA find_data;
- HANDLE find_handle = FindFirstFile((name + "/*").c_str(), &find_data);
+ WIN32_FIND_DATAA find_data;
+ HANDLE find_handle = FindFirstFileA((name + "/*").c_str(), &find_data);
if (find_handle == INVALID_HANDLE_VALUE) {
// Just delete it, whatever it is.
- DeleteFile(name.c_str());
- RemoveDirectory(name.c_str());
+ DeleteFileA(name.c_str());
+ RemoveDirectoryA(name.c_str());
return;
}
@@ -155,15 +156,15 @@ void File::DeleteRecursively(const string& name,
string path = name + "/" + entry_name;
if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
DeleteRecursively(path, NULL, NULL);
- RemoveDirectory(path.c_str());
+ RemoveDirectoryA(path.c_str());
} else {
- DeleteFile(path.c_str());
+ DeleteFileA(path.c_str());
}
}
- } while(FindNextFile(find_handle, &find_data));
+ } while(FindNextFileA(find_handle, &find_data));
FindClose(find_handle);
- RemoveDirectory(name.c_str());
+ RemoveDirectoryA(name.c_str());
#else
// Use opendir()! Yay!
// lstat = Don't follow symbolic links.
diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc
index d49d8588..66b2648b 100644
--- a/src/google/protobuf/text_format.cc
+++ b/src/google/protobuf/text_format.cc
@@ -759,6 +759,20 @@ class TextFormat::Parser::ParserImpl {
}
return true;
}
+ if (TryConsume("[")) {
+ while (true) {
+ if (!LookingAt("{") && !LookingAt("<")) {
+ DO(SkipFieldValue());
+ } else {
+ DO(SkipFieldMessage());
+ }
+ if (TryConsume("]")) {
+ break;
+ }
+ DO(Consume(","));
+ }
+ return true;
+ }
// Possible field values other than string:
// 12345 => TYPE_INTEGER
// -12345 => TYPE_SYMBOL + TYPE_INTEGER
diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc
index 2ec4bc56..487e62b0 100644
--- a/src/google/protobuf/timestamp.pb.cc
+++ b/src/google/protobuf/timestamp.pb.cc
@@ -29,6 +29,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -61,6 +62,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftimestamp_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -74,6 +76,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ftimestamp_2eproto() {
delete Timestamp_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftimestamp_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -101,16 +104,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ftimestamp_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2ftimestamp_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -206,7 +199,7 @@ void Timestamp::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -336,7 +329,9 @@ int Timestamp::ByteSize() const {
void Timestamp::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Timestamp)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Timestamp* source =
::google::protobuf::internal::DynamicCastToGenerated<const Timestamp>(
&from);
@@ -351,7 +346,9 @@ void Timestamp::MergeFrom(const ::google::protobuf::Message& from) {
void Timestamp::MergeFrom(const Timestamp& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.seconds() != 0) {
set_seconds(from.seconds());
}
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index f9182a75..a2a7f282 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -44,6 +44,7 @@ const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -159,6 +160,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -188,6 +190,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto() {
delete Option_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -272,16 +275,6 @@ bool Syntax_IsValid(int value) {
}
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -658,7 +651,9 @@ int Type::ByteSize() const {
void Type::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Type)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Type* source =
::google::protobuf::internal::DynamicCastToGenerated<const Type>(
&from);
@@ -673,7 +668,9 @@ void Type::MergeFrom(const ::google::protobuf::Message& from) {
void Type::MergeFrom(const Type& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
fields_.MergeFrom(from.fields_);
oneofs_.MergeFrom(from.oneofs_);
options_.MergeFrom(from.options_);
@@ -1128,7 +1125,7 @@ void Field::Clear() {
#endif
#define ZR_(first, last) do {\
- ::memset(&first, 0,\
+ ::memset(&(first), 0,\
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
@@ -1581,7 +1578,9 @@ int Field::ByteSize() const {
void Field::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Field)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Field* source =
::google::protobuf::internal::DynamicCastToGenerated<const Field>(
&from);
@@ -1596,7 +1595,9 @@ void Field::MergeFrom(const ::google::protobuf::Message& from) {
void Field::MergeFrom(const Field& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.kind() != 0) {
set_kind(from.kind());
@@ -2285,7 +2286,9 @@ int Enum::ByteSize() const {
void Enum::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Enum)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Enum* source =
::google::protobuf::internal::DynamicCastToGenerated<const Enum>(
&from);
@@ -2300,7 +2303,9 @@ void Enum::MergeFrom(const ::google::protobuf::Message& from) {
void Enum::MergeFrom(const Enum& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
enumvalue_.MergeFrom(from.enumvalue_);
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -2764,7 +2769,9 @@ int EnumValue::ByteSize() const {
void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.EnumValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const EnumValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const EnumValue>(
&from);
@@ -2779,7 +2786,9 @@ void EnumValue::MergeFrom(const ::google::protobuf::Message& from) {
void EnumValue::MergeFrom(const EnumValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
options_.MergeFrom(from.options_);
if (from.name().size() > 0) {
@@ -3133,7 +3142,9 @@ int Option::ByteSize() const {
void Option::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Option)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Option* source =
::google::protobuf::internal::DynamicCastToGenerated<const Option>(
&from);
@@ -3148,7 +3159,9 @@ void Option::MergeFrom(const ::google::protobuf::Message& from) {
void Option::MergeFrom(const Option& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index d4e383da..8ee99d48 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -69,28 +69,14 @@ const UnknownFieldSet* UnknownFieldSet::default_instance() {
return default_unknown_field_set_instance_;
}
-UnknownFieldSet::UnknownFieldSet()
- : fields_(NULL) {}
-
-UnknownFieldSet::~UnknownFieldSet() {
- Clear();
- delete fields_;
-}
-
void UnknownFieldSet::ClearFallback() {
- if (fields_ != NULL) {
- for (int i = 0; i < fields_->size(); i++) {
- (*fields_)[i].Delete();
- }
- delete fields_;
- fields_ = NULL;
- }
-}
-
-void UnknownFieldSet::ClearAndFreeMemory() {
- if (fields_ != NULL) {
- Clear();
- }
+ GOOGLE_DCHECK(fields_ != NULL && fields_->size() > 0);
+ int n = fields_->size();
+ do {
+ (*fields_)[--n].Delete();
+ } while (n > 0);
+ delete fields_;
+ fields_ = NULL;
}
void UnknownFieldSet::InternalMergeFrom(const UnknownFieldSet& other) {
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 612a942a..aa752916 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -241,8 +241,14 @@ class LIBPROTOBUF_EXPORT UnknownField {
// ===================================================================
// inline implementations
+inline UnknownFieldSet::UnknownFieldSet() : fields_(NULL) {}
+
+inline UnknownFieldSet::~UnknownFieldSet() { Clear(); }
+
+inline void UnknownFieldSet::ClearAndFreeMemory() { Clear(); }
+
inline void UnknownFieldSet::Clear() {
- if (fields_) {
+ if (fields_ != NULL) {
ClearFallback();
}
}
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 21d7a2e4..fa31f763 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -64,6 +64,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter(
type_(type),
current_(NULL),
root_(NULL),
+ suppress_empty_list_(false),
field_scrub_callback_(NULL),
ow_(ow) {}
@@ -164,7 +165,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBytes(
if (current_ == NULL) {
ow_->RenderBytes(name, value);
} else {
- RenderDataPiece(name, DataPiece(value, false, true));
+ // Since StringPiece is essentially a pointer, takes a copy of "value" to
+ // avoid ownership issues.
+ string_values_.push_back(new string(value.ToString()));
+ RenderDataPiece(name, DataPiece(*string_values_.back(), false, true));
}
return this;
}
@@ -184,12 +188,10 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack(
field_scrub_callback_.reset(field_scrub_callback.release());
}
-DefaultValueObjectWriter::Node::Node(const string& name,
- const google::protobuf::Type* type,
- NodeKind kind, const DataPiece& data,
- bool is_placeholder,
- const vector<string>& path,
- FieldScrubCallBack* field_scrub_callback)
+DefaultValueObjectWriter::Node::Node(
+ const string& name, const google::protobuf::Type* type, NodeKind kind,
+ const DataPiece& data, bool is_placeholder, const vector<string>& path,
+ bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback)
: name_(name),
type_(type),
kind_(kind),
@@ -197,6 +199,7 @@ DefaultValueObjectWriter::Node::Node(const string& name,
data_(data),
is_placeholder_(is_placeholder),
path_(path),
+ suppress_empty_list_(suppress_empty_list),
field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
@@ -230,6 +233,9 @@ void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) {
// Write out lists. If we didn't have any list in response, write out empty
// list.
if (kind_ == LIST) {
+ // Suppress empty lists if requested.
+ if (suppress_empty_list_ && is_placeholder_) return;
+
ow->StartList(name_);
WriteChildren(ow);
ow->EndList();
@@ -366,7 +372,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
field.json_name(), field_type, kind,
kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo)
: DataPiece::NullData(),
- true, path, field_scrub_callback_));
+ true, path, suppress_empty_list_, field_scrub_callback_));
new_children.push_back(child.release());
}
// Adds all leftover nodes in children_ to the beginning of new_child.
@@ -462,7 +468,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
if (current_ == NULL) {
vector<string> path;
root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
- false, path, field_scrub_callback_.get()));
+ false, path, suppress_empty_list_,
+ field_scrub_callback_.get()));
root_->PopulateChildren(typeinfo_);
current_ = root_.get();
return this;
@@ -478,7 +485,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
: NULL),
OBJECT, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- field_scrub_callback_.get()));
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@@ -509,7 +516,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
if (current_ == NULL) {
vector<string> path;
root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(),
- false, path, field_scrub_callback_.get()));
+ false, path, suppress_empty_list_,
+ field_scrub_callback_.get()));
current_ = root_.get();
return this;
}
@@ -519,7 +527,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- field_scrub_callback_.get()));
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@@ -577,7 +585,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, PRIMITIVE, data, false,
child == NULL ? current_->path() : child->path(),
- field_scrub_callback_.get()));
+ suppress_empty_list_, field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
} else {
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index 1d85bed8..5f3b25f3 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -122,6 +122,10 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// field_scrub_callback pointer is also transferred to this class
void RegisterFieldScrubCallBack(FieldScrubCallBackPtr field_scrub_callback);
+ // If set to true, empty lists are suppressed from output when default values
+ // are written.
+ void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; }
+
private:
enum NodeKind {
PRIMITIVE = 0,
@@ -136,7 +140,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
public:
Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder, const vector<string>& path,
- FieldScrubCallBack* field_scrub_callback);
+ bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback);
virtual ~Node() {
for (int i = 0; i < children_.size(); ++i) {
delete children_[i];
@@ -212,6 +216,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Path of the field of this node
std::vector<string> path_;
+ // Whether to suppress empty list output.
+ bool suppress_empty_list_;
+
// Pointer to function for determining whether a field needs to be scrubbed
// or not. This callback is owned by the creator of this node.
FieldScrubCallBack* field_scrub_callback_;
@@ -257,6 +264,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// The stack to hold the path of Nodes from current_ to root_;
std::stack<Node*> stack_;
+ // Whether to suppress output of empty lists.
+ bool suppress_empty_list_;
+
// Unique Pointer to function for determining whether a field needs to be
// scrubbed or not.
FieldScrubCallBackPtr field_scrub_callback_;
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
index 8254c0fa..e1dd697a 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
@@ -149,6 +149,39 @@ TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
}
+class DefaultValueObjectWriterSuppressListTest
+ : public BaseDefaultValueObjectWriterTest {
+ protected:
+ DefaultValueObjectWriterSuppressListTest()
+ : BaseDefaultValueObjectWriterTest(DefaultValueTest::descriptor()) {
+ testing_->set_suppress_empty_list(true);
+ }
+ ~DefaultValueObjectWriterSuppressListTest() {}
+};
+
+INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
+ DefaultValueObjectWriterSuppressListTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(DefaultValueObjectWriterSuppressListTest, Empty) {
+ // Set expectation. Emtpy lists should be suppressed.
+ expects_.StartObject("")
+ ->RenderDouble("doubleValue", 0.0)
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
+ ->RenderBytes("bytesValue", "")
+ ->RenderString("enumValue", "ENUM_FIRST")
+ ->EndObject();
+
+ // Actual testing
+ testing_->StartObject("")->EndObject();
+}
} // namespace testing
} // namespace converter
} // namespace util
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index 7a1a6cbd..0c38aeb9 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -298,7 +298,9 @@ ProtoWriter::ProtoElement::ProtoElement(const TypeInfo* typeinfo,
proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
type_(type),
size_index_(-1),
- array_index_(-1) {
+ array_index_(-1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type.oneofs_size() + 1) {
if (!proto3_) {
required_fields_ = GetRequiredFields(type_);
}
@@ -312,13 +314,15 @@ ProtoWriter::ProtoElement::ProtoElement(ProtoWriter::ProtoElement* parent,
ow_(this->parent()->ow_),
parent_field_(field),
typeinfo_(this->parent()->typeinfo_),
- proto3_(this->parent()->proto3_),
+ proto3_(type.syntax() == google::protobuf::SYNTAX_PROTO3),
type_(type),
size_index_(
!is_list && field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
? ow_->size_insert_.size()
: -1),
- array_index_(is_list ? 0 : -1) {
+ array_index_(is_list ? 0 : -1),
+ // oneof_indices_ values are 1-indexed (0 means not present).
+ oneof_indices_(type_.oneofs_size() + 1) {
if (!is_list) {
if (ow_->IsRepeated(*field)) {
// Update array_index_ if it is an explicit list.
@@ -411,11 +415,11 @@ string ProtoWriter::ProtoElement::ToString() const {
}
bool ProtoWriter::ProtoElement::IsOneofIndexTaken(int32 index) {
- return ContainsKey(oneof_indices_, index);
+ return oneof_indices_[index];
}
void ProtoWriter::ProtoElement::TakeOneofIndex(int32 index) {
- InsertIfNotPresent(&oneof_indices_, index);
+ oneof_indices_[index] = true;
}
void ProtoWriter::InvalidName(StringPiece unknown_name, StringPiece message) {
@@ -573,10 +577,19 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
// Pushing a ProtoElement and then pop it off at the end for 2 purposes:
// error location reporting and required field accounting.
- element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ //
+ // For proto3, since there is no required field tracking, we only need to push
+ // ProtoElement for error cases.
+ if (!element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
if (field.kind() == google::protobuf::Field_Kind_TYPE_UNKNOWN ||
field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE) {
+ // Push a ProtoElement for location reporting purposes.
+ if (element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
InvalidValue(field.type_url().empty()
? google::protobuf::Field_Kind_Name(field.kind())
: field.type_url(),
@@ -657,11 +670,18 @@ ProtoWriter* ProtoWriter::RenderPrimitiveField(
}
if (!status.ok()) {
+ // Push a ProtoElement for location reporting purposes.
+ if (element_->proto3()) {
+ element_.reset(new ProtoElement(element_.release(), &field, type, false));
+ }
InvalidValue(google::protobuf::Field_Kind_Name(field.kind()),
status.error_message());
+ element_.reset(element()->pop());
+ return this;
}
- element_.reset(element()->pop());
+ if (!element_->proto3()) element_.reset(element()->pop());
+
return this;
}
diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h
index 8b7c6c34..7f1108ab 100644
--- a/src/google/protobuf/util/internal/proto_writer.h
+++ b/src/google/protobuf/util/internal/proto_writer.h
@@ -32,8 +32,8 @@
#define GOOGLE_PROTOBUF_UTIL_CONVERTER_PROTO_WRITER_H__
#include <deque>
-#include <google/protobuf/stubs/hash.h>
#include <string>
+#include <vector>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
@@ -45,6 +45,7 @@
#include <google/protobuf/util/internal/structured_objectwriter.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
+#include <google/protobuf/stubs/hash.h>
namespace google {
namespace protobuf {
@@ -191,6 +192,8 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// generate an error.
void TakeOneofIndex(int32 index);
+ bool proto3() { return proto3_; }
+
private:
// Used for access to variables of the enclosing instance of
// ProtoWriter.
@@ -203,7 +206,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// TypeInfo to lookup types.
const TypeInfo* typeinfo_;
- // Whether the root type is a proto3 or not.
+ // Whether the type_ is proto3 or not.
bool proto3_;
// Additional variables if this element is a message:
@@ -221,7 +224,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter {
// Set of oneof indices already seen for the type_. Used to validate
// incoming messages so no more than one oneof is set.
- hash_set<int32> oneof_indices_;
+ std::vector<bool> oneof_indices_;
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement);
};
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 1825f556..73e05cfe 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -907,7 +907,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
// conversions as much as possible. Because ToSnakeCase sometimes returns the
// wrong value.
google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > callback(
- ::google::protobuf::internal::NewPermanentCallback(&RenderOneFieldPath, ow));
+ NewPermanentCallback(&RenderOneFieldPath, ow));
return DecodeCompactFieldMaskPaths(data.str(), callback.get());
}
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index 6d45a4f9..d7ac2dba 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -177,6 +177,66 @@ util::Status JsonToBinaryString(TypeResolver* resolver,
resolver, type_url, &input_stream, &output_stream, options);
}
+namespace {
+const char* kTypeUrlPrefix = "type.googleapis.com";
+TypeResolver* generated_type_resolver_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(generated_type_resolver_init_);
+
+string GetTypeUrl(const Message& message) {
+ return string(kTypeUrlPrefix) + "/" + message.GetDescriptor()->full_name();
+}
+
+void DeleteGeneratedTypeResolver() { delete generated_type_resolver_; }
+
+void InitGeneratedTypeResolver() {
+ generated_type_resolver_ = NewTypeResolverForDescriptorPool(
+ kTypeUrlPrefix, DescriptorPool::generated_pool());
+ ::google::protobuf::internal::OnShutdown(&DeleteGeneratedTypeResolver);
+}
+
+TypeResolver* GetGeneratedTypeResolver() {
+ ::google::protobuf::GoogleOnceInit(&generated_type_resolver_init_, &InitGeneratedTypeResolver);
+ return generated_type_resolver_;
+}
+} // namespace
+
+util::Status MessageToJsonString(const Message& message, string* output,
+ const JsonOptions& options) {
+ const DescriptorPool* pool = message.GetDescriptor()->file()->pool();
+ TypeResolver* resolver =
+ pool == DescriptorPool::generated_pool()
+ ? GetGeneratedTypeResolver()
+ : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
+ util::Status result =
+ BinaryToJsonString(resolver, GetTypeUrl(message),
+ message.SerializeAsString(), output, options);
+ if (pool != DescriptorPool::generated_pool()) {
+ delete resolver;
+ }
+ return result;
+}
+
+util::Status JsonStringToMessage(const string& input, Message* message,
+ const JsonParseOptions& options) {
+ const DescriptorPool* pool = message->GetDescriptor()->file()->pool();
+ TypeResolver* resolver =
+ pool == DescriptorPool::generated_pool()
+ ? GetGeneratedTypeResolver()
+ : NewTypeResolverForDescriptorPool(kTypeUrlPrefix, pool);
+ string binary;
+ util::Status result = JsonToBinaryString(
+ resolver, GetTypeUrl(*message), input, &binary, options);
+ if (result.ok() && !message->ParseFromString(binary)) {
+ result =
+ util::Status(util::error::INVALID_ARGUMENT,
+ "JSON transcoder produced invalid protobuf output.");
+ }
+ if (pool != DescriptorPool::generated_pool()) {
+ delete resolver;
+ }
+ return result;
+}
+
} // namespace util
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index b4c2579b..6d3cee52 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -33,6 +33,7 @@
#ifndef GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
#define GOOGLE_PROTOBUF_UTIL_JSON_UTIL_H__
+#include <google/protobuf/message.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/stubs/bytestream.h>
@@ -69,13 +70,37 @@ struct JsonPrintOptions {
// DEPRECATED. Use JsonPrintOptions instead.
typedef JsonPrintOptions JsonOptions;
+// Converts from protobuf message to JSON. This is a simple wrapper of
+// BinaryToJsonString(). It will use the DescriptorPool of the passed-in
+// message to resolve Any types.
+LIBPROTOBUF_EXPORT util::Status MessageToJsonString(const Message& message,
+ string* output,
+ const JsonOptions& options);
+
+inline util::Status MessageToJsonString(const Message& message,
+ string* output) {
+ return MessageToJsonString(message, output, JsonOptions());
+}
+
+// Converts from JSON to protobuf message. This is a simple wrapper of
+// JsonStringToBinary(). It will use the DescriptorPool of the passed-in
+// message to resolve Any types.
+LIBPROTOBUF_EXPORT util::Status JsonStringToMessage(const string& input,
+ Message* message,
+ const JsonParseOptions& options);
+
+inline util::Status JsonStringToMessage(const string& input,
+ Message* message) {
+ return JsonStringToMessage(input, message, JsonParseOptions());
+}
+
// Converts protobuf binary data to JSON.
// The conversion will fail if:
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid protobuf wire format, or conflicts with the type
// information returned by TypeResolver.
// Note that unknown fields will be discarded silently.
-util::Status BinaryToJsonStream(
+LIBPROTOBUF_EXPORT util::Status BinaryToJsonStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* binary_input,
@@ -110,7 +135,7 @@ inline util::Status BinaryToJsonString(TypeResolver* resolver,
// 1. TypeResolver fails to resolve a type.
// 2. input is not valid JSON format, or conflicts with the type
// information returned by TypeResolver.
-util::Status JsonToBinaryStream(
+LIBPROTOBUF_EXPORT util::Status JsonToBinaryStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* json_input,
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index c7d5c59e..24ff5fd6 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -34,6 +34,8 @@
#include <string>
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor_database.h>
+#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/util/json_format_proto3.pb.h>
#include <google/protobuf/util/type_resolver.h>
#include <google/protobuf/util/type_resolver_util.h>
@@ -63,28 +65,21 @@ static string GetTypeUrl(const Descriptor* message) {
class JsonUtilTest : public testing::Test {
protected:
JsonUtilTest() {
- resolver_.reset(NewTypeResolverForDescriptorPool(
- kTypeUrlPrefix, DescriptorPool::generated_pool()));
}
string ToJson(const Message& message, const JsonPrintOptions& options) {
string result;
- GOOGLE_CHECK_OK(BinaryToJsonString(resolver_.get(),
- GetTypeUrl(message.GetDescriptor()),
- message.SerializeAsString(), &result, options));
+ GOOGLE_CHECK_OK(MessageToJsonString(message, &result, options));
return result;
}
bool FromJson(const string& json, Message* message,
const JsonParseOptions& options) {
- string binary;
- if (!JsonToBinaryString(resolver_.get(),
- GetTypeUrl(message->GetDescriptor()), json, &binary,
- options)
- .ok()) {
- return false;
- }
- return message->ParseFromString(binary);
+ return JsonStringToMessage(json, message, options).ok();
+ }
+
+ bool FromJson(const string& json, Message* message) {
+ return FromJson(json, message, JsonParseOptions());
}
google::protobuf::scoped_ptr<TypeResolver> resolver_;
@@ -133,6 +128,34 @@ TEST_F(JsonUtilTest, TestDefaultValues) {
"\"repeatedMessageValue\":[]"
"}",
ToJson(m, options));
+
+ options.always_print_primitive_fields = true;
+ m.set_string_value("i am a test string value");
+ m.set_bytes_value("i am a test bytes value");
+ EXPECT_EQ(
+ "{\"boolValue\":false,"
+ "\"int32Value\":0,"
+ "\"int64Value\":\"0\","
+ "\"uint32Value\":0,"
+ "\"uint64Value\":\"0\","
+ "\"floatValue\":0,"
+ "\"doubleValue\":0,"
+ "\"stringValue\":\"i am a test string value\","
+ "\"bytesValue\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
+ "\"enumValue\":\"FOO\","
+ "\"repeatedBoolValue\":[],"
+ "\"repeatedInt32Value\":[],"
+ "\"repeatedInt64Value\":[],"
+ "\"repeatedUint32Value\":[],"
+ "\"repeatedUint64Value\":[],"
+ "\"repeatedFloatValue\":[],"
+ "\"repeatedDoubleValue\":[],"
+ "\"repeatedStringValue\":[],"
+ "\"repeatedBytesValue\":[],"
+ "\"repeatedEnumValue\":[],"
+ "\"repeatedMessageValue\":[]"
+ "}",
+ ToJson(m, options));
}
TEST_F(JsonUtilTest, ParseMessage) {
@@ -189,6 +212,45 @@ TEST_F(JsonUtilTest, TestParseErrors) {
EXPECT_FALSE(FromJson("{\"int32Value\":2147483648}", &m, options));
}
+TEST_F(JsonUtilTest, TestDynamicMessage) {
+ // Some random message but good enough to test the wrapper functions.
+ string input =
+ "{\n"
+ " \"int32Value\": 1024,\n"
+ " \"repeatedInt32Value\": [1, 2],\n"
+ " \"messageValue\": {\n"
+ " \"value\": 2048\n"
+ " },\n"
+ " \"repeatedMessageValue\": [\n"
+ " {\"value\": 40}, {\"value\": 96}\n"
+ " ]\n"
+ "}\n";
+
+ // Create a new DescriptorPool with the same protos as the generated one.
+ DescriptorPoolDatabase database(*DescriptorPool::generated_pool());
+ DescriptorPool pool(&database);
+ // A dynamic version of the test proto.
+ DynamicMessageFactory factory;
+ google::protobuf::scoped_ptr<Message> message(factory.GetPrototype(
+ pool.FindMessageTypeByName("proto3.TestMessage"))->New());
+ EXPECT_TRUE(FromJson(input, message.get()));
+
+ // Convert to generated message for easy inspection.
+ TestMessage generated;
+ EXPECT_TRUE(generated.ParseFromString(message->SerializeAsString()));
+ EXPECT_EQ(1024, generated.int32_value());
+ ASSERT_EQ(2, generated.repeated_int32_value_size());
+ EXPECT_EQ(1, generated.repeated_int32_value(0));
+ EXPECT_EQ(2, generated.repeated_int32_value(1));
+ EXPECT_EQ(2048, generated.message_value().value());
+ ASSERT_EQ(2, generated.repeated_message_value_size());
+ EXPECT_EQ(40, generated.repeated_message_value(0).value());
+ EXPECT_EQ(96, generated.repeated_message_value(1).value());
+
+ JsonOptions options;
+ EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
+}
+
typedef pair<char*, int> Segment;
// A ZeroCopyOutputStream that writes to multiple buffers.
class SegmentedZeroCopyOutputStream : public io::ZeroCopyOutputStream {
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index a6d0cb07..03a334b6 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -1389,8 +1389,7 @@ bool MessageDifferencer::MatchRepeatedFieldIndices(
// doesn't necessarily imply Compare(b, c). Therefore a naive greedy
// algorithm will fail to find a maximum matching.
// Here we use the argumenting path algorithm.
- MaximumMatcher::NodeMatchCallback* callback =
- ::google::protobuf::internal::NewPermanentCallback(
+ MaximumMatcher::NodeMatchCallback* callback = NewPermanentCallback(
this, &MessageDifferencer::IsMatch,
repeated_field, key_comparator,
&message1, &message2, parent_fields);
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
index c782d691..031d019a 100644
--- a/src/google/protobuf/util/time_util.cc
+++ b/src/google/protobuf/util/time_util.cc
@@ -142,6 +142,13 @@ int64 RoundTowardZero(int64 value, int64 divider) {
}
} // namespace
+// Actually define these static const integers. Required by C++ standard (but
+// omitting them may still work with some compilers).
+const int64 TimeUtil::kTimestampMinSeconds;
+const int64 TimeUtil::kTimestampMaxSeconds;
+const int64 TimeUtil::kDurationMaxSeconds;
+const int64 TimeUtil::kDurationMinSeconds;
+
string TimeUtil::ToString(const Timestamp& timestamp) {
return FormatTime(timestamp.seconds(), timestamp.nanos());
}
@@ -174,7 +181,7 @@ string TimeUtil::ToString(const Duration& duration) {
seconds = -seconds;
nanos = -nanos;
}
- result += StringPrintf("%" GOOGLE_LL_FORMAT "d", seconds);
+ result += SimpleItoa(seconds);
if (nanos != 0) {
result += "." + FormatNanos(nanos);
}
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index f2517074..05cc0854 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -466,7 +466,8 @@ void WireFormatLite::WriteGroupMaybeToArray(int field_number,
const int size = value.GetCachedSize();
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
- uint8* end = value.SerializeWithCachedSizesToArray(target);
+ uint8* end = value.InternalSerializeWithCachedSizesToArray(
+ output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
@@ -482,7 +483,8 @@ void WireFormatLite::WriteMessageMaybeToArray(int field_number,
output->WriteVarint32(size);
uint8* target = output->GetDirectBufferForNBytesAndAdvance(size);
if (target != NULL) {
- uint8* end = value.SerializeWithCachedSizesToArray(target);
+ uint8* end = value.InternalSerializeWithCachedSizesToArray(
+ output->IsSerializationDeterminstic(), target);
GOOGLE_DCHECK_EQ(end - target, size);
} else {
value.SerializeWithCachedSizes(output);
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index ebd858ff..93d7c824 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -346,9 +346,9 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
io::CodedInputStream* input, RepeatedField<CType>* values) {
int length;
if (!input->ReadVarintSizeAsInt(&length)) return false;
- const uint32 old_entries = values->size();
- const uint32 new_entries = length / sizeof(CType);
- const uint32 new_bytes = new_entries * sizeof(CType);
+ const int old_entries = values->size();
+ const int new_entries = length / sizeof(CType);
+ const int new_bytes = new_entries * sizeof(CType);
if (new_bytes != length) return false;
// We would *like* to pre-allocate the buffer to write into (for
// speed), but *must* avoid performing a very large allocation due
@@ -382,7 +382,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
#else
values->Reserve(old_entries + new_entries);
CType value;
- for (uint32 i = 0; i < new_entries; ++i) {
+ for (int i = 0; i < new_entries; ++i) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->AddAlreadyReserved(value);
}
@@ -392,7 +392,7 @@ inline bool WireFormatLite::ReadPackedFixedSizePrimitive(
// safely allocate. We read as much as we can into *values
// without pre-allocating "length" bytes.
CType value;
- for (uint32 i = 0; i < new_entries; ++i) {
+ for (int i = 0; i < new_entries; ++i) {
if (!ReadPrimitive<CType, DeclaredType>(input, &value)) return false;
values->Add(value);
}
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index 08490f3f..33a69d3b 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -53,6 +53,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
} // namespace
+void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto() {
protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto();
const ::google::protobuf::FileDescriptor* file =
@@ -204,6 +205,7 @@ inline void protobuf_AssignDescriptorsOnce() {
&protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto);
}
+void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD;
void protobuf_RegisterTypes(const ::std::string&) {
protobuf_AssignDescriptorsOnce();
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
@@ -249,6 +251,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto() {
delete BytesValue_reflection_;
}
+void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() GOOGLE_ATTRIBUTE_COLD;
void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
static bool already_here = false;
if (already_here) return;
@@ -298,16 +301,6 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2fwrappers_2eproto {
}
} static_descriptor_initializer_google_2fprotobuf_2fwrappers_2eproto_;
-namespace {
-
-static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
-static void MergeFromFail(int line) {
- GOOGLE_CHECK(false) << __FILE__ << ":" << line;
-}
-
-} // namespace
-
-
// ===================================================================
#if !defined(_MSC_VER) || _MSC_VER >= 1900
@@ -477,7 +470,9 @@ int DoubleValue::ByteSize() const {
void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.DoubleValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const DoubleValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const DoubleValue>(
&from);
@@ -492,7 +487,9 @@ void DoubleValue::MergeFrom(const ::google::protobuf::Message& from) {
void DoubleValue::MergeFrom(const DoubleValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -735,7 +732,9 @@ int FloatValue::ByteSize() const {
void FloatValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.FloatValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const FloatValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const FloatValue>(
&from);
@@ -750,7 +749,9 @@ void FloatValue::MergeFrom(const ::google::protobuf::Message& from) {
void FloatValue::MergeFrom(const FloatValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -995,7 +996,9 @@ int Int64Value::ByteSize() const {
void Int64Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int64Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Int64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int64Value>(
&from);
@@ -1010,7 +1013,9 @@ void Int64Value::MergeFrom(const ::google::protobuf::Message& from) {
void Int64Value::MergeFrom(const Int64Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -1255,7 +1260,9 @@ int UInt64Value::ByteSize() const {
void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt64Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UInt64Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt64Value>(
&from);
@@ -1270,7 +1277,9 @@ void UInt64Value::MergeFrom(const ::google::protobuf::Message& from) {
void UInt64Value::MergeFrom(const UInt64Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -1515,7 +1524,9 @@ int Int32Value::ByteSize() const {
void Int32Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.Int32Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const Int32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const Int32Value>(
&from);
@@ -1530,7 +1541,9 @@ void Int32Value::MergeFrom(const ::google::protobuf::Message& from) {
void Int32Value::MergeFrom(const Int32Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -1775,7 +1788,9 @@ int UInt32Value::ByteSize() const {
void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.UInt32Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const UInt32Value* source =
::google::protobuf::internal::DynamicCastToGenerated<const UInt32Value>(
&from);
@@ -1790,7 +1805,9 @@ void UInt32Value::MergeFrom(const ::google::protobuf::Message& from) {
void UInt32Value::MergeFrom(const UInt32Value& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -2033,7 +2050,9 @@ int BoolValue::ByteSize() const {
void BoolValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BoolValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const BoolValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BoolValue>(
&from);
@@ -2048,7 +2067,9 @@ void BoolValue::MergeFrom(const ::google::protobuf::Message& from) {
void BoolValue::MergeFrom(const BoolValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value() != 0) {
set_value(from.value());
}
@@ -2308,7 +2329,9 @@ int StringValue::ByteSize() const {
void StringValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.StringValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const StringValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const StringValue>(
&from);
@@ -2323,7 +2346,9 @@ void StringValue::MergeFrom(const ::google::protobuf::Message& from) {
void StringValue::MergeFrom(const StringValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value().size() > 0) {
set_value(from.value());
}
@@ -2623,7 +2648,9 @@ int BytesValue::ByteSize() const {
void BytesValue::MergeFrom(const ::google::protobuf::Message& from) {
// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.BytesValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
const BytesValue* source =
::google::protobuf::internal::DynamicCastToGenerated<const BytesValue>(
&from);
@@ -2638,7 +2665,9 @@ void BytesValue::MergeFrom(const ::google::protobuf::Message& from) {
void BytesValue::MergeFrom(const BytesValue& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue)
- if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (GOOGLE_PREDICT_FALSE(&from == this)) {
+ ::google::protobuf::internal::MergeFromFail(__FILE__, __LINE__);
+ }
if (from.value().size() > 0) {
set_value(from.value());
}