aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am72
-rw-r--r--src/google/protobuf/any.cc4
-rw-r--r--src/google/protobuf/any.h2
-rw-r--r--src/google/protobuf/any.pb.cc14
-rw-r--r--src/google/protobuf/any.proto10
-rw-r--r--src/google/protobuf/api.pb.cc733
-rw-r--r--src/google/protobuf/api.pb.h315
-rw-r--r--src/google/protobuf/api.proto107
-rwxr-xr-xsrc/google/protobuf/arena.cc40
-rw-r--r--src/google/protobuf/arena.h174
-rw-r--r--src/google/protobuf/arena_test_util.cc1
-rw-r--r--src/google/protobuf/arena_unittest.cc55
-rwxr-xr-xsrc/google/protobuf/arenastring.h12
-rw-r--r--src/google/protobuf/arenastring_unittest.cc1
-rw-r--r--src/google/protobuf/compiler/code_generator.cc1
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc5
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc43
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.cc8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum.h5
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_enum_field.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_field.cc1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc254
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.h32
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_generator.cc13
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc112
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h26
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.cc72
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_map_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.cc181
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message.h9
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.cc616
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_message_field.h20
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc115
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.h1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc8
-rw-r--r--src/google/protobuf/compiler/importer_unittest.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum.cc4
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum_field_lite.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.cc226
-rw-r--r--src/google/protobuf/compiler/java/java_enum_lite.h99
-rw-r--r--src/google/protobuf/compiler/java/java_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_field.h1
-rw-r--r--src/google/protobuf/compiler/java/java_helpers.h15
-rw-r--r--src/google/protobuf/compiler/java/java_map_field.cc24
-rw-r--r--src/google/protobuf/compiler/java/java_map_field_lite.cc24
-rw-r--r--src/google/protobuf/compiler/java/java_message.cc137
-rw-r--r--src/google/protobuf/compiler/java/java_message.h1
-rw-r--r--src/google/protobuf/compiler/java/java_message_field.cc13
-rw-r--r--src/google/protobuf/compiler/java/java_message_field_lite.cc14
-rw-r--r--src/google/protobuf/compiler/java/java_message_lite.cc92
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_primitive_field_lite.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_service.cc1
-rw-r--r--src/google/protobuf/compiler/java/java_string_field.cc26
-rw-r--r--src/google/protobuf/compiler/java/java_string_field_lite.cc193
-rw-r--r--src/google/protobuf/compiler/parser.cc37
-rw-r--r--src/google/protobuf/compiler/parser.h6
-rw-r--r--src/google/protobuf/compiler/plugin.cc1
-rw-r--r--src/google/protobuf/compiler/plugin.pb.cc44
-rw-r--r--src/google/protobuf/compiler/plugin.pb.h28
-rw-r--r--src/google/protobuf/compiler/python/python_generator.cc1
-rw-r--r--src/google/protobuf/compiler/python/python_generator.h1
-rw-r--r--src/google/protobuf/compiler/subprocess.cc1
-rw-r--r--src/google/protobuf/descriptor.cc24
-rw-r--r--src/google/protobuf/descriptor.h4
-rw-r--r--src/google/protobuf/descriptor.pb.cc506
-rw-r--r--src/google/protobuf/descriptor.pb.h346
-rw-r--r--src/google/protobuf/descriptor.proto11
-rw-r--r--src/google/protobuf/descriptor_database_unittest.cc2
-rw-r--r--src/google/protobuf/descriptor_unittest.cc85
-rw-r--r--src/google/protobuf/duration.proto1
-rw-r--r--src/google/protobuf/dynamic_message.cc27
-rw-r--r--src/google/protobuf/dynamic_message.h1
-rw-r--r--src/google/protobuf/dynamic_message_unittest.cc2
-rw-r--r--src/google/protobuf/empty.pb.cc6
-rw-r--r--src/google/protobuf/empty.proto7
-rw-r--r--src/google/protobuf/extension_set.h7
-rw-r--r--src/google/protobuf/extension_set_heavy.cc16
-rw-r--r--src/google/protobuf/extension_set_unittest.cc3
-rw-r--r--src/google/protobuf/field_mask.pb.cc24
-rw-r--r--src/google/protobuf/field_mask.proto6
-rw-r--r--src/google/protobuf/generated_message_reflection.cc133
-rw-r--r--src/google/protobuf/generated_message_reflection.h38
-rw-r--r--src/google/protobuf/generated_message_reflection_unittest.cc52
-rw-r--r--src/google/protobuf/io/coded_stream.cc5
-rw-r--r--src/google/protobuf/io/coded_stream.h31
-rw-r--r--src/google/protobuf/io/coded_stream_inl.h1
-rw-r--r--src/google/protobuf/io/coded_stream_unittest.cc2
-rw-r--r--src/google/protobuf/io/gzip_stream.cc2
-rw-r--r--src/google/protobuf/io/printer.cc1
-rw-r--r--src/google/protobuf/io/printer_unittest.cc1
-rw-r--r--src/google/protobuf/io/strtod.cc1
-rw-r--r--src/google/protobuf/io/tokenizer.cc1
-rw-r--r--src/google/protobuf/io/tokenizer.h1
-rw-r--r--src/google/protobuf/io/tokenizer_unittest.cc1
-rw-r--r--src/google/protobuf/io/zero_copy_stream.cc1
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl.cc1
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.cc1
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl_lite.h1
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc3
-rw-r--r--src/google/protobuf/lite_arena_unittest.cc83
-rw-r--r--src/google/protobuf/lite_unittest.cc39
-rw-r--r--src/google/protobuf/map.h444
-rw-r--r--src/google/protobuf/map_entry.h81
-rw-r--r--src/google/protobuf/map_entry_lite.h158
-rw-r--r--src/google/protobuf/map_field.cc316
-rw-r--r--src/google/protobuf/map_field.h194
-rw-r--r--src/google/protobuf/map_field_inl.h233
-rw-r--r--src/google/protobuf/map_field_test.cc23
-rw-r--r--src/google/protobuf/map_lite_unittest.proto17
-rw-r--r--src/google/protobuf/map_proto2_unittest.proto8
-rw-r--r--src/google/protobuf/map_test.cc190
-rw-r--r--src/google/protobuf/map_test_util.cc726
-rw-r--r--src/google/protobuf/map_test_util.h131
-rw-r--r--src/google/protobuf/map_test_util_impl.h16
-rw-r--r--src/google/protobuf/map_type_handler.h729
-rw-r--r--src/google/protobuf/map_unittest.proto16
-rw-r--r--src/google/protobuf/message.cc19
-rw-r--r--src/google/protobuf/message.h113
-rw-r--r--src/google/protobuf/message_lite.cc62
-rw-r--r--src/google/protobuf/message_unittest.cc1
-rw-r--r--src/google/protobuf/metadata.h15
-rw-r--r--src/google/protobuf/no_field_presence_test.cc40
-rw-r--r--src/google/protobuf/proto3_arena_unittest.cc26
-rw-r--r--src/google/protobuf/proto_cast.h1
-rw-r--r--src/google/protobuf/proto_cast_test.cc2
-rwxr-xr-xsrc/google/protobuf/reflection.h2
-rw-r--r--src/google/protobuf/reflection_ops_unittest.cc1
-rw-r--r--src/google/protobuf/repeated_field.cc9
-rw-r--r--src/google/protobuf/repeated_field.h82
-rw-r--r--src/google/protobuf/repeated_field_unittest.cc2
-rw-r--r--src/google/protobuf/service.h5
-rw-r--r--src/google/protobuf/source_context.pb.cc20
-rw-r--r--src/google/protobuf/source_context.proto2
-rw-r--r--src/google/protobuf/struct.pb.cc66
-rw-r--r--src/google/protobuf/struct.pb.h30
-rw-r--r--src/google/protobuf/struct.proto28
-rw-r--r--src/google/protobuf/stubs/common.cc63
-rw-r--r--src/google/protobuf/stubs/common.h24
-rwxr-xr-xsrc/google/protobuf/stubs/hash.h9
-rw-r--r--src/google/protobuf/stubs/int128.cc200
-rw-r--r--src/google/protobuf/stubs/int128.h383
-rw-r--r--src/google/protobuf/stubs/int128_unittest.cc513
-rw-r--r--src/google/protobuf/stubs/logging.h4
-rw-r--r--src/google/protobuf/stubs/mathutil.h16
-rw-r--r--src/google/protobuf/stubs/port.h19
-rw-r--r--src/google/protobuf/stubs/status.cc1
-rw-r--r--src/google/protobuf/stubs/structurally_valid.cc52
-rw-r--r--src/google/protobuf/test_util.cc1
-rw-r--r--src/google/protobuf/test_util_lite.cc1
-rw-r--r--src/google/protobuf/text_format_unittest.cc2
-rw-r--r--src/google/protobuf/timestamp.proto11
-rw-r--r--src/google/protobuf/type.pb.cc527
-rw-r--r--src/google/protobuf/type.pb.h211
-rw-r--r--src/google/protobuf/type.proto102
-rw-r--r--src/google/protobuf/unittest_mset.proto19
-rw-r--r--src/google/protobuf/unittest_mset_wire_format.proto52
-rw-r--r--src/google/protobuf/unittest_no_arena.proto1
-rw-r--r--src/google/protobuf/unittest_no_arena_lite.proto42
-rw-r--r--src/google/protobuf/unknown_enum_impl.h9
-rw-r--r--src/google/protobuf/unknown_enum_test.proto2
-rw-r--r--src/google/protobuf/unknown_field_set.cc1
-rw-r--r--src/google/protobuf/unknown_field_set.h1
-rw-r--r--src/google/protobuf/unknown_field_set_unittest.cc3
-rw-r--r--src/google/protobuf/util/field_comparator_test.cc2
-rw-r--r--src/google/protobuf/util/field_mask_util.cc418
-rw-r--r--src/google/protobuf/util/field_mask_util.h146
-rw-r--r--src/google/protobuf/util/field_mask_util_test.cc395
-rw-r--r--src/google/protobuf/util/internal/datapiece.cc6
-rw-r--r--src/google/protobuf/util/internal/datapiece.h14
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc66
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.h11
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter_test.cc58
-rw-r--r--src/google/protobuf/util/internal/error_listener.h2
-rw-r--r--src/google/protobuf/util/internal/field_mask_utility.cc23
-rw-r--r--src/google/protobuf/util/internal/json_escaping.cc1
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter.cc12
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter_test.cc189
-rw-r--r--src/google/protobuf/util/internal/json_stream_parser.cc62
-rw-r--r--src/google/protobuf/util/internal/json_stream_parser.h12
-rw-r--r--src/google/protobuf/util/internal/json_stream_parser_test.cc23
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc69
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.h14
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource_test.cc40
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.cc143
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter.h45
-rw-r--r--src/google/protobuf/util/internal/protostream_objectwriter_test.cc306
-rw-r--r--src/google/protobuf/util/internal/snake2camel_objectwriter.h46
-rw-r--r--src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc260
-rw-r--r--src/google/protobuf/util/internal/testdata/default_value.proto7
-rw-r--r--src/google/protobuf/util/internal/testdata/oneofs.proto68
-rw-r--r--src/google/protobuf/util/internal/type_info.cc25
-rw-r--r--src/google/protobuf/util/internal/type_info.h13
-rw-r--r--src/google/protobuf/util/internal/type_info_test_helper.cc7
-rw-r--r--src/google/protobuf/util/internal/utility.cc15
-rw-r--r--src/google/protobuf/util/internal/utility.h11
-rw-r--r--src/google/protobuf/util/json_util.h6
-rw-r--r--src/google/protobuf/util/json_util_test.cc43
-rw-r--r--src/google/protobuf/util/message_differencer.cc1
-rwxr-xr-xsrc/google/protobuf/util/message_differencer_unittest.cc3
-rw-r--r--src/google/protobuf/util/time_util.cc525
-rw-r--r--src/google/protobuf/util/time_util.h296
-rw-r--r--src/google/protobuf/util/time_util_test.cc380
-rw-r--r--src/google/protobuf/util/type_resolver_util.cc43
-rw-r--r--src/google/protobuf/wire_format.cc57
-rw-r--r--src/google/protobuf/wire_format.h19
-rw-r--r--src/google/protobuf/wire_format_lite.cc38
-rw-r--r--src/google/protobuf/wire_format_lite.h177
-rw-r--r--src/google/protobuf/wire_format_lite_inl.h1
-rw-r--r--src/google/protobuf/wire_format_unittest.cc16
-rw-r--r--src/google/protobuf/wrappers.pb.cc21
-rw-r--r--src/google/protobuf/wrappers.pb.h10
-rw-r--r--src/google/protobuf/wrappers.proto38
215 files changed, 12468 insertions, 3331 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 584bcd21..caae2933 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -158,9 +158,11 @@ nobase_include_HEADERS = \
google/protobuf/compiler/csharp/csharp_generator.h \
google/protobuf/compiler/csharp/csharp_names.h \
google/protobuf/util/type_resolver.h \
- google/protobuf/util/type_resolver_util.h \
- google/protobuf/util/json_util.h \
google/protobuf/util/field_comparator.h \
+ google/protobuf/util/field_mask_util.h \
+ google/protobuf/util/json_util.h \
+ google/protobuf/util/time_util.h \
+ google/protobuf/util/type_resolver_util.h \
google/protobuf/util/message_differencer.h
lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la
@@ -174,6 +176,8 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/stubs/bytestream.h \
google/protobuf/stubs/common.cc \
google/protobuf/stubs/hash.h \
+ google/protobuf/stubs/int128.cc \
+ google/protobuf/stubs/int128.h \
google/protobuf/stubs/map_util.h \
google/protobuf/stubs/mathutil.h \
google/protobuf/stubs/once.cc \
@@ -187,6 +191,7 @@ libprotobuf_lite_la_SOURCES = \
google/protobuf/stubs/stringpiece.h \
google/protobuf/stubs/stringprintf.cc \
google/protobuf/stubs/stringprintf.h \
+ google/protobuf/stubs/structurally_valid.cc \
google/protobuf/stubs/strutil.cc \
google/protobuf/stubs/strutil.h \
google/protobuf/stubs/time.cc \
@@ -209,8 +214,8 @@ libprotobuf_la_SOURCES = \
$(libprotobuf_lite_la_SOURCES) \
google/protobuf/any.pb.cc \
google/protobuf/api.pb.cc \
- google/protobuf/stubs/mathlimits.h \
google/protobuf/stubs/mathlimits.cc \
+ google/protobuf/stubs/mathlimits.h \
google/protobuf/any.cc \
google/protobuf/descriptor.cc \
google/protobuf/descriptor_database.cc \
@@ -228,7 +233,6 @@ libprotobuf_la_SOURCES = \
google/protobuf/service.cc \
google/protobuf/source_context.pb.cc \
google/protobuf/struct.pb.cc \
- google/protobuf/stubs/structurally_valid.cc \
google/protobuf/stubs/substitute.cc \
google/protobuf/stubs/substitute.h \
google/protobuf/text_format.cc \
@@ -245,6 +249,7 @@ libprotobuf_la_SOURCES = \
google/protobuf/compiler/importer.cc \
google/protobuf/compiler/parser.cc \
google/protobuf/util/field_comparator.cc \
+ google/protobuf/util/field_mask_util.cc \
google/protobuf/util/internal/constants.h \
google/protobuf/util/internal/datapiece.cc \
google/protobuf/util/internal/datapiece.h \
@@ -281,8 +286,10 @@ libprotobuf_la_SOURCES = \
google/protobuf/util/internal/utility.cc \
google/protobuf/util/internal/utility.h \
google/protobuf/util/json_util.cc \
- google/protobuf/util/type_resolver_util.cc \
- google/protobuf/util/message_differencer.cc
+ google/protobuf/util/message_differencer.cc \
+ google/protobuf/util/time_util.cc \
+ google/protobuf/util/type_resolver_util.cc
+
nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES)
libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la
@@ -325,11 +332,13 @@ libprotoc_la_SOURCES = \
google/protobuf/compiler/java/java_context.cc \
google/protobuf/compiler/java/java_context.h \
google/protobuf/compiler/java/java_enum.cc \
+ google/protobuf/compiler/java/java_enum_lite.cc \
google/protobuf/compiler/java/java_enum_field.cc \
google/protobuf/compiler/java/java_enum_field.h \
google/protobuf/compiler/java/java_enum_field_lite.cc \
google/protobuf/compiler/java/java_enum_field_lite.h \
google/protobuf/compiler/java/java_enum.h \
+ google/protobuf/compiler/java/java_enum_lite.h \
google/protobuf/compiler/java/java_extension.cc \
google/protobuf/compiler/java/java_extension.h \
google/protobuf/compiler/java/java_field.cc \
@@ -480,6 +489,8 @@ protoc_inputs = \
google/protobuf/unittest_lite_imports_nonlite.proto \
google/protobuf/unittest_lite.proto \
google/protobuf/unittest_mset.proto \
+ google/protobuf/unittest_mset_wire_format.proto \
+ google/protobuf/unittest_no_arena_lite.proto \
google/protobuf/unittest_no_arena_import.proto \
google/protobuf/unittest_no_arena.proto \
google/protobuf/unittest_no_field_presence.proto \
@@ -496,6 +507,7 @@ protoc_inputs = \
google/protobuf/util/internal/testdata/default_value_test.proto \
google/protobuf/util/internal/testdata/field_mask.proto \
google/protobuf/util/internal/testdata/maps.proto \
+ google/protobuf/util/internal/testdata/oneofs.proto \
google/protobuf/util/internal/testdata/struct.proto \
google/protobuf/util/internal/testdata/timestamp_duration.proto \
google/protobuf/util/json_format_proto3.proto \
@@ -530,6 +542,8 @@ protoc_lite_outputs = \
google/protobuf/map_lite_unittest.pb.h \
google/protobuf/unittest_lite.pb.cc \
google/protobuf/unittest_lite.pb.h \
+ google/protobuf/unittest_no_arena_lite.pb.cc \
+ google/protobuf/unittest_no_arena_lite.pb.h \
google/protobuf/unittest_import_lite.pb.cc \
google/protobuf/unittest_import_lite.pb.h \
google/protobuf/unittest_import_public_lite.pb.cc \
@@ -567,6 +581,8 @@ protoc_outputs = \
google/protobuf/unittest_lite_imports_nonlite.pb.h \
google/protobuf/unittest_mset.pb.cc \
google/protobuf/unittest_mset.pb.h \
+ google/protobuf/unittest_mset_wire_format.pb.cc \
+ google/protobuf/unittest_mset_wire_format.pb.h \
google/protobuf/unittest_no_arena_import.pb.cc \
google/protobuf/unittest_no_arena_import.pb.h \
google/protobuf/unittest_no_arena.pb.cc \
@@ -599,6 +615,8 @@ protoc_outputs = \
google/protobuf/util/internal/testdata/field_mask.pb.h \
google/protobuf/util/internal/testdata/maps.pb.cc \
google/protobuf/util/internal/testdata/maps.pb.h \
+ google/protobuf/util/internal/testdata/oneofs.pb.cc \
+ google/protobuf/util/internal/testdata/oneofs.pb.h \
google/protobuf/util/internal/testdata/struct.pb.cc \
google/protobuf/util/internal/testdata/struct.pb.h \
google/protobuf/util/internal/testdata/timestamp_duration.pb.cc \
@@ -641,7 +659,8 @@ COMMON_TEST_SOURCES = \
google/protobuf/testing/file.h
check_PROGRAMS = protoc protobuf-test protobuf-lazy-descriptor-test \
- protobuf-lite-test test_plugin $(GZCHECKPROGRAMS)
+ protobuf-lite-test test_plugin protobuf-lite-arena-test \
+ $(GZCHECKPROGRAMS)
protobuf_test_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
../gmock/gtest/lib/libgtest.la \
../gmock/lib/libgmock.la \
@@ -655,6 +674,7 @@ protobuf_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
protobuf_test_SOURCES = \
google/protobuf/stubs/bytestream_unittest.cc \
google/protobuf/stubs/common_unittest.cc \
+ google/protobuf/stubs/int128_unittest.cc \
google/protobuf/stubs/once_unittest.cc \
google/protobuf/stubs/statusor_test.cc \
google/protobuf/stubs/status_test.cc \
@@ -707,6 +727,7 @@ protobuf_test_SOURCES = \
google/protobuf/compiler/ruby/ruby_generator_unittest.cc \
google/protobuf/compiler/csharp/csharp_generator_unittest.cc \
google/protobuf/util/field_comparator_test.cc \
+ google/protobuf/util/field_mask_util_test.cc \
google/protobuf/util/internal/default_value_objectwriter_test.cc \
google/protobuf/util/internal/json_objectwriter_test.cc \
google/protobuf/util/internal/json_stream_parser_test.cc \
@@ -714,6 +735,7 @@ protobuf_test_SOURCES = \
google/protobuf/util/internal/protostream_objectwriter_test.cc \
google/protobuf/util/internal/type_info_test_helper.cc \
google/protobuf/util/json_util_test.cc \
+ google/protobuf/util/time_util_test.cc \
google/protobuf/util/type_resolver_util_test.cc \
$(COMMON_TEST_SOURCES)
@@ -735,21 +757,40 @@ protobuf_lazy_descriptor_test_SOURCES = \
$(COMMON_TEST_SOURCES)
nodist_protobuf_lazy_descriptor_test_SOURCES = $(protoc_outputs)
-# Build lite_unittest separately, since it doesn't use gtest.
-protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
-protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
-protobuf_lite_test_SOURCES = \
+COMMON_LITE_TEST_SOURCES = \
google/protobuf/arena_test_util.cc \
google/protobuf/arena_test_util.h \
- google/protobuf/lite_unittest.cc \
google/protobuf/map_lite_test_util.cc \
google/protobuf/map_lite_test_util.h \
google/protobuf/test_util_lite.cc \
google/protobuf/test_util_lite.h
- # TODO(teboring) add the file back and make the test build.
- # google/protobuf/map_lite_test.cc
+
+# Build lite_unittest separately, since it doesn't use gtest. It can't
+# depend on gtest because our internal version of gtest depend on proto
+# full runtime and we want to make sure this test builds without full
+# runtime.
+protobuf_lite_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la
+protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lite_test_SOURCES = \
+ google/protobuf/lite_unittest.cc \
+ $(COMMON_LITE_TEST_SOURCES)
nodist_protobuf_lite_test_SOURCES = $(protoc_lite_outputs)
+# lite_arena_unittest depends on gtest because teboring@ found that without
+# gtest when building the test internally our memory sanitizer doesn't detect
+# memory leaks (don't know why).
+protobuf_lite_arena_test_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la \
+ ../gmock/gtest/lib/libgtest.la \
+ ../gmock/lib/libgmock.la \
+ ../gmock/lib/libgmock_main.la
+protobuf_lite_arena_test_CPPFLAGS = -I$(srcdir)/../gmock/include \
+ -I$(srcdir)/../gmock/gtest/include
+protobuf_lite_arena_test_CXXFLAGS = $(NO_OPT_CXXFLAGS)
+protobuf_lite_arena_test_SOURCES = \
+ google/protobuf/lite_arena_unittest.cc \
+ $(COMMON_LITE_TEST_SOURCES)
+nodist_protobuf_lite_arena_test_SOURCES = $(protoc_lite_outputs)
+
# Test plugin binary.
test_plugin_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la \
../gmock/gtest/lib/libgtest.la
@@ -769,4 +810,5 @@ zcgunzip_SOURCES = google/protobuf/testing/zcgunzip.cc
endif
TESTS = protobuf-test protobuf-lazy-descriptor-test protobuf-lite-test \
- google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS)
+ google/protobuf/compiler/zip_output_unittest.sh $(GZTESTS) \
+ protobuf-lite-arena-test
diff --git a/src/google/protobuf/any.cc b/src/google/protobuf/any.cc
index c66fdfad..c6ed37ae 100644
--- a/src/google/protobuf/any.cc
+++ b/src/google/protobuf/any.cc
@@ -50,7 +50,7 @@ AnyMetadata::AnyMetadata(UrlType* type_url, ValueType* value)
void AnyMetadata::PackFrom(const Message& message) {
type_url_->SetNoArena(&::google::protobuf::internal::GetEmptyString(),
- GetTypeUrl(message.GetDescriptor()));
+ GetTypeUrl(message.GetDescriptor()));
message.SerializeToString(value_->MutableNoArena(
&::google::protobuf::internal::GetEmptyStringAlreadyInited()));
}
@@ -76,7 +76,7 @@ bool ParseAnyTypeUrl(const string& type_url, string* full_type_name) {
type_url.size() - prefix_len);
return true;
}
- return true;
+ return false;
}
diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h
index f681eceb..7eeb6b70 100644
--- a/src/google/protobuf/any.h
+++ b/src/google/protobuf/any.h
@@ -34,9 +34,9 @@
#include <string>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/arenastring.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
+#include <google/protobuf/arenastring.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc
index c2e58131..cbb5d233 100644
--- a/src/google/protobuf/any.pb.cc
+++ b/src/google/protobuf/any.pb.cc
@@ -208,10 +208,10 @@ bool Any::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_type_url()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Any.type_url");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Any.type_url"));
} else {
goto handle_unusual;
}
@@ -258,9 +258,9 @@ void Any::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Any)
// optional string type_url = 1;
if (this->type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Any.type_url");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->type_url(), output);
@@ -280,9 +280,9 @@ void Any::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any)
// optional string type_url = 1;
if (this->type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Any.type_url");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
diff --git a/src/google/protobuf/any.proto b/src/google/protobuf/any.proto
index d3ad3acc..423699be 100644
--- a/src/google/protobuf/any.proto
+++ b/src/google/protobuf/any.proto
@@ -42,10 +42,8 @@ option objc_class_prefix = "GPB";
// `Any` contains an arbitrary serialized message along with a URL
// that describes the type of the serialized message.
//
-// The proto runtimes and/or compiler will eventually
-// provide utilities to pack/unpack Any values (projected Q1/15).
-//
-// # JSON
+// JSON
+// ====
// The JSON representation of an `Any` value uses the regular
// representation of the deserialized, embedded message, with an
// additional field `@type` which contains the type URL. Example:
@@ -93,10 +91,6 @@ message Any {
// Schemas other than `http`, `https` (or the empty schema) might be
// used with implementation specific semantics.
//
- // Types originating from the `google.*` package
- // namespace should use `type.googleapis.com/full.type.name` (without
- // schema and path). A type service will eventually become available which
- // serves those URLs (projected Q2/15).
string type_url = 1;
// Must be valid serialized data of the above specified type.
diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc
index 0feddb31..0a2c4ec0 100644
--- a/src/google/protobuf/api.pb.cc
+++ b/src/google/protobuf/api.pb.cc
@@ -27,6 +27,9 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
const ::google::protobuf::Descriptor* Method_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
Method_reflection_ = NULL;
+const ::google::protobuf::Descriptor* Mixin_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+ Mixin_reflection_ = NULL;
} // namespace
@@ -38,12 +41,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
"google/protobuf/api.proto");
GOOGLE_CHECK(file != NULL);
Api_descriptor_ = file->message_type(0);
- static const int Api_offsets_[5] = {
+ static const int Api_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, version_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, source_context_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, mixins_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, syntax_),
};
Api_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -57,13 +62,14 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _is_default_instance_));
Method_descriptor_ = file->message_type(1);
- static const int Method_offsets_[6] = {
+ static const int Method_offsets_[7] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_type_url_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, request_streaming_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_type_url_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, response_streaming_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, options_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, syntax_),
};
Method_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -76,6 +82,22 @@ void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto() {
sizeof(Method),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _is_default_instance_));
+ Mixin_descriptor_ = file->message_type(2);
+ static const int Mixin_offsets_[2] = {
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_),
+ };
+ Mixin_reflection_ =
+ ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+ Mixin_descriptor_,
+ Mixin::default_instance_,
+ Mixin_offsets_,
+ -1,
+ -1,
+ -1,
+ sizeof(Mixin),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _is_default_instance_));
}
namespace {
@@ -92,6 +114,8 @@ void protobuf_RegisterTypes(const ::std::string&) {
Api_descriptor_, &Api::default_instance());
::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
Method_descriptor_, &Method::default_instance());
+ ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+ Mixin_descriptor_, &Mixin::default_instance());
}
} // namespace
@@ -101,6 +125,8 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto() {
delete Api_reflection_;
delete Method::default_instance_;
delete Method_reflection_;
+ delete Mixin::default_instance_;
+ delete Mixin_reflection_;
}
void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
@@ -114,24 +140,30 @@ void protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\031google/protobuf/api.proto\022\017google.prot"
"obuf\032$google/protobuf/source_context.pro"
- "to\032\032google/protobuf/type.proto\"\260\001\n\003Api\022\014"
+ "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
"\n\004name\030\001 \001(\t\022(\n\007methods\030\002 \003(\0132\027.google.p"
"rotobuf.Method\022(\n\007options\030\003 \003(\0132\027.google"
".protobuf.Option\022\017\n\007version\030\004 \001(\t\0226\n\016sou"
"rce_context\030\005 \001(\0132\036.google.protobuf.Sour"
- "ceContext\"\254\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020re"
- "quest_type_url\030\002 \001(\t\022\031\n\021request_streamin"
- "g\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022re"
- "sponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\0132"
- "\027.google.protobuf.OptionBH\n\023com.google.p"
- "rotobufB\010ApiProtoP\001\242\002\003GPB\252\002\036Google.Proto"
- "buf.WellKnownTypesb\006proto3", 546);
+ "ceContext\022&\n\006mixins\030\006 \003(\0132\026.google.proto"
+ "buf.Mixin\022\'\n\006syntax\030\007 \001(\0162\027.google.proto"
+ "buf.Syntax\"\325\001\n\006Method\022\014\n\004name\030\001 \001(\t\022\030\n\020r"
+ "equest_type_url\030\002 \001(\t\022\031\n\021request_streami"
+ "ng\030\003 \001(\010\022\031\n\021response_type_url\030\004 \001(\t\022\032\n\022r"
+ "esponse_streaming\030\005 \001(\010\022(\n\007options\030\006 \003(\013"
+ "2\027.google.protobuf.Option\022\'\n\006syntax\030\007 \001("
+ "\0162\027.google.protobuf.Syntax\"#\n\005Mixin\022\014\n\004n"
+ "ame\030\001 \001(\t\022\014\n\004root\030\002 \001(\tBK\n\023com.google.pr"
+ "otobufB\010ApiProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Pro"
+ "tobuf.WellKnownTypesb\006proto3", 708);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/api.proto", &protobuf_RegisterTypes);
Api::default_instance_ = new Api();
Method::default_instance_ = new Method();
+ Mixin::default_instance_ = new Mixin();
Api::default_instance_->InitAsDefaultInstance();
Method::default_instance_->InitAsDefaultInstance();
+ Mixin::default_instance_->InitAsDefaultInstance();
::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto);
}
@@ -160,6 +192,8 @@ const int Api::kMethodsFieldNumber;
const int Api::kOptionsFieldNumber;
const int Api::kVersionFieldNumber;
const int Api::kSourceContextFieldNumber;
+const int Api::kMixinsFieldNumber;
+const int Api::kSyntaxFieldNumber;
#endif // !_MSC_VER
Api::Api()
@@ -188,6 +222,7 @@ void Api::SharedCtor() {
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
version_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
source_context_ = NULL;
+ syntax_ = 0;
}
Api::~Api() {
@@ -233,8 +268,10 @@ void Api::Clear() {
version_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
+ syntax_ = 0;
methods_.Clear();
options_.Clear();
+ mixins_.Clear();
}
bool Api::MergePartialFromCodedStream(
@@ -252,10 +289,10 @@ bool Api::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Api.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Api.name"));
} else {
goto handle_unusual;
}
@@ -302,10 +339,10 @@ bool Api::MergePartialFromCodedStream(
parse_version:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_version()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->version().data(), this->version().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Api.version");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Api.version"));
} else {
goto handle_unusual;
}
@@ -322,6 +359,39 @@ bool Api::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
+ if (input->ExpectTag(50)) goto parse_mixins;
+ break;
+ }
+
+ // repeated .google.protobuf.Mixin mixins = 6;
+ case 6: {
+ if (tag == 50) {
+ parse_mixins:
+ DO_(input->IncrementRecursionDepth());
+ parse_loop_mixins:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+ input, add_mixins()));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(50)) goto parse_loop_mixins;
+ input->UnsafeDecrementRecursionDepth();
+ if (input->ExpectTag(56)) goto parse_syntax;
+ break;
+ }
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ case 7: {
+ if (tag == 56) {
+ parse_syntax:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -352,9 +422,9 @@ void Api::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Api)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Api.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -374,9 +444,9 @@ void Api::SerializeWithCachedSizes(
// optional string version = 4;
if (this->version().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->version().data(), this->version().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Api.version");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
4, this->version(), output);
@@ -388,6 +458,18 @@ void Api::SerializeWithCachedSizes(
5, *this->source_context_, output);
}
+ // repeated .google.protobuf.Mixin mixins = 6;
+ for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+ ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+ 6, this->mixins(i), output);
+ }
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 7, this->syntax(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Api)
}
@@ -396,9 +478,9 @@ void Api::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Api.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -421,9 +503,9 @@ void Api::SerializeWithCachedSizes(
// optional string version = 4;
if (this->version().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->version().data(), this->version().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Api.version");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -437,6 +519,19 @@ void Api::SerializeWithCachedSizes(
5, *this->source_context_, target);
}
+ // repeated .google.protobuf.Mixin mixins = 6;
+ for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) {
+ target = ::google::protobuf::internal::WireFormatLite::
+ WriteMessageNoVirtualToArray(
+ 6, this->mixins(i), target);
+ }
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 7, this->syntax(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Api)
return target;
}
@@ -465,6 +560,12 @@ int Api::ByteSize() const {
*this->source_context_);
}
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+ }
+
// repeated .google.protobuf.Method methods = 2;
total_size += 1 * this->methods_size();
for (int i = 0; i < this->methods_size(); i++) {
@@ -481,6 +582,14 @@ int Api::ByteSize() const {
this->options(i));
}
+ // repeated .google.protobuf.Mixin mixins = 6;
+ total_size += 1 * this->mixins_size();
+ for (int i = 0; i < this->mixins_size(); i++) {
+ total_size +=
+ ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+ this->mixins(i));
+ }
+
GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
_cached_size_ = total_size;
GOOGLE_SAFE_CONCURRENT_WRITES_END();
@@ -503,6 +612,7 @@ void Api::MergeFrom(const Api& from) {
if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
methods_.MergeFrom(from.methods_);
options_.MergeFrom(from.options_);
+ mixins_.MergeFrom(from.mixins_);
if (from.name().size() > 0) {
name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
@@ -514,6 +624,9 @@ void Api::MergeFrom(const Api& from) {
if (from.has_source_context()) {
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
}
+ if (from.syntax() != 0) {
+ set_syntax(from.syntax());
+ }
}
void Api::CopyFrom(const ::google::protobuf::Message& from) {
@@ -543,6 +656,8 @@ void Api::InternalSwap(Api* other) {
options_.UnsafeArenaSwap(&other->options_);
version_.Swap(&other->version_);
std::swap(source_context_, other->source_context_);
+ mixins_.UnsafeArenaSwap(&other->mixins_);
+ std::swap(syntax_, other->syntax_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -608,28 +723,28 @@ int Api::methods_size() const {
void Api::clear_methods() {
methods_.Clear();
}
- const ::google::protobuf::Method& Api::methods(int index) const {
+const ::google::protobuf::Method& Api::methods(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Api.methods)
return methods_.Get(index);
}
- ::google::protobuf::Method* Api::mutable_methods(int index) {
+::google::protobuf::Method* Api::mutable_methods(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.methods)
return methods_.Mutable(index);
}
- ::google::protobuf::Method* Api::add_methods() {
+::google::protobuf::Method* Api::add_methods() {
// @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
return methods_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
-Api::methods() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
- return methods_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >*
Api::mutable_methods() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
return &methods_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
+Api::methods() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
+ return methods_;
+}
// repeated .google.protobuf.Option options = 3;
int Api::options_size() const {
@@ -638,28 +753,28 @@ int Api::options_size() const {
void Api::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& Api::options(int index) const {
+const ::google::protobuf::Option& Api::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Api.options)
return options_.Get(index);
}
- ::google::protobuf::Option* Api::mutable_options(int index) {
+::google::protobuf::Option* Api::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* Api::add_options() {
+::google::protobuf::Option* Api::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Api.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Api::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
- return options_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Api::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
return &options_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Api::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
+ return options_;
+}
// optional string version = 4;
void Api::clear_version() {
@@ -712,11 +827,11 @@ void Api::clear_source_context() {
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
}
- const ::google::protobuf::SourceContext& Api::source_context() const {
+const ::google::protobuf::SourceContext& Api::source_context() const {
// @@protoc_insertion_point(field_get:google.protobuf.Api.source_context)
return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_;
}
- ::google::protobuf::SourceContext* Api::mutable_source_context() {
+::google::protobuf::SourceContext* Api::mutable_source_context() {
if (source_context_ == NULL) {
source_context_ = new ::google::protobuf::SourceContext;
@@ -724,13 +839,13 @@ void Api::clear_source_context() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Api.source_context)
return source_context_;
}
- ::google::protobuf::SourceContext* Api::release_source_context() {
+::google::protobuf::SourceContext* Api::release_source_context() {
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
return temp;
}
- void Api::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
+void Api::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
delete source_context_;
source_context_ = source_context;
if (source_context) {
@@ -741,6 +856,50 @@ void Api::clear_source_context() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
}
+// repeated .google.protobuf.Mixin mixins = 6;
+int Api::mixins_size() const {
+ return mixins_.size();
+}
+void Api::clear_mixins() {
+ mixins_.Clear();
+}
+const ::google::protobuf::Mixin& Api::mixins(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
+ return mixins_.Get(index);
+}
+::google::protobuf::Mixin* Api::mutable_mixins(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+ return mixins_.Mutable(index);
+}
+::google::protobuf::Mixin* Api::add_mixins() {
+ // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
+ return mixins_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+Api::mutable_mixins() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
+ return &mixins_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+Api::mixins() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
+ return mixins_;
+}
+
+// optional .google.protobuf.Syntax syntax = 7;
+void Api::clear_syntax() {
+ syntax_ = 0;
+}
+ ::google::protobuf::Syntax Api::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Api::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
+}
+
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
@@ -752,6 +911,7 @@ const int Method::kRequestStreamingFieldNumber;
const int Method::kResponseTypeUrlFieldNumber;
const int Method::kResponseStreamingFieldNumber;
const int Method::kOptionsFieldNumber;
+const int Method::kSyntaxFieldNumber;
#endif // !_MSC_VER
Method::Method()
@@ -781,6 +941,7 @@ void Method::SharedCtor() {
request_streaming_ = false;
response_type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
response_streaming_ = false;
+ syntax_ = 0;
}
Method::~Method() {
@@ -830,7 +991,7 @@ void Method::Clear() {
ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)
- ZR_(request_streaming_, response_streaming_);
+ ZR_(request_streaming_, syntax_);
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
request_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
response_type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
@@ -856,10 +1017,10 @@ bool Method::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Method.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Method.name"));
} else {
goto handle_unusual;
}
@@ -873,10 +1034,10 @@ bool Method::MergePartialFromCodedStream(
parse_request_type_url:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_request_type_url()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->request_type_url().data(), this->request_type_url().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Method.request_type_url");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Method.request_type_url"));
} else {
goto handle_unusual;
}
@@ -905,10 +1066,10 @@ bool Method::MergePartialFromCodedStream(
parse_response_type_url:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_response_type_url()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->response_type_url().data(), this->response_type_url().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Method.response_type_url");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Method.response_type_url"));
} else {
goto handle_unusual;
}
@@ -944,6 +1105,22 @@ bool Method::MergePartialFromCodedStream(
}
if (input->ExpectTag(50)) goto parse_loop_options;
input->UnsafeDecrementRecursionDepth();
+ if (input->ExpectTag(56)) goto parse_syntax;
+ break;
+ }
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ case 7: {
+ if (tag == 56) {
+ parse_syntax:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -974,9 +1151,9 @@ void Method::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Method)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -984,9 +1161,9 @@ void Method::SerializeWithCachedSizes(
// optional string request_type_url = 2;
if (this->request_type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->request_type_url().data(), this->request_type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.request_type_url");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
2, this->request_type_url(), output);
@@ -999,9 +1176,9 @@ void Method::SerializeWithCachedSizes(
// optional string response_type_url = 4;
if (this->response_type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->response_type_url().data(), this->response_type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.response_type_url");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
4, this->response_type_url(), output);
@@ -1018,6 +1195,12 @@ void Method::SerializeWithCachedSizes(
6, this->options(i), output);
}
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 7, this->syntax(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Method)
}
@@ -1026,9 +1209,9 @@ void Method::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1037,9 +1220,9 @@ void Method::SerializeWithCachedSizes(
// optional string request_type_url = 2;
if (this->request_type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->request_type_url().data(), this->request_type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.request_type_url");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1053,9 +1236,9 @@ void Method::SerializeWithCachedSizes(
// optional string response_type_url = 4;
if (this->response_type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->response_type_url().data(), this->response_type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Method.response_type_url");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1074,6 +1257,12 @@ void Method::SerializeWithCachedSizes(
6, this->options(i), target);
}
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 7, this->syntax(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Method)
return target;
}
@@ -1112,6 +1301,12 @@ int Method::ByteSize() const {
total_size += 1 + 1;
}
+ // optional .google.protobuf.Syntax syntax = 7;
+ if (this->syntax() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+ }
+
// repeated .google.protobuf.Option options = 6;
total_size += 1 * this->options_size();
for (int i = 0; i < this->options_size(); i++) {
@@ -1159,6 +1354,9 @@ void Method::MergeFrom(const Method& from) {
if (from.response_streaming() != 0) {
set_response_streaming(from.response_streaming());
}
+ if (from.syntax() != 0) {
+ set_syntax(from.syntax());
+ }
}
void Method::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1189,6 +1387,7 @@ void Method::InternalSwap(Method* other) {
response_type_url_.Swap(&other->response_type_url_);
std::swap(response_streaming_, other->response_streaming_);
options_.UnsafeArenaSwap(&other->options_);
+ std::swap(syntax_, other->syntax_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -1368,27 +1567,409 @@ int Method::options_size() const {
void Method::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& Method::options(int index) const {
+const ::google::protobuf::Option& Method::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Method.options)
return options_.Get(index);
}
- ::google::protobuf::Option* Method::mutable_options(int index) {
+::google::protobuf::Option* Method::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Method.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* Method::add_options() {
+::google::protobuf::Option* Method::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Method.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+Method::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
+ return &options_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Method::options() const {
// @@protoc_insertion_point(field_list:google.protobuf.Method.options)
return options_;
}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
-Method::mutable_options() {
- // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
- return &options_;
+
+// optional .google.protobuf.Syntax syntax = 7;
+void Method::clear_syntax() {
+ syntax_ = 0;
+}
+ ::google::protobuf::Syntax Method::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Method::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
+}
+
+#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#ifndef _MSC_VER
+const int Mixin::kNameFieldNumber;
+const int Mixin::kRootFieldNumber;
+#endif // !_MSC_VER
+
+Mixin::Mixin()
+ : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+ SharedCtor();
+ // @@protoc_insertion_point(constructor:google.protobuf.Mixin)
+}
+
+void Mixin::InitAsDefaultInstance() {
+ _is_default_instance_ = true;
+}
+
+Mixin::Mixin(const Mixin& from)
+ : ::google::protobuf::Message(),
+ _internal_metadata_(NULL) {
+ SharedCtor();
+ MergeFrom(from);
+ // @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
+}
+
+void Mixin::SharedCtor() {
+ _is_default_instance_ = false;
+ ::google::protobuf::internal::GetEmptyString();
+ _cached_size_ = 0;
+ name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ root_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+Mixin::~Mixin() {
+ // @@protoc_insertion_point(destructor:google.protobuf.Mixin)
+ SharedDtor();
+}
+
+void Mixin::SharedDtor() {
+ name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ root_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ if (this != default_instance_) {
+ }
+}
+
+void Mixin::SetCachedSize(int size) const {
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* Mixin::descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return Mixin_descriptor_;
+}
+
+const Mixin& Mixin::default_instance() {
+ if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
+ return *default_instance_;
+}
+
+Mixin* Mixin::default_instance_ = NULL;
+
+Mixin* Mixin::New(::google::protobuf::Arena* arena) const {
+ Mixin* n = new Mixin;
+ if (arena != NULL) {
+ arena->Own(n);
+ }
+ return n;
+}
+
+void Mixin::Clear() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool Mixin::MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!(EXPRESSION)) goto failure
+ ::google::protobuf::uint32 tag;
+ // @@protoc_insertion_point(parse_start:google.protobuf.Mixin)
+ for (;;) {
+ ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+ tag = p.first;
+ if (!p.second) goto handle_unusual;
+ switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+ // optional string name = 1;
+ case 1: {
+ if (tag == 10) {
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_name()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Mixin.name"));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectTag(18)) goto parse_root;
+ break;
+ }
+
+ // optional string root = 2;
+ case 2: {
+ if (tag == 18) {
+ parse_root:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_root()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->root().data(), this->root().length(),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Mixin.root"));
+ } else {
+ goto handle_unusual;
+ }
+ if (input->ExpectAtEnd()) goto success;
+ break;
+ }
+
+ default: {
+ handle_unusual:
+ if (tag == 0 ||
+ ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+ goto success;
+ }
+ DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+ break;
+ }
+ }
+ }
+success:
+ // @@protoc_insertion_point(parse_success:google.protobuf.Mixin)
+ return true;
+failure:
+ // @@protoc_insertion_point(parse_failure:google.protobuf.Mixin)
+ return false;
+#undef DO_
+}
+
+void Mixin::SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const {
+ // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin)
+ // optional string name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Mixin.name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 1, this->name(), output);
+ }
+
+ // optional string root = 2;
+ if (this->root().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->root().data(), this->root().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Mixin.root");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 2, this->root(), output);
+ }
+
+ // @@protoc_insertion_point(serialize_end:google.protobuf.Mixin)
+}
+
+::google::protobuf::uint8* Mixin::SerializeWithCachedSizesToArray(
+ ::google::protobuf::uint8* target) const {
+ // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin)
+ // optional string name = 1;
+ if (this->name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->name().data(), this->name().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Mixin.name");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 1, this->name(), target);
+ }
+
+ // optional string root = 2;
+ if (this->root().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->root().data(), this->root().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Mixin.root");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 2, this->root(), target);
+ }
+
+ // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Mixin)
+ return target;
+}
+
+int Mixin::ByteSize() const {
+ int total_size = 0;
+
+ // optional string name = 1;
+ if (this->name().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->name());
+ }
+
+ // optional string root = 2;
+ if (this->root().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->root());
+ }
+
+ GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+ _cached_size_ = total_size;
+ GOOGLE_SAFE_CONCURRENT_WRITES_END();
+ return total_size;
+}
+
+void Mixin::MergeFrom(const ::google::protobuf::Message& from) {
+ if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ const Mixin* source =
+ ::google::protobuf::internal::DynamicCastToGenerated<const Mixin>(
+ &from);
+ if (source == NULL) {
+ ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+ } else {
+ MergeFrom(*source);
+ }
+}
+
+void Mixin::MergeFrom(const Mixin& from) {
+ if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+ if (from.name().size() > 0) {
+
+ name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+ }
+ if (from.root().size() > 0) {
+
+ root_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.root_);
+ }
+}
+
+void Mixin::CopyFrom(const ::google::protobuf::Message& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+void Mixin::CopyFrom(const Mixin& from) {
+ if (&from == this) return;
+ Clear();
+ MergeFrom(from);
+}
+
+bool Mixin::IsInitialized() const {
+
+ return true;
+}
+
+void Mixin::Swap(Mixin* other) {
+ if (other == this) return;
+ InternalSwap(other);
+}
+void Mixin::InternalSwap(Mixin* other) {
+ name_.Swap(&other->name_);
+ root_.Swap(&other->root_);
+ _internal_metadata_.Swap(&other->_internal_metadata_);
+ std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata Mixin::GetMetadata() const {
+ protobuf_AssignDescriptorsOnce();
+ ::google::protobuf::Metadata metadata;
+ metadata.descriptor = Mixin_descriptor_;
+ metadata.reflection = Mixin_reflection_;
+ return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// Mixin
+
+// optional string name = 1;
+void Mixin::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Mixin::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
+ return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
+}
+ void Mixin::set_name(const char* value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
+}
+ void Mixin::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
+}
+ ::std::string* Mixin::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Mixin::release_name() {
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
+}
+
+// optional string root = 2;
+void Mixin::clear_root() {
+ root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Mixin::root() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
+ return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_root(const ::std::string& value) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
+}
+ void Mixin::set_root(const char* value) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
+}
+ void Mixin::set_root(const char* value, size_t size) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
+}
+ ::std::string* Mixin::mutable_root() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
+ return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Mixin::release_root() {
+
+ return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Mixin::set_allocated_root(::std::string* root) {
+ if (root != NULL) {
+
+ } else {
+
+ }
+ root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h
index 985adc5d..3c5a6f31 100644
--- a/src/google/protobuf/api.pb.h
+++ b/src/google/protobuf/api.pb.h
@@ -41,6 +41,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
class Api;
class Method;
+class Mixin;
// ===================================================================
@@ -118,10 +119,10 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
const ::google::protobuf::Method& methods(int index) const;
::google::protobuf::Method* mutable_methods(int index);
::google::protobuf::Method* add_methods();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
- methods() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >*
mutable_methods();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
+ methods() const;
// repeated .google.protobuf.Option options = 3;
int options_size() const;
@@ -130,10 +131,10 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
// optional string version = 4;
void clear_version();
@@ -155,6 +156,24 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
::google::protobuf::SourceContext* release_source_context();
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
+ // repeated .google.protobuf.Mixin mixins = 6;
+ int mixins_size() const;
+ void clear_mixins();
+ static const int kMixinsFieldNumber = 6;
+ const ::google::protobuf::Mixin& mixins(int index) const;
+ ::google::protobuf::Mixin* mutable_mixins(int index);
+ ::google::protobuf::Mixin* add_mixins();
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+ mutable_mixins();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+ mixins() const;
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ void clear_syntax();
+ static const int kSyntaxFieldNumber = 7;
+ ::google::protobuf::Syntax syntax() const;
+ void set_syntax(::google::protobuf::Syntax value);
+
// @@protoc_insertion_point(class_scope:google.protobuf.Api)
private:
@@ -165,6 +184,8 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message {
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
::google::protobuf::internal::ArenaStringPtr version_;
::google::protobuf::SourceContext* source_context_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin > mixins_;
+ int syntax_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
@@ -283,10 +304,16 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
+
+ // optional .google.protobuf.Syntax syntax = 7;
+ void clear_syntax();
+ static const int kSyntaxFieldNumber = 7;
+ ::google::protobuf::Syntax syntax() const;
+ void set_syntax(::google::protobuf::Syntax value);
// @@protoc_insertion_point(class_scope:google.protobuf.Method)
private:
@@ -296,9 +323,10 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
::google::protobuf::internal::ArenaStringPtr name_;
::google::protobuf::internal::ArenaStringPtr request_type_url_;
::google::protobuf::internal::ArenaStringPtr response_type_url_;
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
bool request_streaming_;
bool response_streaming_;
+ int syntax_;
+ ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
@@ -307,6 +335,101 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message {
void InitAsDefaultInstance();
static Method* default_instance_;
};
+// -------------------------------------------------------------------
+
+class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message {
+ public:
+ Mixin();
+ virtual ~Mixin();
+
+ Mixin(const Mixin& from);
+
+ inline Mixin& operator=(const Mixin& from) {
+ CopyFrom(from);
+ return *this;
+ }
+
+ static const ::google::protobuf::Descriptor* descriptor();
+ static const Mixin& default_instance();
+
+ void Swap(Mixin* other);
+
+ // implements Message ----------------------------------------------
+
+ inline Mixin* New() const { return New(NULL); }
+
+ Mixin* New(::google::protobuf::Arena* arena) const;
+ void CopyFrom(const ::google::protobuf::Message& from);
+ void MergeFrom(const ::google::protobuf::Message& from);
+ void CopyFrom(const Mixin& from);
+ void MergeFrom(const Mixin& from);
+ void Clear();
+ bool IsInitialized() const;
+
+ int ByteSize() const;
+ bool MergePartialFromCodedStream(
+ ::google::protobuf::io::CodedInputStream* input);
+ void SerializeWithCachedSizes(
+ ::google::protobuf::io::CodedOutputStream* output) const;
+ ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+ int GetCachedSize() const { return _cached_size_; }
+ private:
+ void SharedCtor();
+ void SharedDtor();
+ void SetCachedSize(int size) const;
+ void InternalSwap(Mixin* other);
+ private:
+ inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+ return _internal_metadata_.arena();
+ }
+ inline void* MaybeArenaPtr() const {
+ return _internal_metadata_.raw_arena_ptr();
+ }
+ public:
+
+ ::google::protobuf::Metadata GetMetadata() const;
+
+ // nested types ----------------------------------------------------
+
+ // accessors -------------------------------------------------------
+
+ // optional string name = 1;
+ void clear_name();
+ static const int kNameFieldNumber = 1;
+ const ::std::string& name() const;
+ void set_name(const ::std::string& value);
+ void set_name(const char* value);
+ void set_name(const char* value, size_t size);
+ ::std::string* mutable_name();
+ ::std::string* release_name();
+ void set_allocated_name(::std::string* name);
+
+ // optional string root = 2;
+ void clear_root();
+ static const int kRootFieldNumber = 2;
+ const ::std::string& root() const;
+ void set_root(const ::std::string& value);
+ void set_root(const char* value);
+ void set_root(const char* value, size_t size);
+ ::std::string* mutable_root();
+ ::std::string* release_root();
+ void set_allocated_root(::std::string* root);
+
+ // @@protoc_insertion_point(class_scope:google.protobuf.Mixin)
+ private:
+
+ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+ bool _is_default_instance_;
+ ::google::protobuf::internal::ArenaStringPtr name_;
+ ::google::protobuf::internal::ArenaStringPtr root_;
+ mutable int _cached_size_;
+ friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fapi_2eproto();
+ friend void protobuf_AssignDesc_google_2fprotobuf_2fapi_2eproto();
+ friend void protobuf_ShutdownFile_google_2fprotobuf_2fapi_2eproto();
+
+ void InitAsDefaultInstance();
+ static Mixin* default_instance_;
+};
// ===================================================================
@@ -377,16 +500,16 @@ inline ::google::protobuf::Method* Api::add_methods() {
// @@protoc_insertion_point(field_add:google.protobuf.Api.methods)
return methods_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
-Api::methods() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
- return methods_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >*
Api::mutable_methods() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.methods)
return &methods_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Method >&
+Api::methods() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.methods)
+ return methods_;
+}
// repeated .google.protobuf.Option options = 3;
inline int Api::options_size() const {
@@ -407,16 +530,16 @@ inline ::google::protobuf::Option* Api::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Api.options)
return options_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Api::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
- return options_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Api::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.options)
return &options_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Api::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.options)
+ return options_;
+}
// optional string version = 4;
inline void Api::clear_version() {
@@ -498,6 +621,50 @@ inline void Api::set_allocated_source_context(::google::protobuf::SourceContext*
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Api.source_context)
}
+// repeated .google.protobuf.Mixin mixins = 6;
+inline int Api::mixins_size() const {
+ return mixins_.size();
+}
+inline void Api::clear_mixins() {
+ mixins_.Clear();
+}
+inline const ::google::protobuf::Mixin& Api::mixins(int index) const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.mixins)
+ return mixins_.Get(index);
+}
+inline ::google::protobuf::Mixin* Api::mutable_mixins(int index) {
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Api.mixins)
+ return mixins_.Mutable(index);
+}
+inline ::google::protobuf::Mixin* Api::add_mixins() {
+ // @@protoc_insertion_point(field_add:google.protobuf.Api.mixins)
+ return mixins_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >*
+Api::mutable_mixins() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Api.mixins)
+ return &mixins_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Mixin >&
+Api::mixins() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Api.mixins)
+ return mixins_;
+}
+
+// optional .google.protobuf.Syntax syntax = 7;
+inline void Api::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Api::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Api.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Api::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Api.syntax)
+}
+
// -------------------------------------------------------------------
// Method
@@ -678,20 +845,126 @@ inline ::google::protobuf::Option* Method::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Method.options)
return options_.Add();
}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+Method::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
+ return &options_;
+}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Method::options() const {
// @@protoc_insertion_point(field_list:google.protobuf.Method.options)
return options_;
}
-inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
-Method::mutable_options() {
- // @@protoc_insertion_point(field_mutable_list:google.protobuf.Method.options)
- return &options_;
+
+// optional .google.protobuf.Syntax syntax = 7;
+inline void Method::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Method::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Method.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Method::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Method.syntax)
+}
+
+// -------------------------------------------------------------------
+
+// Mixin
+
+// optional string name = 1;
+inline void Mixin::clear_name() {
+ name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Mixin::name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Mixin.name)
+ return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_name(const ::std::string& value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.name)
+}
+inline void Mixin::set_name(const char* value) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name)
+}
+inline void Mixin::set_name(const char* value, size_t size) {
+
+ name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.name)
+}
+inline ::std::string* Mixin::mutable_name() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.name)
+ return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Mixin::release_name() {
+
+ return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_allocated_name(::std::string* name) {
+ if (name != NULL) {
+
+ } else {
+
+ }
+ name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.name)
+}
+
+// optional string root = 2;
+inline void Mixin::clear_root() {
+ root_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Mixin::root() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Mixin.root)
+ return root_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_root(const ::std::string& value) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Mixin.root)
+}
+inline void Mixin::set_root(const char* value) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root)
+}
+inline void Mixin::set_root(const char* value, size_t size) {
+
+ root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Mixin.root)
+}
+inline ::std::string* Mixin::mutable_root() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Mixin.root)
+ return root_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Mixin::release_root() {
+
+ return root_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Mixin::set_allocated_root(::std::string* root) {
+ if (root != NULL) {
+
+ } else {
+
+ }
+ root_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), root);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Mixin.root)
}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
+// -------------------------------------------------------------------
+
// @@protoc_insertion_point(namespace_scope)
diff --git a/src/google/protobuf/api.proto b/src/google/protobuf/api.proto
index d6c2a8b3..597a6497 100644
--- a/src/google/protobuf/api.proto
+++ b/src/google/protobuf/api.proto
@@ -34,15 +34,16 @@ package google.protobuf;
import "google/protobuf/source_context.proto";
import "google/protobuf/type.proto";
-option java_multiple_files = true;
-option java_outer_classname = "ApiProto";
option java_package = "com.google.protobuf";
+option java_outer_classname = "ApiProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// Api is a light-weight descriptor for a protocol buffer service.
message Api {
+
// The fully qualified name of this api, including package name
// followed by the api's simple name.
string name = 1;
@@ -74,18 +75,22 @@ message Api {
// be omitted. Zero major versions must only be used for
// experimental, none-GA apis.
//
- // See also: [design doc](http://go/api-versioning).
- //
- //
string version = 4;
// Source context for the protocol buffer service represented by this
// message.
SourceContext source_context = 5;
+
+ // Included APIs. See [Mixin][].
+ repeated Mixin mixins = 6;
+
+ // The source syntax of the service.
+ Syntax syntax = 7;
}
// Method represents a method of an api.
message Method {
+
// The simple name of this method.
string name = 1;
@@ -103,4 +108,94 @@ message Method {
// Any metadata attached to the method.
repeated Option options = 6;
+
+ // The source syntax of this method.
+ Syntax syntax = 7;
+}
+
+// Declares an API to be included in this API. The including API must
+// redeclare all the methods from the included API, but documentation
+// and options are inherited as follows:
+//
+// - If after comment and whitespace stripping, the documentation
+// string of the redeclared method is empty, it will be inherited
+// from the original method.
+//
+// - Each annotation belonging to the service config (http,
+// visibility) which is not set in the redeclared method will be
+// inherited.
+//
+// - If an http annotation is inherited, the path pattern will be
+// modified as follows. Any version prefix will be replaced by the
+// version of the including API plus the [root][] path if specified.
+//
+// Example of a simple mixin:
+//
+// package google.acl.v1;
+// service AccessControl {
+// // Get the underlying ACL object.
+// rpc GetAcl(GetAclRequest) returns (Acl) {
+// option (google.api.http).get = "/v1/{resource=**}:getAcl";
+// }
+// }
+//
+// package google.storage.v2;
+// service Storage {
+// // (-- see AccessControl.GetAcl --)
+// rpc GetAcl(GetAclRequest) returns (Acl);
+//
+// // Get a data record.
+// rpc GetData(GetDataRequest) returns (Data) {
+// option (google.api.http).get = "/v2/{resource=**}";
+// }
+// }
+//
+// Example of a mixin configuration:
+//
+// apis:
+// - name: google.storage.v2.Storage
+// mixins:
+// - name: google.acl.v1.AccessControl
+//
+// The mixin construct implies that all methods in `AccessControl` are
+// also declared with same name and request/response types in
+// `Storage`. A documentation generator or annotation processor will
+// see the effective `Storage.GetAcl` method after inherting
+// documentation and annotations as follows:
+//
+// service Storage {
+// // Get the underlying ACL object.
+// rpc GetAcl(GetAclRequest) returns (Acl) {
+// option (google.api.http).get = "/v2/{resource=**}:getAcl";
+// }
+// ...
+// }
+//
+// Note how the version in the path pattern changed from `v1` to `v2`.
+//
+// If the `root` field in the mixin is specified, it should be a
+// relative path under which inherited HTTP paths are placed. Example:
+//
+// apis:
+// - name: google.storage.v2.Storage
+// mixins:
+// - name: google.acl.v1.AccessControl
+// root: acls
+//
+// This implies the following inherited HTTP annotation:
+//
+// service Storage {
+// // Get the underlying ACL object.
+// rpc GetAcl(GetAclRequest) returns (Acl) {
+// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
+// }
+// ...
+// }
+message Mixin {
+ // The fully qualified name of the API which is included.
+ string name = 1;
+
+ // If non-empty specifies a path under which inherited HTTP paths
+ // are rooted.
+ string root = 2;
}
diff --git a/src/google/protobuf/arena.cc b/src/google/protobuf/arena.cc
index ed1c5ef2..907a6a20 100755
--- a/src/google/protobuf/arena.cc
+++ b/src/google/protobuf/arena.cc
@@ -66,8 +66,12 @@ void Arena::Init() {
first_block->size = options_.initial_block_size;
first_block->pos = kHeaderSize;
first_block->next = NULL;
- first_block->owner = &first_block->owner;
- AddBlock(first_block);
+ // Thread which calls Init() owns the first block. This allows the
+ // single-threaded case to allocate on the first block without taking any
+ // locks.
+ first_block->owner = &thread_cache();
+ SetThreadCacheBlock(first_block);
+ AddBlockInternal(first_block);
owns_first_block_ = false;
}
@@ -80,7 +84,7 @@ void Arena::Init() {
}
Arena::~Arena() {
- uint64 space_allocated = Reset();
+ uint64 space_allocated = ResetInternal();
// Call the destruction hook
if (options_.on_arena_destruction != NULL) {
@@ -89,10 +93,14 @@ Arena::~Arena() {
}
uint64 Arena::Reset() {
- CleanupList();
- uint64 space_allocated = FreeBlocks();
// Invalidate any ThreadCaches pointing to any blocks we just destroyed.
lifecycle_id_ = lifecycle_id_generator_.GetNext();
+ return ResetInternal();
+}
+
+uint64 Arena::ResetInternal() {
+ CleanupList();
+ uint64 space_allocated = FreeBlocks();
// Call the reset hook
if (options_.on_arena_reset != NULL) {
@@ -137,6 +145,10 @@ Arena::Block* Arena::NewBlock(void* me, Block* my_last_block, size_t n,
void Arena::AddBlock(Block* b) {
MutexLock l(&blocks_lock_);
+ AddBlockInternal(b);
+}
+
+void Arena::AddBlockInternal(Block* b) {
b->next = reinterpret_cast<Block*>(google::protobuf::internal::NoBarrier_Load(&blocks_));
google::protobuf::internal::Release_Store(&blocks_, reinterpret_cast<google::protobuf::internal::AtomicWord>(b));
if (b->avail() != 0) {
@@ -181,16 +193,6 @@ void* Arena::AllocateAligned(const std::type_info* allocated, size_t n) {
void* me = &thread_cache();
Block* b = reinterpret_cast<Block*>(google::protobuf::internal::Acquire_Load(&hint_));
if (!b || b->owner != me || b->avail() < n) {
- // If the next block to allocate from is the first block, try to claim it
- // for this thread.
- if (!owns_first_block_ && b->next == NULL) {
- MutexLock l(&blocks_lock_);
- if (b->owner == &b->owner && b->avail() >= n) {
- b->owner = me;
- SetThreadCacheBlock(b);
- return AllocFromBlock(b, n);
- }
- }
return SlowAlloc(n);
}
return AllocFromBlock(b, n);
@@ -267,8 +269,12 @@ uint64 Arena::FreeBlocks() {
// Make the first block that was passed in through ArenaOptions
// available for reuse.
first_block->pos = kHeaderSize;
- first_block->owner = &first_block->owner;
- AddBlock(first_block);
+ // Thread which calls Reset() owns the first block. This allows the
+ // single-threaded case to allocate on the first block without taking any
+ // locks.
+ first_block->owner = &thread_cache();
+ SetThreadCacheBlock(first_block);
+ AddBlockInternal(first_block);
}
return space_allocated;
}
diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h
index e7e693b2..074a9e54 100644
--- a/src/google/protobuf/arena.h
+++ b/src/google/protobuf/arena.h
@@ -31,6 +31,10 @@
#ifndef GOOGLE_PROTOBUF_ARENA_H__
#define GOOGLE_PROTOBUF_ARENA_H__
+#include <limits>
+#ifdef max
+#undef max // Visual Studio defines this macro
+#endif
#if __cplusplus >= 201103L
#include <google/protobuf/stubs/type_traits.h>
#endif
@@ -39,7 +43,8 @@
#include <google/protobuf/stubs/atomic_sequence_num.h>
#include <google/protobuf/stubs/atomicops.h>
#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/platform_macros.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/type_traits.h>
namespace google {
@@ -414,6 +419,9 @@ class LIBPROTOBUF_EXPORT Arena {
// trivially destructible.
template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
static T* CreateArray(::google::protobuf::Arena* arena, size_t num_elements) {
+ GOOGLE_CHECK_LE(num_elements,
+ std::numeric_limits<size_t>::max() / sizeof(T))
+ << "Requested size is too large to fit into size_t.";
if (arena == NULL) {
return static_cast<T*>(::operator new[](num_elements * sizeof(T)));
} else {
@@ -459,7 +467,8 @@ class LIBPROTOBUF_EXPORT Arena {
// will be manually called when the arena is destroyed or reset. This differs
// from OwnDestructor() in that any member function may be specified, not only
// the class destructor.
- GOOGLE_ATTRIBUTE_NOINLINE void OwnCustomDestructor(void* object, void (*destruct)(void*)) {
+ GOOGLE_ATTRIBUTE_NOINLINE void OwnCustomDestructor(void* object,
+ void (*destruct)(void*)) {
AddListNode(object, destruct);
}
@@ -468,7 +477,7 @@ class LIBPROTOBUF_EXPORT Arena {
// latter is a virtual call, while this method is a templated call that
// resolves at compile-time.
template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- static inline ::google::protobuf::Arena* GetArena(const T* value) {
+ static ::google::protobuf::Arena* GetArena(const T* value) {
return GetArenaInternal(value, static_cast<T*>(0));
}
@@ -506,7 +515,7 @@ class LIBPROTOBUF_EXPORT Arena {
// aligned at a multiple of 8 bytes.
size_t pos;
size_t size; // total size of the block.
- size_t avail() const GOOGLE_ATTRIBUTE_ALWAYS_INLINE { return size - pos; }
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE size_t avail() const { return size - pos; }
// data follows
};
@@ -554,6 +563,33 @@ class LIBPROTOBUF_EXPORT Arena {
return google::protobuf::internal::has_trivial_destructor<T>::value;
}
+ // Helper typetrait that indicates whether the desctructor of type T should be
+ // called when arena is destroyed at compile time. This is only to allow
+ // construction of higher-level templated utilities.
+ // is_destructor_skippable<T>::value is an instance of google::protobuf::internal::true_type if the
+ // destructor of the message type T should not be called when arena is
+ // destroyed or google::protobuf::internal::has_trivial_destructor<T>::value == true, and
+ // google::protobuf::internal::false_type otherwise.
+ //
+ // This is inside Arena because only Arena has the friend relationships
+ // necessary to see the underlying generated code traits.
+ template<typename T>
+ struct is_destructor_skippable {
+ template<typename U>
+ static char DestructorSkippable(
+ const typename U::DestructorSkippable_*);
+ template<typename U>
+ static double DestructorSkippable(...);
+
+ // This will resolve to either google::protobuf::internal::true_type or google::protobuf::internal::false_type.
+ typedef google::protobuf::internal::integral_constant<bool,
+ sizeof(DestructorSkippable<const T>(static_cast<const T*>(0))) ==
+ sizeof(char) || google::protobuf::internal::has_trivial_destructor<T>::value == true>
+ type;
+ static const type value;
+ };
+
+
// CreateMessage<T> requires that T supports arenas, but this private method
// works whether or not T supports arenas. These are not exposed to user code
// as it can cause confusing API usages, and end up having double free in
@@ -573,14 +609,16 @@ class LIBPROTOBUF_EXPORT Arena {
// Just allocate the required size for the given type assuming the
// type has a trivial constructor.
template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateInternalRawArray(size_t num_elements) {
+ T* CreateInternalRawArray(size_t num_elements) {
+ GOOGLE_CHECK_LE(num_elements,
+ std::numeric_limits<size_t>::max() / sizeof(T))
+ << "Requested size is too large to fit into size_t.";
return static_cast<T*>(
AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements));
}
template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateInternal(
- bool skip_explicit_ownership) {
+ T* CreateInternal(bool skip_explicit_ownership) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T();
if (!skip_explicit_ownership) {
AddListNode(t, &internal::arena_destruct_object<T>);
@@ -589,8 +627,7 @@ class LIBPROTOBUF_EXPORT Arena {
}
template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateInternal(
- bool skip_explicit_ownership, const Arg& arg) {
+ T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg);
if (!skip_explicit_ownership) {
AddListNode(t, &internal::arena_destruct_object<T>);
@@ -599,7 +636,7 @@ class LIBPROTOBUF_EXPORT Arena {
}
template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateInternal(
+ T* CreateInternal(
bool skip_explicit_ownership, const Arg1& arg1, const Arg2& arg2) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg1, arg2);
if (!skip_explicit_ownership) {
@@ -609,10 +646,10 @@ class LIBPROTOBUF_EXPORT Arena {
}
template <typename T, typename Arg1, typename Arg2, typename Arg3>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3);
if (!skip_explicit_ownership) {
@@ -623,11 +660,11 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3,
- const Arg4& arg4) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3, arg4);
if (!skip_explicit_ownership) {
@@ -638,12 +675,12 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4, typename Arg5>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3,
- const Arg4& arg4,
- const Arg5& arg5) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3, arg4, arg5);
if (!skip_explicit_ownership) {
@@ -654,13 +691,13 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4, typename Arg5, typename Arg6>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3,
- const Arg4& arg4,
- const Arg5& arg5,
- const Arg6& arg6) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5,
+ const Arg6& arg6) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3, arg4, arg5, arg6);
if (!skip_explicit_ownership) {
@@ -671,14 +708,14 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4, typename Arg5, typename Arg6, typename Arg7>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3,
- const Arg4& arg4,
- const Arg5& arg5,
- const Arg6& arg6,
- const Arg7& arg7) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5,
+ const Arg6& arg6,
+ const Arg7& arg7) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3, arg4, arg5, arg6, arg7);
if (!skip_explicit_ownership) {
@@ -690,15 +727,15 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T, typename Arg1, typename Arg2, typename Arg3,
typename Arg4, typename Arg5, typename Arg6, typename Arg7,
typename Arg8>
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline T* CreateInternal(bool skip_explicit_ownership,
- const Arg1& arg1,
- const Arg2& arg2,
- const Arg3& arg3,
- const Arg4& arg4,
- const Arg5& arg5,
- const Arg6& arg6,
- const Arg7& arg7,
- const Arg8& arg8) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal(bool skip_explicit_ownership,
+ const Arg1& arg1,
+ const Arg2& arg2,
+ const Arg3& arg3,
+ const Arg4& arg4,
+ const Arg5& arg5,
+ const Arg6& arg6,
+ const Arg7& arg7,
+ const Arg8& arg8) {
T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T)))
T(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if (!skip_explicit_ownership) {
@@ -708,21 +745,21 @@ class LIBPROTOBUF_EXPORT Arena {
}
template <typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
+ T* CreateMessageInternal(typename T::InternalArenaConstructable_*) {
return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
this);
}
template <typename T, typename Arg> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
- const Arg& arg) {
+ T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
+ const Arg& arg) {
return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
this, arg);
}
template <typename T, typename Arg1, typename Arg2> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- inline T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
- const Arg1& arg1, const Arg2& arg2) {
+ T* CreateMessageInternal(typename T::InternalArenaConstructable_*,
+ const Arg1& arg1, const Arg2& arg2) {
return CreateInternal<T, Arena*>(SkipDeleteList<T>(static_cast<T*>(0)),
this, arg1, arg2);
}
@@ -733,19 +770,29 @@ class LIBPROTOBUF_EXPORT Arena {
template <typename T>
static void CreateInArenaStorage(T* ptr, Arena* arena) {
CreateInArenaStorageInternal(ptr, arena, is_arena_constructable<T>::value);
+ RegisterDestructorInternal(ptr, arena, is_destructor_skippable<T>::value);
}
+
template <typename T>
static void CreateInArenaStorageInternal(
T* ptr, Arena* arena, google::protobuf::internal::true_type) {
new (ptr) T(arena);
}
-
template <typename T>
static void CreateInArenaStorageInternal(
T* ptr, Arena* arena, google::protobuf::internal::false_type) {
new (ptr) T;
}
+ template <typename T>
+ static void RegisterDestructorInternal(
+ T* ptr, Arena* arena, google::protobuf::internal::true_type) {}
+ template <typename T>
+ static void RegisterDestructorInternal(
+ T* ptr, Arena* arena, google::protobuf::internal::false_type) {
+ arena->OwnDestructor(ptr);
+ }
+
// These implement Own(), which registers an object for deletion (destructor
// call and operator delete()). The second parameter has type 'true_type' if T
// is a subtype of ::google::protobuf::Message and 'false_type' otherwise. Collapsing
@@ -768,13 +815,13 @@ class LIBPROTOBUF_EXPORT Arena {
// InternalArenaConstructable_ tags can be associated with an arena, and such
// objects must implement a GetArenaNoVirtual() method.
template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- static inline ::google::protobuf::Arena* GetArenaInternal(const T* value,
- typename T::InternalArenaConstructable_*) {
+ static ::google::protobuf::Arena* GetArenaInternal(
+ const T* value, typename T::InternalArenaConstructable_*) {
return value->GetArenaNoVirtual();
}
template<typename T> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
- static inline ::google::protobuf::Arena* GetArenaInternal(const T* value, ...) {
+ static ::google::protobuf::Arena* GetArenaInternal(const T* value, ...) {
return NULL;
}
@@ -784,7 +831,7 @@ class LIBPROTOBUF_EXPORT Arena {
void* AllocateAligned(const std::type_info* allocated, size_t n);
// Allocate an internal allocation, avoiding optional typed monitoring.
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE inline void* AllocateAligned(size_t n) {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* AllocateAligned(size_t n) {
return AllocateAligned(NULL, n);
}
@@ -802,6 +849,7 @@ class LIBPROTOBUF_EXPORT Arena {
void AddListNode(void* elem, void (*cleanup)(void*));
// Delete or Destruct all objects owned by the arena.
void CleanupList();
+ uint64 ResetInternal();
inline void SetThreadCacheBlock(Block* block) {
thread_cache().last_block_used_ = block;
@@ -828,6 +876,9 @@ class LIBPROTOBUF_EXPORT Arena {
Mutex blocks_lock_;
void AddBlock(Block* b);
+ // Access must be synchronized, either by blocks_lock_ or by being called from
+ // Init()/Reset().
+ void AddBlockInternal(Block* b);
void* SlowAlloc(size_t n);
Block* FindBlock(void* me);
Block* NewBlock(void* me, Block* my_last_block, size_t n,
@@ -853,6 +904,11 @@ const typename Arena::is_arena_constructable<T>::type
Arena::is_arena_constructable<T>::value =
typename Arena::is_arena_constructable<T>::type();
+template<typename T>
+const typename Arena::is_destructor_skippable<T>::type
+ Arena::is_destructor_skippable<T>::value =
+ typename Arena::is_destructor_skippable<T>::type();
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/arena_test_util.cc b/src/google/protobuf/arena_test_util.cc
index 21f55c6e..df9c5bd6 100644
--- a/src/google/protobuf/arena_test_util.cc
+++ b/src/google/protobuf/arena_test_util.cc
@@ -28,6 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena_test_util.h>
diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc
index 6c185695..c9ca1fd1 100644
--- a/src/google/protobuf/arena_unittest.cc
+++ b/src/google/protobuf/arena_unittest.cc
@@ -40,7 +40,9 @@
#include <typeinfo>
#include <vector>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/arena_test_util.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
@@ -619,8 +621,6 @@ TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
}
}
-// N.B.: no reflection version of this test because all the arena-specific code
-// is in RepeatedPtrField, and the reflection works implicitly based on that.
TEST(ArenaTest, AddAllocatedToRepeatedField) {
// Heap->arena case.
Arena arena1;
@@ -680,6 +680,55 @@ TEST(ArenaTest, AddAllocatedToRepeatedField) {
}
}
+TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
+ // Heap->arena case.
+ Arena arena1;
+ TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
+ const Reflection* r = arena1_message->GetReflection();
+ const Descriptor* d = arena1_message->GetDescriptor();
+ const FieldDescriptor* fd =
+ d->FindFieldByName("repeated_nested_message");
+ for (int i = 0; i < 10; i++) {
+ TestAllTypes::NestedMessage* heap_submessage =
+ new TestAllTypes::NestedMessage;
+ heap_submessage->set_bb(42);
+ r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
+ // Should not copy object -- will use arena_->Own().
+ EXPECT_EQ(heap_submessage,
+ &arena1_message->repeated_nested_message(i));
+ EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
+ }
+
+ // Arena1->Arena2 case.
+ arena1_message->Clear();
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
+ // Should copy object.
+ EXPECT_NE(arena2_submessage,
+ &arena1_message->repeated_nested_message(i));
+ EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
+ }
+
+ // Arena->heap case.
+ TestAllTypes* heap_message = new TestAllTypes;
+ for (int i = 0; i < 10; i++) {
+ Arena arena2;
+ TestAllTypes::NestedMessage* arena2_submessage =
+ Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
+ arena2_submessage->set_bb(42);
+ r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
+ // Should copy object.
+ EXPECT_NE(arena2_submessage,
+ &heap_message->repeated_nested_message(i));
+ EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
+ }
+ delete heap_message;
+}
+
TEST(ArenaTest, ReleaseLastRepeatedField) {
// Release from arena-allocated repeated field and ensure that returned object
// is heap-allocated.
@@ -1230,7 +1279,7 @@ TEST(ArenaTest, ArenaHooksSanity) {
EXPECT_EQ(1, ArenaHooksTestUtil::num_init);
EXPECT_EQ(0, ArenaHooksTestUtil::num_allocations);
::google::protobuf::Arena::Create<uint64>(&arena);
- if (::google::protobuf::internal::has_trivial_destructor<uint64>::value) {
+ if (google::protobuf::internal::has_trivial_destructor<uint64>::value) {
EXPECT_EQ(1, ArenaHooksTestUtil::num_allocations);
} else {
EXPECT_EQ(2, ArenaHooksTestUtil::num_allocations);
diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h
index 7bbf6c76..1dacdc68 100755
--- a/src/google/protobuf/arenastring.h
+++ b/src/google/protobuf/arenastring.h
@@ -33,6 +33,7 @@
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/fastmem.h>
@@ -145,7 +146,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
// Swaps internal pointers. Arena-safety semantics: this is guarded by the
// logic in Swap()/UnsafeArenaSwap() at the message level, so this method is
// 'unsafe' if called directly.
- inline void Swap(ArenaStringPtr* other) GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(ArenaStringPtr* other) {
std::swap(ptr_, other->ptr_);
}
@@ -283,9 +284,8 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
private:
::std::string* ptr_;
- GOOGLE_ATTRIBUTE_NOINLINE
- inline void CreateInstance(::google::protobuf::Arena* arena,
- const ::std::string* initial_value) {
+ GOOGLE_ATTRIBUTE_NOINLINE void CreateInstance(::google::protobuf::Arena* arena,
+ const ::std::string* initial_value) {
// Assumes ptr_ is not NULL.
if (initial_value != NULL) {
ptr_ = new ::std::string(*initial_value);
@@ -296,9 +296,7 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr {
arena->Own(ptr_);
}
}
-
- GOOGLE_ATTRIBUTE_NOINLINE
- inline void CreateInstanceNoArena(const ::std::string* initial_value) {
+ GOOGLE_ATTRIBUTE_NOINLINE void CreateInstanceNoArena(const ::std::string* initial_value) {
if (initial_value != NULL) {
ptr_ = new ::std::string(*initial_value);
} else {
diff --git a/src/google/protobuf/arenastring_unittest.cc b/src/google/protobuf/arenastring_unittest.cc
index 8ebd4b9c..3fb582be 100644
--- a/src/google/protobuf/arenastring_unittest.cc
+++ b/src/google/protobuf/arenastring_unittest.cc
@@ -42,6 +42,7 @@
#endif
#include <cstdlib>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/compiler/code_generator.cc b/src/google/protobuf/compiler/code_generator.cc
index 0039b00a..473eb4e6 100644
--- a/src/google/protobuf/compiler/code_generator.cc
+++ b/src/google/protobuf/compiler/code_generator.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index e8871861..26a4f0b0 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -70,6 +70,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/map_util.h>
@@ -1657,7 +1658,11 @@ bool CommandLineInterface::WriteDescriptorSet(
&already_seen, file_set.mutable_file());
}
} else {
+ set<const FileDescriptor*> already_seen;
for (int i = 0; i < parsed_files.size(); i++) {
+ if (!already_seen.insert(parsed_files[i]).second) {
+ continue;
+ }
FileDescriptorProto* file_proto = file_set.add_file();
parsed_files[i]->CopyTo(file_proto);
if (source_info_in_descriptor_set_) {
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index e5b77c33..9560d0e0 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -63,13 +63,13 @@
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
+namespace google {
+namespace protobuf {
+namespace compiler {
// Disable the whole test when we use tcmalloc for "draconian" heap checks, in
// which case tcmalloc will print warnings that fail the plugin tests.
#if !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
-namespace google {
-namespace protobuf {
-namespace compiler {
#if defined(_WIN32)
#ifndef STDIN_FILENO
@@ -886,6 +886,39 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSet) {
EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
}
+TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) {
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "message Foo {}\n");
+ CreateTempFile("bar.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Bar {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+ CreateTempFile("baz.proto",
+ "syntax = \"proto2\";\n"
+ "import \"foo.proto\";\n"
+ "message Baz {\n"
+ " optional Foo foo = 1;\n"
+ "}\n");
+
+ Run("protocol_compiler --descriptor_set_out=$tmpdir/descriptor_set "
+ "--proto_path=$tmpdir bar.proto foo.proto bar.proto baz.proto");
+
+ ExpectNoErrors();
+
+ FileDescriptorSet descriptor_set;
+ ReadDescriptorSet("descriptor_set", &descriptor_set);
+ if (HasFatalFailure()) return;
+ EXPECT_EQ(3, descriptor_set.file_size());
+ EXPECT_EQ("bar.proto", descriptor_set.file(0).name());
+ EXPECT_EQ("foo.proto", descriptor_set.file(1).name());
+ EXPECT_EQ("baz.proto", descriptor_set.file(2).name());
+ // Descriptor set should not have source code info.
+ EXPECT_FALSE(descriptor_set.file(0).has_source_code_info());
+}
+
TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) {
CreateTempFile("foo.proto",
"syntax = \"proto2\";\n"
@@ -1767,8 +1800,8 @@ TEST_F(EncodeDecodeTest, ProtoParseError) {
} // anonymous namespace
+#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
+
} // namespace compiler
} // namespace protobuf
-
-#endif // !GOOGLE_PROTOBUF_HEAP_CHECK_DRACONIAN
} // namespace google
diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
index 13ed0b64..c3e9fe74 100644
--- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc
@@ -133,8 +133,7 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) {
CppGenerator generator;
MockGeneratorContext context;
string error;
- string parameter;
- parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
+ string parameter = "dllexport_decl=LIBPROTOBUF_EXPORT";
ASSERT_TRUE(generator.Generate(proto_file, parameter,
&context, &error));
parameter = "dllexport_decl=LIBPROTOC_EXPORT";
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.cc b/src/google/protobuf/compiler/cpp/cpp_enum.cc
index 70d3a600..de4d7cc7 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.cc
@@ -32,7 +32,6 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
-#include <set>
#include <map>
#include <google/protobuf/compiler/cpp/cpp_enum.h>
@@ -70,14 +69,11 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor,
EnumGenerator::~EnumGenerator() {}
-void EnumGenerator::GenerateForwardDeclaration(io::Printer* printer) {
+void EnumGenerator::FillForwardDeclaration(set<string>* enum_names) {
if (!options_.proto_h) {
return;
}
- map<string, string> vars;
- vars["classname"] = classname_;
- printer->Print(vars, "enum $classname$ : int;\n");
- printer->Print(vars, "bool $classname$_IsValid(int value);\n");
+ enum_names->insert(classname_);
}
void EnumGenerator::GenerateDefinition(io::Printer* printer) {
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum.h b/src/google/protobuf/compiler/cpp/cpp_enum.h
index 3e930856..f3aa72e4 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum.h
+++ b/src/google/protobuf/compiler/cpp/cpp_enum.h
@@ -35,6 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
#define GOOGLE_PROTOBUF_COMPILER_CPP_ENUM_H__
+#include <set>
#include <string>
#include <google/protobuf/compiler/cpp/cpp_options.h>
#include <google/protobuf/descriptor.h>
@@ -60,11 +61,11 @@ class EnumGenerator {
// Header stuff.
- // Generate header code to forward-declare the enum. This is for use when
+ // Fills the name to use when declaring the enum. This is for use when
// generating other .proto.h files. This code should be placed within the
// enum's package namespace, but NOT within any class, even for nested
// enums.
- void GenerateForwardDeclaration(io::Printer* printer);
+ void FillForwardDeclaration(set<string>* enum_names);
// Generate header code defining the enum. This code should be placed
// within the enum's package namespace, but NOT within any class, even for
diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
index 965327b1..824e2205 100644
--- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc
@@ -35,7 +35,6 @@
#include <google/protobuf/compiler/cpp/cpp_enum_field.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc
index 43df1d88..8d47d4e0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_field.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 1f0a8205..5dae4cdd 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/compiler/cpp/cpp_file.h>
+#include <map>
#include <memory>
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
@@ -93,22 +94,36 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options)
FileGenerator::~FileGenerator() {}
-void FileGenerator::GenerateHeader(io::Printer* printer) {
- GenerateTopHeaderGuard(printer);
+void FileGenerator::GenerateProtoHeader(io::Printer* printer) {
+ if (!options_.proto_h) {
+ return;
+ }
+
+ string filename_identifier = FilenameIdentifier(file_->name());
+ GenerateTopHeaderGuard(printer, filename_identifier);
+
GenerateLibraryIncludes(printer);
- GenerateDependencyIncludes(printer);
+
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ const FileDescriptor* dep = file_->public_dependency(i);
+ const char* extension = ".proto.h";
+ string dependency = StripProto(dep->name()) + extension;
+ printer->Print(
+ "#include \"$dependency$\" // IWYU pragma: export\n",
+ "dependency", dependency);
+ }
printer->Print(
"// @@protoc_insertion_point(includes)\n");
+ GenerateForwardDeclarations(printer);
// Open namespace.
GenerateNamespaceOpeners(printer);
GenerateGlobalStateFunctionDeclarations(printer);
- GenerateMessageForwardDeclarations(printer);
printer->Print("\n");
@@ -133,6 +148,11 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
GenerateInlineFunctionDefinitions(printer);
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n"
+ "\n");
+
// Close up namespace.
GenerateNamespaceClosers(printer);
@@ -144,19 +164,89 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
"// @@protoc_insertion_point(global_scope)\n"
"\n");
- GenerateBottomHeaderGuard(printer);
+ GenerateBottomHeaderGuard(printer, filename_identifier);
+}
+
+void FileGenerator::GeneratePBHeader(io::Printer* printer) {
+ string filename_identifier =
+ FilenameIdentifier(file_->name() + (options_.proto_h ? ".pb.h" : ""));
+ GenerateTopHeaderGuard(printer, filename_identifier);
+
+ if (options_.proto_h) {
+ printer->Print("#include \"$basename$.proto.h\" // IWYU pragma: export\n",
+ "basename", StripProto(file_->name()));
+ } else {
+ GenerateLibraryIncludes(printer);
+ }
+ GenerateDependencyIncludes(printer);
+
+ printer->Print(
+ "// @@protoc_insertion_point(includes)\n");
+
+
+
+ // Open namespace.
+ GenerateNamespaceOpeners(printer);
+
+ if (!options_.proto_h) {
+ GenerateGlobalStateFunctionDeclarations(printer);
+ GenerateMessageForwardDeclarations(printer);
+
+ printer->Print("\n");
+
+ GenerateEnumDefinitions(printer);
+
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ GenerateMessageDefinitions(printer);
+
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ GenerateServiceDefinitions(printer);
+
+ GenerateExtensionIdentifiers(printer);
+
+ printer->Print("\n");
+ printer->Print(kThickSeparator);
+ printer->Print("\n");
+
+ GenerateInlineFunctionDefinitions(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(namespace_scope)\n");
+
+ // Close up namespace.
+ GenerateNamespaceClosers(printer);
+
+ if (!options_.proto_h) {
+ // We need to specialize some templates in the ::google::protobuf namespace:
+ GenerateProto2NamespaceEnumSpecializations(printer);
+ }
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(global_scope)\n"
+ "\n");
+
+ GenerateBottomHeaderGuard(printer, filename_identifier);
}
void FileGenerator::GenerateSource(io::Printer* printer) {
+ string header =
+ StripProto(file_->name()) + (options_.proto_h ? ".proto.h" : ".pb.h");
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// source: $filename$\n"
"\n"
-
// The generated code calls accessors that might be deprecated. We don't
// want the compiler to warn in generated code.
"#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION\n"
- "#include \"$basename$.pb.h\"\n"
+ "#include \"$header$\"\n"
"\n"
"#include <algorithm>\n" // for swap()
"\n"
@@ -165,7 +255,7 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"#include <google/protobuf/io/coded_stream.h>\n"
"#include <google/protobuf/wire_format_lite_inl.h>\n",
"filename", file_->name(),
- "basename", StripProto(file_->name()));
+ "header", header);
// Unknown fields implementation in lite mode uses StringOutputStream
if (!UseUnknownFieldSet(file_) && file_->message_type_count() > 0) {
@@ -181,6 +271,18 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"#include <google/protobuf/wire_format.h>\n");
}
+ if (options_.proto_h) {
+ // Use the smaller .proto.h files.
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ const FileDescriptor* dep = file_->dependency(i);
+ const char* extension = ".proto.h";
+ string dependency = StripProto(dep->name()) + extension;
+ printer->Print(
+ "#include \"$dependency$\"\n",
+ "dependency", dependency);
+ }
+ }
+
printer->Print(
"// @@protoc_insertion_point(includes)\n");
@@ -276,6 +378,59 @@ void FileGenerator::GenerateSource(io::Printer* printer) {
"// @@protoc_insertion_point(global_scope)\n");
}
+class FileGenerator::ForwardDeclarations {
+ public:
+ ~ForwardDeclarations() {
+ for (map<string, ForwardDeclarations *>::iterator it = namespaces_.begin(),
+ end = namespaces_.end();
+ it != end; ++it) {
+ delete it->second;
+ }
+ namespaces_.clear();
+ }
+
+ ForwardDeclarations* AddOrGetNamespace(const string& ns_name) {
+ ForwardDeclarations*& ns = namespaces_[ns_name];
+ if (ns == NULL) {
+ ns = new ForwardDeclarations;
+ }
+ return ns;
+ }
+
+ set<string>& classes() { return classes_; }
+ set<string>& enums() { return enums_; }
+
+ void Print(io::Printer* printer) const {
+ for (set<string>::const_iterator it = enums_.begin(), end = enums_.end();
+ it != end; ++it) {
+ printer->Print("enum $enumname$ : int;\n"
+ "bool $enumname$_IsValid(int value);\n",
+ "enumname", it->c_str());
+ }
+ for (set<string>::const_iterator it = classes_.begin(),
+ end = classes_.end();
+ it != end; ++it) {
+ printer->Print("class $classname$;\n", "classname", it->c_str());
+ }
+ for (map<string, ForwardDeclarations *>::const_iterator
+ it = namespaces_.begin(),
+ end = namespaces_.end();
+ it != end; ++it) {
+ printer->Print("namespace $nsname$ {\n",
+ "nsname", it->first);
+ it->second->Print(printer);
+ printer->Print("} // namespace $nsname$\n",
+ "nsname", it->first);
+ }
+ }
+
+
+ private:
+ map<string, ForwardDeclarations*> namespaces_;
+ set<string> classes_;
+ set<string> enums_;
+};
+
void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
// AddDescriptors() is a file-level procedure which adds the encoded
// FileDescriptorProto for this .proto file to the global DescriptorPool for
@@ -434,12 +589,17 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
string file_data;
file_proto.SerializeToString(&file_data);
+#ifdef _MSC_VER
+ bool breakdown_large_file = true;
+#else
+ bool breakdown_large_file = false;
+#endif
// Workaround for MSVC: "Error C1091: compiler limit: string exceeds 65535
// bytes in length". Declare a static array of characters rather than use a
// string literal.
- if (file_data.size() > 65535) {
+ if (breakdown_large_file && file_data.size() > 65535) {
printer->Print(
- "static const char descriptor[] = {\n");
+ "static const char descriptor[] = {\n");
printer->Indent();
// Only write 25 bytes per line.
@@ -447,26 +607,25 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
for (int i = 0; i < file_data.size();) {
for (int j = 0; j < kBytesPerLine && i < file_data.size(); ++i, ++j) {
printer->Print(
- "$char$, ",
- "char", SimpleItoa(file_data[i]));
+ "$char$, ",
+ "char", SimpleItoa(file_data[i]));
}
printer->Print(
- "\n");
+ "\n");
}
printer->Outdent();
printer->Print(
- "};\n");
+ "};\n");
printer->Print(
- "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
- "size", SimpleItoa(file_data.size()));
+ "::google::protobuf::DescriptorPool::InternalAddGeneratedFile(descriptor, $size$);\n",
+ "size", SimpleItoa(file_data.size()));
} else {
-
printer->Print(
"::google::protobuf::DescriptorPool::InternalAddGeneratedFile(");
-
+
// Only write 40 bytes per line.
static const int kBytesPerLine = 40;
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
@@ -474,11 +633,10 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
"data",
EscapeTrigraphs(
CEscape(file_data.substr(i, kBytesPerLine))));
- }
- printer->Print(
- ", $size$);\n",
+ }
+ printer->Print(
+ ", $size$);\n",
"size", SimpleItoa(file_data.size()));
-
}
// Call MessageFactory::InternalRegisterGeneratedFile().
@@ -548,8 +706,40 @@ void FileGenerator::GenerateNamespaceClosers(io::Printer* printer) {
}
}
-void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer) {
- string filename_identifier = FilenameIdentifier(file_->name());
+void FileGenerator::GenerateForwardDeclarations(io::Printer* printer) {
+ ForwardDeclarations decls;
+ for (int i = 0; i < file_->dependency_count(); i++) {
+ FileGenerator dependency(file_->dependency(i), options_);
+ dependency.FillForwardDeclarations(&decls);
+ }
+ FillForwardDeclarations(&decls);
+ decls.Print(printer);
+}
+
+void FileGenerator::FillForwardDeclarations(ForwardDeclarations* decls) {
+ for (int i = 0; i < file_->public_dependency_count(); i++) {
+ FileGenerator dependency(file_->public_dependency(i), options_);
+ dependency.FillForwardDeclarations(decls);
+ }
+ for (int i = 0; i < package_parts_.size(); i++) {
+ decls = decls->AddOrGetNamespace(package_parts_[i]);
+ }
+ // Generate enum definitions.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->FillEnumForwardDeclarations(&decls->enums());
+ }
+ for (int i = 0; i < file_->enum_type_count(); i++) {
+ enum_generators_[i]->FillForwardDeclaration(&decls->enums());
+ }
+ // Generate forward declarations of classes.
+ for (int i = 0; i < file_->message_type_count(); i++) {
+ message_generators_[i]->FillMessageForwardDeclarations(
+ &decls->classes());
+ }
+}
+
+void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer,
+ const string& filename_identifier) {
// Generate top of header.
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
@@ -564,8 +754,8 @@ void FileGenerator::GenerateTopHeaderGuard(io::Printer* printer) {
"filename_identifier", filename_identifier);
}
-void FileGenerator::GenerateBottomHeaderGuard(io::Printer* printer) {
- string filename_identifier = FilenameIdentifier(file_->name());
+void FileGenerator::GenerateBottomHeaderGuard(
+ io::Printer* printer, const string& filename_identifier) {
printer->Print(
"#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
"filename_identifier", filename_identifier);
@@ -696,9 +886,13 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations(
}
void FileGenerator::GenerateMessageForwardDeclarations(io::Printer* printer) {
- // Generate forward declarations of classes.
+ set<string> classes;
for (int i = 0; i < file_->message_type_count(); i++) {
- message_generators_[i]->GenerateMessageForwardDeclaration(printer);
+ message_generators_[i]->FillMessageForwardDeclarations(&classes);
+ }
+ for (set<string>::const_iterator it = classes.begin(), end = classes.end();
+ it != end; ++it) {
+ printer->Print("class $classname$;\n", "classname", it->c_str());
}
}
@@ -804,10 +998,6 @@ void FileGenerator::GenerateInlineFunctionDefinitions(io::Printer* printer) {
// Methods of the dependent base class must always be inline in the header.
message_generators_[i]->GenerateDependentInlineMethods(printer);
}
-
- printer->Print(
- "\n"
- "// @@protoc_insertion_point(namespace_scope)\n");
}
void FileGenerator::GenerateProto2NamespaceEnumSpecializations(
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h
index e68f67bb..29cdaea5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.h
+++ b/src/google/protobuf/compiler/cpp/cpp_file.h
@@ -69,10 +69,14 @@ class FileGenerator {
const Options& options);
~FileGenerator();
- void GenerateHeader(io::Printer* printer);
+ void GenerateProtoHeader(io::Printer* printer);
+ void GeneratePBHeader(io::Printer* printer);
void GenerateSource(io::Printer* printer);
private:
+ // Internal type used by GenerateForwardDeclarations (defined in file.cc).
+ class ForwardDeclarations;
+
// Generate the BuildDescriptors() procedure, which builds all descriptors
// for types defined in the file.
void GenerateBuildDescriptors(io::Printer* printer);
@@ -80,9 +84,19 @@ class FileGenerator {
void GenerateNamespaceOpeners(io::Printer* printer);
void GenerateNamespaceClosers(io::Printer* printer);
+ // For other imports, generates their forward-declarations.
+ void GenerateForwardDeclarations(io::Printer* printer);
+
+ // Internal helper used by GenerateForwardDeclarations: fills 'decls'
+ // with all necessary forward-declarations for this file and its
+ // transient depednencies.
+ void FillForwardDeclarations(ForwardDeclarations* decls);
+
// Generates top or bottom of a header file.
- void GenerateTopHeaderGuard(io::Printer* printer);
- void GenerateBottomHeaderGuard(io::Printer* printer);
+ void GenerateTopHeaderGuard(io::Printer* printer,
+ const string& filename_identifier);
+ void GenerateBottomHeaderGuard(io::Printer* printer,
+ const string& filename_identifier);
// Generates #include directives.
void GenerateLibraryIncludes(io::Printer* printer);
@@ -92,10 +106,20 @@ class FileGenerator {
void GenerateGlobalStateFunctionDeclarations(io::Printer* printer);
// Generates types for classes.
- void GenerateMessageForwardDeclarations(io::Printer* printer);
void GenerateMessageDefinitions(io::Printer* printer);
+ // Generates forward-declarations for just this file's classes. This is
+ // used for .pb.h headers, but not in proto_h mode.
+ void GenerateMessageForwardDeclarations(io::Printer* printer);
+
+ // Fills in types for forward declarations. This is used internally, and
+ // also by other FileGenerators to determine imports' declarations.
+ void FillMessageForwardDeclarations(ForwardDeclarations* decls);
+ void FillMessageDefinitions(ForwardDeclarations* decls);
+
// Generates enum definitions.
+ void GenerateEnumForwardDeclarations(io::Printer* printer);
+ void FillEnumForwardDeclarations(ForwardDeclarations* decls);
void GenerateEnumDefinitions(io::Printer* printer);
// Generates generic service definitions.
diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc
index 99416372..781526b5 100644
--- a/src/google/protobuf/compiler/cpp/cpp_generator.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc
@@ -100,16 +100,23 @@ bool CppGenerator::Generate(const FileDescriptor* file,
string basename = StripProto(file->name());
- basename.append(".pb");
FileGenerator file_generator(file, file_options);
- // Generate header.
+ // Generate header(s).
+ if (file_options.proto_h) {
+ google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(basename + ".proto.h"));
+ io::Printer printer(output.get(), '$');
+ file_generator.GenerateProtoHeader(&printer);
+ }
+
+ basename.append(".pb");
{
google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(basename + ".h"));
io::Printer printer(output.get(), '$');
- file_generator.GenerateHeader(&printer);
+ file_generator.GeneratePBHeader(&printer);
}
// Generate cc file.
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index 0f3688d0..09845458 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
#include <google/protobuf/io/printer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
@@ -68,7 +69,7 @@ const char* const kKeywordList[] = {
"constexpr", "const_cast", "continue", "decltype", "default", "delete", "do",
"double", "dynamic_cast", "else", "enum", "explicit", "extern", "false",
"float", "for", "friend", "goto", "if", "inline", "int", "long", "mutable",
- "namespace", "new", "noexcept", "not", "not_eq", "nullptr", "operator", "or",
+ "namespace", "new", "noexcept", "not", "not_eq", "NULL", "operator", "or",
"or_eq", "private", "protected", "public", "register", "reinterpret_cast",
"return", "short", "signed", "sizeof", "static", "static_assert",
"static_cast", "struct", "switch", "template", "this", "thread_local",
@@ -174,6 +175,14 @@ string SuperClassName(const Descriptor* descriptor) {
"::google::protobuf::Message" : "::google::protobuf::MessageLite";
}
+string DependentBaseDownCast() {
+ return "reinterpret_cast<T*>(this)->";
+}
+
+string DependentBaseConstDownCast() {
+ return "reinterpret_cast<const T*>(this)->";
+}
+
string FieldName(const FieldDescriptor* field) {
string result = field->name();
LowerString(&result);
@@ -208,6 +217,19 @@ string FieldConstantName(const FieldDescriptor *field) {
}
bool IsFieldDependent(const FieldDescriptor* field) {
+ if (field->containing_oneof() != NULL &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
+ return true;
+ }
+ if (field->is_map()) {
+ const Descriptor* map_descriptor = field->message_type();
+ for (int i = 0; i < map_descriptor->field_count(); i++) {
+ if (IsFieldDependent(map_descriptor->field(i))) {
+ return true;
+ }
+ }
+ return false;
+ }
if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
return false;
}
@@ -578,6 +600,94 @@ bool IsAnyMessage(const Descriptor* descriptor) {
descriptor->file()->name() == kAnyProtoFile;
}
+enum Utf8CheckMode {
+ STRICT = 0, // Parsing will fail if non UTF-8 data is in string fields.
+ VERIFY = 1, // Only log an error but parsing will succeed.
+ NONE = 2, // No UTF-8 check.
+};
+
+// Which level of UTF-8 enforcemant is placed on this file.
+static Utf8CheckMode GetUtf8CheckMode(const FieldDescriptor* field) {
+ if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+ return STRICT;
+ } else if (field->file()->options().optimize_for() !=
+ FileOptions::LITE_RUNTIME) {
+ return VERIFY;
+ } else {
+ return NONE;
+ }
+}
+
+static void GenerateUtf8CheckCode(const FieldDescriptor* field,
+ bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ const char* strict_function,
+ const char* verify_function,
+ io::Printer* printer) {
+ switch (GetUtf8CheckMode(field)) {
+ case STRICT: {
+ if (for_parse) {
+ printer->Print("DO_(");
+ }
+ printer->Print(
+ "::google::protobuf::internal::WireFormatLite::$function$(\n",
+ "function", strict_function);
+ printer->Indent();
+ printer->Print(variables, parameters);
+ if (for_parse) {
+ printer->Print("::google::protobuf::internal::WireFormatLite::PARSE,\n");
+ } else {
+ printer->Print("::google::protobuf::internal::WireFormatLite::SERIALIZE,\n");
+ }
+ printer->Print("\"$full_name$\")", "full_name", field->full_name());
+ if (for_parse) {
+ printer->Print(")");
+ }
+ printer->Print(";\n");
+ printer->Outdent();
+ break;
+ }
+ case VERIFY: {
+ printer->Print(
+ "::google::protobuf::internal::WireFormat::$function$(\n",
+ "function", verify_function);
+ printer->Indent();
+ printer->Print(variables, parameters);
+ if (for_parse) {
+ printer->Print("::google::protobuf::internal::WireFormat::PARSE,\n");
+ } else {
+ printer->Print("::google::protobuf::internal::WireFormat::SERIALIZE,\n");
+ }
+ printer->Print("\"$full_name$\");\n", "full_name", field->full_name());
+ printer->Outdent();
+ break;
+ }
+ case NONE:
+ break;
+ }
+}
+
+void GenerateUtf8CheckCodeForString(const FieldDescriptor* field,
+ bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ io::Printer* printer) {
+ GenerateUtf8CheckCode(field, for_parse, variables, parameters,
+ "VerifyUtf8String", "VerifyUTF8StringNamedField",
+ printer);
+}
+
+void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field,
+ bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ io::Printer* printer) {
+ GenerateUtf8CheckCode(field, for_parse, variables, parameters,
+ "VerifyUtf8Cord", "VerifyUTF8CordNamedField",
+ printer);
+}
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index 4bbf8303..985cb04c 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -70,8 +70,15 @@ string ClassName(const EnumDescriptor* enum_descriptor, bool qualified);
// This is a class name, like "ProtoName_InternalBase".
string DependentBaseClassTemplateName(const Descriptor* descriptor);
+// Name of the base class: either the dependent base class (for use with
+// proto_h) or google::protobuf::Message.
string SuperClassName(const Descriptor* descriptor);
+// Returns a string that down-casts from the dependent base class to the
+// derived class.
+string DependentBaseDownCast();
+string DependentBaseConstDownCast();
+
// Get the (unqualified) name that should be used for this field in C++ code.
// The name is coerced to lower-case to emulate proto1 behavior. People
// should be using lowercase-with-underscores style for proto field names
@@ -195,11 +202,6 @@ inline bool HasGenericServices(const FileDescriptor* file) {
file->options().cc_generic_services();
}
-// Should string fields in this file verify that their contents are UTF-8?
-inline bool HasUtf8Verification(const FileDescriptor* file) {
- return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
-}
-
// Should we generate a separate, super-optimized code path for serializing to
// flat arrays? We don't do this in Lite mode because we'd rather reduce code
// size.
@@ -263,6 +265,20 @@ inline bool SupportsArenas(const FieldDescriptor* field) {
bool IsAnyMessage(const FileDescriptor* descriptor);
bool IsAnyMessage(const Descriptor* descriptor);
+void GenerateUtf8CheckCodeForString(
+ const FieldDescriptor* field,
+ bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ io::Printer* printer);
+
+void GenerateUtf8CheckCodeForCord(
+ const FieldDescriptor* field,
+ bool for_parse,
+ const map<string, string>& variables,
+ const char* parameters,
+ io::Printer* printer);
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.cc b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
index 0ff0d27c..25acc61b 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc
@@ -100,8 +100,9 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
MapFieldGenerator::
MapFieldGenerator(const FieldDescriptor* descriptor,
- const Options& options)
- : descriptor_(descriptor) {
+ const Options& options)
+ : descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -152,7 +153,9 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MapFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_.Clear();\n");
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
+ printer->Print(variables, "$this_message$$name$_.Clear();\n");
}
void MapFieldGenerator::
@@ -231,6 +234,20 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"}\n");
}
+ const FieldDescriptor* key_field =
+ descriptor_->message_type()->FindFieldByName("key");
+ if (key_field->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ key_field, true, variables_,
+ "entry->key().data(), entry->key().length(),\n", printer);
+ }
+ if (value_field->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ value_field, true, variables_,
+ "entry->mutable_value()->data(),\n"
+ "entry->mutable_value()->length(),\n", printer);
+ }
+
// If entry is allocated by arena, its desctructor should be avoided.
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
@@ -258,7 +275,30 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
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"
+ " $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, false, variables_,
+ "it->first.data(), it->first.length(),\n", printer);
+ }
+ if (value_field->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ value_field, false, variables_,
+ "it->second.data(), it->second.length(),\n", printer);
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+
+ printer->Print(
" }\n");
// If entry is allocated by arena, its desctructor should be avoided.
@@ -293,7 +333,29 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
" entry.reset($name$_.New$wrapper$(it->first, it->second));\n"
" target = ::google::protobuf::internal::WireFormatLite::\n"
" Write$declared_type$NoVirtualToArray(\n"
- " $number$, *entry, target);\n"
+ " $number$, *entry, target);\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, false, variables_,
+ "it->first.data(), it->first.length(),\n", printer);
+ }
+ if (value_field->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ value_field, false, variables_,
+ "it->second.data(), it->second.length(),\n", printer);
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
" }\n");
// If entry is allocated by arena, its desctructor should be avoided.
diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h
index d27d4851..5e205623 100644
--- a/src/google/protobuf/compiler/cpp/cpp_map_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h
@@ -63,6 +63,7 @@ class MapFieldGenerator : public FieldGenerator {
private:
const FieldDescriptor* descriptor_;
+ const bool dependent_field_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc
index b0e38755..fc1ce962 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message.cc
@@ -39,7 +39,6 @@
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
-#include <set>
#include <utility>
#include <vector>
#include <google/protobuf/compiler/cpp/cpp_message.h>
@@ -415,31 +414,34 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor,
use_dependent_base_ = true;
}
}
+ if (options.proto_h && descriptor->oneof_decl_count() > 0) {
+ // Always make oneofs dependent.
+ use_dependent_base_ = true;
+ }
}
MessageGenerator::~MessageGenerator() {}
void MessageGenerator::
-GenerateMessageForwardDeclaration(io::Printer* printer) {
- printer->Print("class $classname$;\n",
- "classname", classname_);
+FillMessageForwardDeclarations(set<string>* class_names) {
+ class_names->insert(classname_);
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
// map entry message doesn't need forward declaration. Since map entry
// message cannot be a top level class, we just need to avoid calling
// GenerateForwardDeclaration here.
if (IsMapEntryMessage(descriptor_->nested_type(i))) continue;
- nested_generators_[i]->GenerateMessageForwardDeclaration(printer);
+ nested_generators_[i]->FillMessageForwardDeclarations(class_names);
}
}
void MessageGenerator::
-GenerateEnumForwardDeclaration(io::Printer* printer) {
+FillEnumForwardDeclarations(set<string>* enum_names) {
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
- nested_generators_[i]->GenerateEnumForwardDeclaration(printer);
+ nested_generators_[i]->FillEnumForwardDeclarations(enum_names);
}
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- enum_generators_[i]->GenerateForwardDeclaration(printer);
+ enum_generators_[i]->FillForwardDeclaration(enum_names);
}
}
@@ -484,13 +486,6 @@ GenerateDependentFieldAccessorDeclarations(io::Printer* printer) {
field_generators_.get(field).GenerateDependentAccessorDeclarations(printer);
printer->Print("\n");
}
- for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
- const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
- PrintFieldComment(printer, oneof);
- printer->Print(
- "void clear_$oneof_name$();\n",
- "oneof_name", oneof->name());
- }
}
void MessageGenerator::
@@ -505,7 +500,9 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) {
vars["constant_name"] = FieldConstantName(field);
bool dependent_field = use_dependent_base_ && IsFieldDependent(field);
- if (dependent_field) {
+ if (dependent_field &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
+ !field->is_map()) {
// If this field is dependent, the dependent base class determines
// the message type from the derived class (which is a template
// parameter). This typedef is for that:
@@ -594,8 +591,8 @@ GenerateDependentFieldAccessorDefinitions(io::Printer* printer) {
vars["tmpl"] = "template<class T>\n";
vars["dependent_classname"] =
DependentBaseClassTemplateName(descriptor_) + "<T>";
- vars["this_message"] = "reinterpret_cast<T*>(this)->";
- vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ vars["this_message"] = DependentBaseDownCast();
+ vars["this_const_message"] = DependentBaseConstDownCast();
GenerateFieldClear(field, vars, printer);
}
@@ -721,13 +718,15 @@ GenerateFieldClear(const FieldDescriptor* field,
printer->Print(vars,
"if ($this_message$has_$name$()) {\n");
printer->Indent();
- field_generators_.get(field).GenerateClearingCode(printer);
+ field_generators_.get(field)
+ .GenerateClearingCode(printer);
printer->Print(vars,
"$this_message$clear_has_$oneof_name$();\n");
printer->Outdent();
printer->Print("}\n");
} else {
- field_generators_.get(field).GenerateClearingCode(printer);
+ field_generators_.get(field)
+ .GenerateClearingCode(printer);
if (HasFieldPresence(descriptor_->file())) {
if (!field->is_repeated()) {
printer->Print(vars,
@@ -752,6 +751,18 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
map<string, string> vars;
SetCommonFieldVariables(field, &vars, options_);
vars["inline"] = is_inline ? "inline " : "";
+ if (use_dependent_base_ && IsFieldDependent(field)) {
+ vars["tmpl"] = "template<class T>\n";
+ vars["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_) + "<T>";
+ vars["this_message"] = "reinterpret_cast<T*>(this)->";
+ vars["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ } else {
+ vars["tmpl"] = "";
+ vars["dependent_classname"] = vars["classname"];
+ vars["this_message"] = "";
+ vars["this_const_message"] = "";
+ }
// Generate has_$name$() or $name$_size().
if (field->is_repeated()) {
@@ -775,10 +786,6 @@ GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline) {
}
if (!use_dependent_base_ || !IsFieldDependent(field)) {
- vars["tmpl"] = "";
- vars["dependent_classname"] = vars["classname"];
- vars["this_message"] = "";
- vars["this_const_message"] = "";
GenerateFieldClear(field, vars, printer);
}
@@ -915,15 +922,32 @@ GenerateClassDefinition(io::Printer* printer) {
"}\n"
"\n");
} else {
- printer->Print(
- "inline const ::std::string& unknown_fields() const {\n"
- " return _unknown_fields_;\n"
- "}\n"
- "\n"
- "inline ::std::string* mutable_unknown_fields() {\n"
- " return &_unknown_fields_;\n"
- "}\n"
- "\n");
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_.Get(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return _unknown_fields_.Mutable(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n"
+ "}\n"
+ "\n");
+ } else {
+ printer->Print(
+ "inline const ::std::string& unknown_fields() const {\n"
+ " return _unknown_fields_.GetNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n"
+ "inline ::std::string* mutable_unknown_fields() {\n"
+ " return _unknown_fields_.MutableNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n"
+ "}\n"
+ "\n");
+ }
}
}
@@ -1068,6 +1092,10 @@ GenerateClassDefinition(io::Printer* printer) {
}
}
uses_string_ = false;
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ uses_string_ = true;
+ }
for (int i = 0; i < descriptors.size(); i++) {
const FieldDescriptor* field = descriptors[i];
if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
@@ -1201,18 +1229,11 @@ GenerateClassDefinition(io::Printer* printer) {
// Generate oneof function declarations
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
- if (use_dependent_base_) {
- printer->Print(
- "inline bool has_$oneof_name$() const;\n"
- "inline void clear_has_$oneof_name$();\n\n",
- "oneof_name", descriptor_->oneof_decl(i)->name());
- } else {
- printer->Print(
- "inline bool has_$oneof_name$() const;\n"
- "void clear_$oneof_name$();\n"
- "inline void clear_has_$oneof_name$();\n\n",
- "oneof_name", descriptor_->oneof_decl(i)->name());
- }
+ printer->Print(
+ "inline bool has_$oneof_name$() const;\n"
+ "void clear_$oneof_name$();\n"
+ "inline void clear_has_$oneof_name$();\n\n",
+ "oneof_name", descriptor_->oneof_decl(i)->name());
}
if (HasGeneratedMethods(descriptor_->file()) &&
@@ -1262,7 +1283,7 @@ GenerateClassDefinition(io::Printer* printer) {
"::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;\n");
} else {
printer->Print(
- "::std::string _unknown_fields_;\n"
+ "::google::protobuf::internal::ArenaStringPtr _unknown_fields_;\n"
"::google::protobuf::Arena* _arena_ptr_;\n"
"\n");
}
@@ -1919,6 +1940,13 @@ GenerateSharedConstructorCode(io::Printer* printer) {
uses_string_ ? "::google::protobuf::internal::GetEmptyString();\n" : "",
"_cached_size_ = 0;\n").c_str());
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ printer->Print(
+ "_unknown_fields_.UnsafeSetDefault(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
+
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->containing_oneof()) {
field_generators_.get(descriptor_->field(i))
@@ -1955,6 +1983,22 @@ GenerateSharedDestructorCode(io::Printer* printer) {
"}\n"
"\n");
}
+
+ // Write the desctructor for _unknown_fields_ in lite runtime.
+ if (PreserveUnknownFields(descriptor_) &&
+ !UseUnknownFieldSet(descriptor_->file())) {
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "_unknown_fields_.Destroy(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n");
+ } else {
+ printer->Print(
+ "_unknown_fields_.DestroyNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
+ }
+
// Write the destructors for each field except oneof members.
for (int i = 0; i < descriptor_->field_count(); i++) {
if (!descriptor_->field(i)->containing_oneof()) {
@@ -2463,8 +2507,16 @@ GenerateClear(io::Printer* printer) {
" mutable_unknown_fields()->Clear();\n"
"}\n");
} else {
- printer->Print(
- "mutable_unknown_fields()->clear();\n");
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(
+ "_unknown_fields_.ClearToEmpty(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited(),\n"
+ " GetArenaNoVirtual());\n");
+ } else {
+ printer->Print(
+ "_unknown_fields_.ClearToEmptyNoArena(\n"
+ " &::google::protobuf::internal::GetEmptyStringAlreadyInited());\n");
+ }
}
}
@@ -2481,33 +2533,16 @@ GenerateOneofClear(io::Printer* printer) {
oneof_vars["oneofname"] = descriptor_->oneof_decl(i)->name();
string message_class;
- if (use_dependent_base_) {
- oneof_vars["tmpl"] = "template<class T>\n";
- oneof_vars["inline"] = "inline ";
- oneof_vars["dependent_classname"] =
- DependentBaseClassTemplateName(descriptor_) + "<T>";
- oneof_vars["this_message"] = "reinterpret_cast<T*>(this)->";
- message_class = "T::";
- } else {
- oneof_vars["tmpl"] = "";
- oneof_vars["inline"] = "";
- oneof_vars["dependent_classname"] = classname_;
- oneof_vars["this_message"] = "";
- }
-
printer->Print(oneof_vars,
- "$tmpl$"
- "$inline$"
- "void $dependent_classname$::clear_$oneofname$() {\n");
+ "void $classname$::clear_$oneofname$() {\n");
printer->Indent();
printer->Print(oneof_vars,
- "switch($this_message$$oneofname$_case()) {\n");
+ "switch($oneofname$_case()) {\n");
printer->Indent();
for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "case $message_class$k$field_name$: {\n",
- "message_class", message_class,
+ "case k$field_name$: {\n",
"field_name", UnderscoresToCamelCase(field->name(), true));
printer->Indent();
// We clear only allocated objects in oneofs
@@ -2524,20 +2559,16 @@ GenerateOneofClear(io::Printer* printer) {
"}\n");
}
printer->Print(
- "case $message_class$$cap_oneof_name$_NOT_SET: {\n"
+ "case $cap_oneof_name$_NOT_SET: {\n"
" break;\n"
"}\n",
- "message_class", message_class,
"cap_oneof_name",
ToUpper(descriptor_->oneof_decl(i)->name()));
printer->Outdent();
printer->Print(
"}\n"
- "$this_message$_oneof_case_[$oneof_index$] = "
- "$message_class$$cap_oneof_name$_NOT_SET;\n",
- "this_message", oneof_vars["this_message"],
+ "_oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n",
"oneof_index", SimpleItoa(i),
- "message_class", message_class,
"cap_oneof_name",
ToUpper(descriptor_->oneof_decl(i)->name()));
printer->Outdent();
@@ -2612,7 +2643,7 @@ GenerateSwap(io::Printer* printer) {
printer->Print(
"_internal_metadata_.Swap(&other->_internal_metadata_);\n");
} else {
- printer->Print("_unknown_fields_.swap(other->_unknown_fields_);\n");
+ printer->Print("_unknown_fields_.Swap(&other->_unknown_fields_);\n");
}
} else {
// Still swap internal_metadata as it may contain more than just
diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h
index 23dad10c..8e19a3f0 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message.h
@@ -39,8 +39,8 @@
#ifndef _SHARED_PTR_H
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <set>
#include <string>
-#include <vector>
#include <google/protobuf/compiler/cpp/cpp_field.h>
#include <google/protobuf/compiler/cpp/cpp_options.h>
@@ -66,9 +66,10 @@ class MessageGenerator {
// Header stuff.
- // Generate foward declarations for this class and all its nested types.
- void GenerateMessageForwardDeclaration(io::Printer* printer);
- void GenerateEnumForwardDeclaration(io::Printer* printer);
+ // Return names for foward declarations of this class and all its nested
+ // types.
+ void FillMessageForwardDeclarations(set<string>* class_names);
+ void FillEnumForwardDeclarations(set<string>* enum_names);
// Generate definitions of all nested enums (must come before class
// definitions because those classes use the enums definitions).
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
index ba318d10..b4545892 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc
@@ -63,6 +63,14 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
SafeFunctionName(descriptor->containing_type(),
descriptor, "release_");
(*variables)["full_name"] = descriptor->full_name();
+ if (options.proto_h && IsFieldDependent(descriptor)) {
+ (*variables)["dependent_type"] = "T::" + DependentTypeName(descriptor);
+ (*variables)["dependent_typename"] =
+ "typename T::" + DependentTypeName(descriptor);
+ } else {
+ (*variables)["dependent_type"] = FieldMessageTypeName(descriptor);
+ (*variables)["dependent_typename"] = FieldMessageTypeName(descriptor);
+ }
}
} // namespace
@@ -85,7 +93,21 @@ GeneratePrivateMembers(io::Printer* printer) const {
}
void MessageFieldGenerator::
+GenerateGetterDeclaration(io::Printer* printer) const {
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+}
+
+void MessageFieldGenerator::
GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
+ // Arena manipulation code is out-of-line in the derived message class.
+ printer->Print(variables_,
+ "$type$* mutable_$name$()$deprecation$;\n"
+ "$type$* $release_name$()$deprecation$;\n"
+ "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
}
void MessageFieldGenerator::
@@ -103,11 +125,13 @@ GenerateAccessorDeclarations(io::Printer* printer) const {
"$type$* _slow_$release_name$()$deprecation$;\n"
"public:\n");
}
- printer->Print(variables_,
- "const $type$& $name$() const$deprecation$;\n"
- "$type$* mutable_$name$()$deprecation$;\n"
- "$type$* $release_name$()$deprecation$;\n"
- "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ GenerateGetterDeclaration(printer);
+ if (!dependent_field_) {
+ printer->Print(variables_,
+ "$type$* mutable_$name$()$deprecation$;\n"
+ "$type$* $release_name$()$deprecation$;\n"
+ "void set_allocated_$name$($type$* $name$)$deprecation$;\n");
+ }
if (SupportsArenas(descriptor_)) {
printer->Print(variables_,
"$type$* unsafe_arena_release_$name$()$deprecation$;\n"
@@ -123,12 +147,12 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
"void $classname$::_slow_mutable_$name$() {\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables_,
- " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $name$_ = ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
+ " GetArenaNoVirtual());\n");
} else {
printer->Print(variables_,
- " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $name$_ = ::google::protobuf::Arena::Create< $type$ >(\n"
+ " GetArenaNoVirtual());\n");
}
printer->Print(variables_,
"}\n"
@@ -151,7 +175,7 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
if (SupportsArenas(descriptor_->message_type())) {
// NOTE: the same logic is mirrored in weak_message_field.cc. Any
// arena-related semantics changes should be made in both places.
- printer->Print(variables_,
+ printer->Print(variables_,
"void $classname$::_slow_set_allocated_$name$(\n"
" ::google::protobuf::Arena* message_arena, $type$** $name$) {\n"
" if (message_arena != NULL && \n"
@@ -189,15 +213,139 @@ void MessageFieldGenerator::GenerateNonInlineAccessorDefinitions(
void MessageFieldGenerator::
GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
+
+ map<string, string> variables(variables_);
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = DependentBaseDownCast();
+ if (!variables["set_hasbit"].empty()) {
+ variables["set_hasbit"] =
+ variables["this_message"] + variables["set_hasbit"];
+ }
+ if (!variables["clear_hasbit"].empty()) {
+ variables["clear_hasbit"] =
+ variables["this_message"] + variables["clear_hasbit"];
+ }
+
+ if (SupportsArenas(descriptor_)) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if ($name$_ == NULL) {\n"
+ " $this_message$_slow_mutable_$name$();\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::$release_name$() {\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $clear_hasbit$\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
+ " return $this_message$_slow_$release_name$();\n"
+ " } else {\n"
+ " $dependent_typename$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ " }\n"
+ "}\n"
+ "template <class T>\n"
+ "inline void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " ::google::protobuf::Arena* message_arena = $this_message$GetArenaNoVirtual();\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if (message_arena == NULL) {\n"
+ " delete $name$_;\n"
+ " }\n"
+ " if ($name$ != NULL) {\n");
+ if (SupportsArenas(descriptor_->message_type())) {
+ // If we're on an arena and the incoming message is not, simply Own() it
+ // rather than copy to the arena -- either way we need a heap dealloc,
+ // so we might as well defer it. Otherwise, if incoming message is on a
+ // different ownership domain (specific arena, or the heap) than we are,
+ // copy to our arena (or heap, as the case may be).
+ printer->Print(variables,
+ " $this_message$_slow_set_allocated_$name$(message_arena, "
+ "&$name$);\n");
+ } else {
+ printer->Print(variables,
+ " if (message_arena != NULL) {\n"
+ " message_arena->Own($name$);\n"
+ " }\n");
+ }
+ printer->Print(variables,
+ " }\n"
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n"
+ // TODO(dlj): move insertion points to message class.
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+ } else {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$() {\n"
+ " $set_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " if ($name$_ == NULL) {\n"
+ " $name$_ = new $dependent_typename$;\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::$release_name$() {\n"
+ " $clear_hasbit$\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " $dependent_typename$* temp = $name$_;\n"
+ " $name$_ = NULL;\n"
+ " return temp;\n"
+ "}\n"
+ "template <class T>\n"
+ "inline void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $dependent_typename$*& $name$_ = $this_message$$name$_;\n"
+ " delete $name$_;\n");
+
+ if (SupportsArenas(descriptor_->message_type())) {
+ printer->Print(variables,
+ " if ($name$ != NULL && static_cast< $dependent_typename$* >($name$)"
+ "->GetArena() != NULL) {\n"
+ " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
+ " new_$name$->CopyFrom(*$name$);\n"
+ " $name$ = new_$name$;\n"
+ " }\n");
+ }
+
+ printer->Print(variables,
+ " $name$_ = $name$;\n"
+ " if ($name$) {\n"
+ " $set_hasbit$\n"
+ " } else {\n"
+ " $clear_hasbit$\n"
+ " }\n"
+ " // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
+ "}\n");
+ }
}
void MessageFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const {
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ variables["inline"] = is_inline ? "inline " : "";
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
+ "$inline$const $type$& $classname$::$name$() const {\n"
" // @@protoc_insertion_point(field_get:$full_name$)\n");
PrintHandlingOptionalStaticInitializers(
@@ -206,19 +354,25 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return $name$_ != NULL ? *$name$_ : *default_instance_->$name$_;\n",
// Without.
" return $name$_ != NULL ? *$name$_ : *default_instance().$name$_;\n");
+ printer->Print(variables, "}\n");
+
+ if (dependent_field_) {
+ return;
+ }
if (SupportsArenas(descriptor_)) {
printer->Print(variables,
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
+ "$inline$"
+ "$type$* $classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
" if ($name$_ == NULL) {\n"
- " _slow_mutable_$name$();"
+ " _slow_mutable_$name$();\n"
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
+ "$inline$"
+ "$type$* $classname$::$release_name$() {\n"
" $clear_hasbit$\n"
" if (GetArenaNoVirtual() != NULL) {\n"
" return _slow_$release_name$();\n"
@@ -228,7 +382,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" return temp;\n"
" }\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ "$inline$ "
+ "void $classname$::set_allocated_$name$($type$* $name$) {\n"
" ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();\n"
" if (message_arena == NULL) {\n"
" delete $name$_;\n"
@@ -260,8 +415,8 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n");
} else {
printer->Print(variables,
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
+ "$inline$"
+ "$type$* $classname$::mutable_$name$() {\n"
" $set_hasbit$\n"
" if ($name$_ == NULL) {\n"
" $name$_ = new $type$;\n"
@@ -269,13 +424,15 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
" return $name$_;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
+ "$inline$"
+ "$type$* $classname$::$release_name$() {\n"
" $clear_hasbit$\n"
" $type$* temp = $name$_;\n"
" $name$_ = NULL;\n"
" return temp;\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
+ "$inline$"
+ "void $classname$::set_allocated_$name$($type$* $name$) {\n"
" delete $name$_;\n");
if (SupportsArenas(descriptor_->message_type())) {
@@ -301,15 +458,19 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MessageFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
if (!HasFieldPresence(descriptor_->file())) {
// If we don't have has-bits, message presence is indicated only by ptr !=
// NULL. Thus on clear, we need to delete the object.
- printer->Print(variables_,
- "if (GetArenaNoVirtual() == NULL && $name$_ != NULL) delete $name$_;\n"
- "$name$_ = NULL;\n");
+ printer->Print(variables,
+ "if ($this_message$GetArenaNoVirtual() == NULL && "
+ "$this_message$$name$_ != NULL) delete $this_message$$name$_;\n"
+ "$this_message$$name$_ = NULL;\n");
} else {
- printer->Print(variables_,
- "if ($name$_ != NULL) $name$_->$type$::Clear();\n");
+ printer->Print(variables,
+ "if ($this_message$$name$_ != NULL) $this_message$$name$_->"
+ "$dependent_type$::Clear();\n");
}
}
@@ -370,79 +531,149 @@ GenerateByteSize(io::Printer* printer) const {
MessageOneofFieldGenerator::
MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : MessageFieldGenerator(descriptor, options) {
+ : MessageFieldGenerator(descriptor, options),
+ dependent_base_(options.proto_h) {
SetCommonOneofFieldVariables(descriptor, &variables_);
}
MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {}
+
+void MessageOneofFieldGenerator::
+GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ // Oneof field getters must be dependent as they call default_instance().
+ // Otherwise, the logic is the same as MessageFields.
+ if (!dependent_field_) {
+ return;
+ }
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+ MessageFieldGenerator::GenerateDependentAccessorDeclarations(printer);
+}
+
+void MessageOneofFieldGenerator::
+GenerateGetterDeclaration(io::Printer* printer) const {
+ // Oneof field getters must be dependent as they call default_instance().
+ // Unlike MessageField, this means there is no (non-dependent) getter to
+ // generate.
+ if (dependent_field_) {
+ return;
+ }
+ printer->Print(variables_,
+ "const $type$& $name$() const$deprecation$;\n");
+}
+
void MessageOneofFieldGenerator::
GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ if (!dependent_base_) {
+ return;
+ }
+ map<string, string> variables(variables_);
+ variables["inline"] = "inline ";
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = "reinterpret_cast<T*>(this)->";
+ // Const message access is needed for the dependent getter.
+ variables["this_const_message"] = "reinterpret_cast<const T*>(this)->";
+ variables["tmpl"] = "template <class T>\n";
+ variables["field_member"] = variables["this_message"] +
+ variables["oneof_prefix"] + variables["name"] +
+ "_";
+ InternalGenerateInlineAccessorDefinitions(variables, printer);
}
void MessageOneofFieldGenerator::
GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const {
+ if (dependent_base_) {
+ return;
+ }
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ variables["inline"] = is_inline ? "inline " : "";
+ variables["dependent_classname"] = variables["classname"];
+ variables["this_message"] = "";
+ variables["this_const_message"] = "";
+ variables["tmpl"] = "";
+ variables["field_member"] =
+ variables["oneof_prefix"] + variables["name"] + "_";
+ variables["dependent_type"] = variables["type"];
+ InternalGenerateInlineAccessorDefinitions(variables, printer);
+}
+
+void MessageOneofFieldGenerator::
+GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["field_member"] =
+ variables["oneof_prefix"] + variables["name"] + "_";
+
+ //printer->Print(variables,
+}
+
+void MessageOneofFieldGenerator::
+InternalGenerateInlineAccessorDefinitions(const map<string, string>& variables,
+ io::Printer* printer) const {
+ printer->Print(variables,
+ "$tmpl$"
+ "$inline$ "
+ "const $type$& $dependent_classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $this_const_message$has_$name$()\n"
+ " ? *$this_const_message$$oneof_prefix$$name$_\n"
+ " : $dependent_type$::default_instance();\n"
+ "}\n");
+
if (SupportsArenas(descriptor_)) {
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return has_$name$() ? *$oneof_prefix$$name$_\n"
- " : $type$::default_instance();\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
- " if (!has_$name$()) {\n"
- " clear_$oneof_name$();\n"
- " set_has_$name$();\n");
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::mutable_$name$() {\n"
+ " if (!$this_message$has_$name$()) {\n"
+ " $this_message$clear_$oneof_name$();\n"
+ " $this_message$set_has_$name$();\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables,
- " $oneof_prefix$$name$_ = \n"
- " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $field_member$ = \n"
+ " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n");
} else {
printer->Print(variables,
- " $oneof_prefix$$name$_ = \n"
- " ::google::protobuf::Arena::Create< $type$ >(\n"
- " GetArenaNoVirtual());\n");
+ " $this_message$$oneof_prefix$$name$_ = \n"
+ " ::google::protobuf::Arena::Create< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n");
}
printer->Print(variables,
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $oneof_prefix$$name$_;\n"
+ " return $field_member$;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " if (GetArenaNoVirtual() != NULL) {\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::$release_name$() {\n"
+ " if ($this_message$has_$name$()) {\n"
+ " $this_message$clear_has_$oneof_name$();\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
// N.B.: safe to use the underlying field pointer here because we are sure
// that it is non-NULL (because has_$name$() returned true).
- " $type$* temp = new $type$;\n"
- " temp->MergeFrom(*$oneof_prefix$$name$_);\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ " $dependent_typename$* temp = new $dependent_typename$;\n"
+ " temp->MergeFrom(*$field_member$);\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" } else {\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ " $dependent_typename$* temp = $field_member$;\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" }\n"
" } else {\n"
" return NULL;\n"
" }\n"
"}\n"
- "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
- " return temp;\n"
- " } else {\n"
- " return NULL;\n"
- " }\n"
- "}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
- " clear_$oneof_name$();\n"
+ "$tmpl$"
+ "$inline$"
+ "void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $this_message$clear_$oneof_name$();\n"
" if ($name$) {\n");
if (SupportsArenas(descriptor_->message_type())) {
@@ -450,32 +681,42 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
// If incoming message is on the heap and we are on an arena, just Own()
// it (see above). If it's on a different arena than we are or one of us
// is on the heap, we make a copy to our arena/heap.
- " if (GetArenaNoVirtual() != NULL &&\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL &&\n"
" ::google::protobuf::Arena::GetArena($name$) == NULL) {\n"
- " GetArenaNoVirtual()->Own($name$);\n"
- " } else if (GetArenaNoVirtual() !=\n"
+ " $this_message$GetArenaNoVirtual()->Own($name$);\n"
+ " } else if ($this_message$GetArenaNoVirtual() !=\n"
" ::google::protobuf::Arena::GetArena($name$)) {\n"
- " $type$* new_$name$ = \n"
- " ::google::protobuf::Arena::CreateMessage< $type$ >(\n"
- " GetArenaNoVirtual());\n"
+ " $dependent_typename$* new_$name$ = \n"
+ " ::google::protobuf::Arena::CreateMessage< $dependent_typename$ >(\n"
+ " $this_message$GetArenaNoVirtual());\n"
" new_$name$->CopyFrom(*$name$);\n"
" $name$ = new_$name$;\n"
" }\n");
} else {
printer->Print(variables,
- " if (GetArenaNoVirtual() != NULL) {\n"
- " GetArenaNoVirtual()->Own($name$);\n"
+ " if ($this_message$GetArenaNoVirtual() != NULL) {\n"
+ " $this_message$GetArenaNoVirtual()->Own($name$);\n"
" }\n");
}
printer->Print(variables,
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = $name$;\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n"
- "$inline$ void $classname$::unsafe_arena_set_allocated_$name$("
- "$type$* $name$) {\n"
+ "$inline$ $type$* $classname$::unsafe_arena_release_$name$() {\n"
+ " if (has_$name$()) {\n"
+ " clear_has_$oneof_name$();\n"
+ " $type$* temp = $oneof_prefix$$name$_;\n"
+ " $oneof_prefix$$name$_ = NULL;\n"
+ " return temp;\n"
+ " } else {\n"
+ " return NULL;\n"
+ " }\n"
+ "}\n"
+ "$inline$ void $classname$::unsafe_arena_set_allocated_$name$"
+ "($type$* $name$) {\n"
// We rely on the oneof clear method to free the earlier contents of this
// oneof. We can directly use the pointer we're given to set the new
// value.
@@ -489,44 +730,47 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
"}\n");
} else {
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return has_$name$() ? *$oneof_prefix$$name$_\n"
- " : $type$::default_instance();\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$() {\n"
- " if (!has_$name$()) {\n"
- " clear_$oneof_name$();\n"
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = new $type$;\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::mutable_$name$() {\n"
+ " if (!$this_message$has_$name$()) {\n"
+ " $this_message$clear_$oneof_name$();\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = new $dependent_typename$;\n"
" }\n"
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $oneof_prefix$$name$_;\n"
+ " return $field_member$;\n"
"}\n"
- "$inline$ $type$* $classname$::$release_name$() {\n"
- " if (has_$name$()) {\n"
- " clear_has_$oneof_name$();\n"
- " $type$* temp = $oneof_prefix$$name$_;\n"
- " $oneof_prefix$$name$_ = NULL;\n"
+ "$tmpl$"
+ "$inline$"
+ "$type$* $dependent_classname$::$release_name$() {\n"
+ " if ($this_message$has_$name$()) {\n"
+ " $this_message$clear_has_$oneof_name$();\n"
+ " $dependent_typename$* temp = $field_member$;\n"
+ " $field_member$ = NULL;\n"
" return temp;\n"
" } else {\n"
" return NULL;\n"
" }\n"
"}\n"
- "$inline$ void $classname$::set_allocated_$name$($type$* $name$) {\n"
- " clear_$oneof_name$();\n"
+ "$tmpl$"
+ "$inline$"
+ "void $dependent_classname$::"
+ "set_allocated_$name$($type$* $name$) {\n"
+ " $this_message$clear_$oneof_name$();\n"
" if ($name$) {\n");
if (SupportsArenas(descriptor_->message_type())) {
printer->Print(variables,
- " if ($name$->GetArena() != NULL) {\n"
- " $type$* new_$name$ = new $type$;\n"
+ " if (static_cast< $dependent_typename$*>($name$)->"
+ "GetArena() != NULL) {\n"
+ " $dependent_typename$* new_$name$ = new $dependent_typename$;\n"
" new_$name$->CopyFrom(*$name$);\n"
" $name$ = new_$name$;\n"
" }\n");
}
printer->Print(variables,
- " set_has_$name$();\n"
- " $oneof_prefix$$name$_ = $name$;\n"
+ " $this_message$set_has_$name$();\n"
+ " $field_member$ = $name$;\n"
" }\n"
" // @@protoc_insertion_point(field_set_allocated:$full_name$)\n"
"}\n");
@@ -535,14 +779,16 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void MessageOneofFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- "if (GetArenaNoVirtual() == NULL) {\n"
- " delete $oneof_prefix$$name$_;\n"
+ printer->Print(variables,
+ "if ($this_message$GetArenaNoVirtual() == NULL) {\n"
+ " delete $this_message$$oneof_prefix$$name$_;\n"
"}\n");
} else {
- printer->Print(variables_,
- "delete $oneof_prefix$$name$_;\n");
+ printer->Print(variables,
+ "delete $this_message$$oneof_prefix$$name$_;\n");
}
}
@@ -562,7 +808,9 @@ GenerateConstructorCode(io::Printer* printer) const {
RepeatedMessageFieldGenerator::
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : descriptor_(descriptor) {
+ : descriptor_(descriptor),
+ dependent_field_(options.proto_h && IsFieldDependent(descriptor)),
+ dependent_getter_(dependent_field_ && options.safe_boundary_check) {
SetMessageVariables(descriptor, &variables_, options);
}
@@ -575,60 +823,160 @@ GeneratePrivateMembers(io::Printer* printer) const {
}
void RepeatedMessageFieldGenerator::
-GenerateDependentAccessorDeclarations(io::Printer* printer) const {
-}
-
-void RepeatedMessageFieldGenerator::
-GenerateAccessorDeclarations(io::Printer* printer) const {
+InternalGenerateTypeDependentAccessorDeclarations(io::Printer* printer) const {
printer->Print(variables_,
- "const $type$& $name$(int index) const$deprecation$;\n"
"$type$* mutable_$name$(int index)$deprecation$;\n"
"$type$* add_$name$()$deprecation$;\n");
+ if (dependent_getter_) {
+ printer->Print(variables_,
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n");
+ }
printer->Print(variables_,
- "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- " $name$() const$deprecation$;\n"
"::google::protobuf::RepeatedPtrField< $type$ >*\n"
" mutable_$name$()$deprecation$;\n");
}
void RepeatedMessageFieldGenerator::
-GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+GenerateDependentAccessorDeclarations(io::Printer* printer) const {
+ if (dependent_getter_) {
+ printer->Print(variables_,
+ "const $type$& $name$(int index) const$deprecation$;\n");
+ }
+ if (dependent_field_) {
+ InternalGenerateTypeDependentAccessorDeclarations(printer);
+ }
}
void RepeatedMessageFieldGenerator::
-GenerateInlineAccessorDefinitions(io::Printer* printer,
- bool is_inline) const {
+GenerateAccessorDeclarations(io::Printer* printer) const {
+ if (!dependent_getter_) {
+ printer->Print(variables_,
+ "const $type$& $name$(int index) const$deprecation$;\n");
+ }
+ if (!dependent_field_) {
+ InternalGenerateTypeDependentAccessorDeclarations(printer);
+ }
+ if (!dependent_getter_) {
+ printer->Print(variables_,
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ " $name$() const$deprecation$;\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
+GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const {
+ if (!dependent_field_) {
+ return;
+ }
map<string, string> variables(variables_);
- variables["inline"] = is_inline ? "inline" : "";
+ // For the CRTP base class, all mutation methods are dependent, and so
+ // they must be in the header.
+ variables["dependent_classname"] =
+ DependentBaseClassTemplateName(descriptor_->containing_type()) + "<T>";
+ variables["this_message"] = DependentBaseDownCast();
+ variables["this_const_message"] = DependentBaseConstDownCast();
+
+ if (dependent_getter_) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline const $type$& $dependent_classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $this_const_message$$name$_.$cppget$(index);\n"
+ "}\n");
+ }
+
+ // Generate per-element accessors:
printer->Print(variables,
- "$inline$ const $type$& $classname$::$name$(int index) const {\n"
- " // @@protoc_insertion_point(field_get:$full_name$)\n"
- " return $name$_.$cppget$(index);\n"
- "}\n"
- "$inline$ $type$* $classname$::mutable_$name$(int index) {\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::mutable_$name$(int index) {\n"
+ // TODO(dlj): move insertion points
" // @@protoc_insertion_point(field_mutable:$full_name$)\n"
- " return $name$_.Mutable(index);\n"
+ " return $this_message$$name$_.Mutable(index);\n"
"}\n"
- "$inline$ $type$* $classname$::add_$name$() {\n"
+ "template <class T>\n"
+ "inline $type$* $dependent_classname$::add_$name$() {\n"
" // @@protoc_insertion_point(field_add:$full_name$)\n"
- " return $name$_.Add();\n"
+ " return $this_message$$name$_.Add();\n"
"}\n");
+
+
+ if (dependent_getter_) {
+ printer->Print(variables,
+ "template <class T>\n"
+ "inline const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$dependent_classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $this_const_message$$name$_;\n"
+ "}\n");
+ }
+
+ // Generate mutable access to the entire list:
printer->Print(variables,
- "$inline$ const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
- "$classname$::$name$() const {\n"
- " // @@protoc_insertion_point(field_list:$full_name$)\n"
- " return $name$_;\n"
- "}\n"
- "$inline$ ::google::protobuf::RepeatedPtrField< $type$ >*\n"
- "$classname$::mutable_$name$() {\n"
+ "template <class T>\n"
+ "inline ::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$dependent_classname$::mutable_$name$() {\n"
" // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
- " return &$name$_;\n"
+ " return &$this_message$$name$_;\n"
"}\n");
}
void RepeatedMessageFieldGenerator::
+GenerateInlineAccessorDefinitions(io::Printer* printer,
+ bool is_inline) const {
+ map<string, string> variables(variables_);
+ variables["inline"] = is_inline ? "inline " : "";
+
+ if (!dependent_getter_) {
+ printer->Print(variables,
+ "$inline$"
+ "const $type$& $classname$::$name$(int index) const {\n"
+ " // @@protoc_insertion_point(field_get:$full_name$)\n"
+ " return $name$_.$cppget$(index);\n"
+ "}\n");
+ }
+
+ if (!dependent_field_) {
+ printer->Print(variables,
+ "$inline$"
+ "$type$* $classname$::mutable_$name$(int index) {\n"
+ // TODO(dlj): move insertion points
+ " // @@protoc_insertion_point(field_mutable:$full_name$)\n"
+ " return $name$_.Mutable(index);\n"
+ "}\n"
+ "$inline$"
+ "$type$* $classname$::add_$name$() {\n"
+ " // @@protoc_insertion_point(field_add:$full_name$)\n"
+ " return $name$_.Add();\n"
+ "}\n");
+ }
+
+
+ if (!dependent_field_) {
+ printer->Print(variables,
+ "$inline$"
+ "::google::protobuf::RepeatedPtrField< $type$ >*\n"
+ "$classname$::mutable_$name$() {\n"
+ " // @@protoc_insertion_point(field_mutable_list:$full_name$)\n"
+ " return &$name$_;\n"
+ "}\n");
+ }
+ if (!dependent_getter_) {
+ printer->Print(variables,
+ "$inline$"
+ "const ::google::protobuf::RepeatedPtrField< $type$ >&\n"
+ "$classname$::$name$() const {\n"
+ " // @@protoc_insertion_point(field_list:$full_name$)\n"
+ " return $name$_;\n"
+ "}\n");
+ }
+}
+
+void RepeatedMessageFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
- printer->Print(variables_, "$name$_.Clear();\n");
+ map<string, string> variables(variables_);
+ variables["this_message"] = dependent_field_ ? DependentBaseDownCast() : "";
+ printer->Print(variables, "$this_message$$name$_.Clear();\n");
}
void RepeatedMessageFieldGenerator::
diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h
index 9ddf9643..35efd0fa 100644
--- a/src/google/protobuf/compiler/cpp/cpp_message_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h
@@ -68,6 +68,11 @@ class MessageFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
protected:
+ void GenerateArenaManipulationCode(const map<string, string>& variables,
+ io::Printer* printer) const;
+
+ virtual void GenerateGetterDeclaration(io::Printer* printer) const;
+
const FieldDescriptor* descriptor_;
const bool dependent_field_;
map<string, string> variables_;
@@ -83,15 +88,23 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator {
~MessageOneofFieldGenerator();
// implements FieldGenerator ---------------------------------------
+ void GenerateDependentAccessorDeclarations(io::Printer* printer) const;
void GenerateDependentInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateInlineAccessorDefinitions(io::Printer* printer,
bool is_inline) const;
- void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const {}
+ void GenerateNonInlineAccessorDefinitions(io::Printer* printer) const;
void GenerateClearingCode(io::Printer* printer) const;
void GenerateSwappingCode(io::Printer* printer) const;
void GenerateConstructorCode(io::Printer* printer) const;
+ protected:
+ void GenerateGetterDeclaration(io::Printer* printer) const;
+
private:
+ void InternalGenerateInlineAccessorDefinitions(
+ const map<string, string>& variables, io::Printer* printer) const;
+
+ const bool dependent_base_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
};
@@ -118,7 +131,12 @@ class RepeatedMessageFieldGenerator : public FieldGenerator {
void GenerateByteSize(io::Printer* printer) const;
private:
+ void InternalGenerateTypeDependentAccessorDeclarations(
+ io::Printer* printer) const;
+
const FieldDescriptor* descriptor_;
+ const bool dependent_field_;
+ const bool dependent_getter_;
map<string, string> variables_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 1a3896a1..6b0821a6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -367,25 +367,19 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
" input, this->mutable_$name$()));\n");
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::PARSE,\n"
- " \"$full_name$\");\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, true, variables_,
+ "this->$name$().data(), this->$name$().length(),\n", printer);
}
}
void StringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
- " \"$full_name$\");\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, false, variables_,
+ "this->$name$().data(), this->$name$().length(),\n", printer);
}
printer->Print(variables_,
"::google::protobuf::internal::WireFormatLite::Write$declared_type$MaybeAliased(\n"
@@ -394,13 +388,10 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const {
void StringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
- " \"$full_name$\");\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, false, variables_,
+ "this->$name$().data(), this->$name$().length(),\n", printer);
}
printer->Print(variables_,
"target =\n"
@@ -421,7 +412,8 @@ GenerateByteSize(io::Printer* printer) const {
StringOneofFieldGenerator::
StringOneofFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : StringFieldGenerator(descriptor, options) {
+ : StringFieldGenerator(descriptor, options),
+ dependent_field_(options.proto_h) {
SetCommonOneofFieldVariables(descriptor, &variables_);
}
@@ -604,13 +596,29 @@ GenerateInlineAccessorDefinitions(io::Printer* printer,
void StringOneofFieldGenerator::
GenerateClearingCode(io::Printer* printer) const {
+ map<string, string> variables(variables_);
+ if (dependent_field_) {
+ variables["this_message"] = DependentBaseDownCast();
+ // This clearing code may be in the dependent base class. If the default
+ // value is an empty string, then the $default_variable$ is a global
+ // singleton. If the default is not empty, we need to down-cast to get the
+ // default value's global singleton instance. See SetStringVariables() for
+ // possible values of default_variable.
+ if (!descriptor_->default_value_string().empty()) {
+ variables["default_variable"] =
+ DependentBaseDownCast() + variables["default_variable"];
+ }
+ } else {
+ variables["this_message"] = "";
+ }
if (SupportsArenas(descriptor_)) {
- printer->Print(variables_,
- "$oneof_prefix$$name$_.Destroy($default_variable$,\n"
- " GetArenaNoVirtual());\n");
+ printer->Print(variables,
+ "$this_message$$oneof_prefix$$name$_.Destroy($default_variable$,\n"
+ " $this_message$GetArenaNoVirtual());\n");
} else {
- printer->Print(variables_,
- "$oneof_prefix$$name$_.DestroyNoArena($default_variable$);\n");
+ printer->Print(variables,
+ "$this_message$$oneof_prefix$$name$_."
+ "DestroyNoArena($default_variable$);\n");
}
}
@@ -648,13 +656,10 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
"DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
" input, this->mutable_$name$()));\n");
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$().data(), this->$name$().length(),\n"
- " ::google::protobuf::internal::WireFormat::PARSE,\n"
- " \"$full_name$\");\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, true, variables_,
+ "this->$name$().data(), this->$name$().length(),\n", printer);
}
}
@@ -664,7 +669,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
RepeatedStringFieldGenerator::
RepeatedStringFieldGenerator(const FieldDescriptor* descriptor,
const Options& options)
- : descriptor_(descriptor) {
+ : descriptor_(descriptor) {
SetStringVariables(descriptor, &variables_, options);
}
@@ -800,14 +805,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) const {
printer->Print(variables_,
"DO_(::google::protobuf::internal::WireFormatLite::Read$declared_type$(\n"
" input, this->add_$name$()));\n");
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$(this->$name$_size() - 1).data(),\n"
- " this->$name$(this->$name$_size() - 1).length(),\n"
- " ::google::protobuf::internal::WireFormat::PARSE,\n"
- " \"$full_name$\");\n");
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, true, variables_,
+ "this->$name$(this->$name$_size() - 1).data(),\n"
+ "this->$name$(this->$name$_size() - 1).length(),\n",
+ printer);
}
}
@@ -815,14 +818,13 @@ void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizes(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n");
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- "::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$(i).data(), this->$name$(i).length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
- " \"$full_name$\");\n");
+ printer->Indent();
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, false, variables_,
+ "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
}
+ printer->Outdent();
printer->Print(variables_,
" ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
" $number$, this->$name$(i), output);\n"
@@ -833,14 +835,13 @@ void RepeatedStringFieldGenerator::
GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < this->$name$_size(); i++) {\n");
- if (HasUtf8Verification(descriptor_->file()) &&
- descriptor_->type() == FieldDescriptor::TYPE_STRING) {
- printer->Print(variables_,
- " ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(\n"
- " this->$name$(i).data(), this->$name$(i).length(),\n"
- " ::google::protobuf::internal::WireFormat::SERIALIZE,\n"
- " \"$full_name$\");\n");
+ printer->Indent();
+ if (descriptor_->type() == FieldDescriptor::TYPE_STRING) {
+ GenerateUtf8CheckCodeForString(
+ descriptor_, false, variables_,
+ "this->$name$(i).data(), this->$name$(i).length(),\n", printer);
}
+ printer->Outdent();
printer->Print(variables_,
" target = ::google::protobuf::internal::WireFormatLite::\n"
" Write$declared_type$ToArray($number$, this->$name$(i), target);\n"
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.h b/src/google/protobuf/compiler/cpp/cpp_string_field.h
index d1f19cd9..616e2067 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.h
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.h
@@ -93,6 +93,7 @@ class StringOneofFieldGenerator : public StringFieldGenerator {
void GenerateMergeFromCodedStream(io::Printer* printer) const;
private:
+ const bool dependent_field_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(StringOneofFieldGenerator);
};
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index bd1c0fde..b7b6039a 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -55,7 +55,11 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_optimize_for.pb.h>
#include <google/protobuf/unittest_embed_optimize_for.pb.h>
+#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER)
+// We exclude this large proto from cmake build because it's too large for
+// visual studio to compile (report internal errors).
#include <google/protobuf/unittest_enormous_descriptor.pb.h>
+#endif
#include <google/protobuf/unittest_no_generic_services.pb.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/compiler/cpp/cpp_helpers.h>
@@ -67,7 +71,9 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/dynamic_message.h>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
@@ -131,6 +137,7 @@ TEST(GeneratedDescriptorTest, IdenticalDescriptors) {
generated_decsriptor_proto.DebugString());
}
+#if !defined(GOOGLE_PROTOBUF_CMAKE_BUILD) && !defined(_MSC_VER)
// Test that generated code has proper descriptors:
// Touch a descriptor generated from an enormous message to validate special
// handling for descriptors exceeding the C++ standard's recommended minimum
@@ -141,6 +148,7 @@ TEST(GeneratedDescriptorTest, EnormousDescriptor) {
EXPECT_TRUE(generated_descriptor != NULL);
}
+#endif
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc
index 43eb0ed5..33c9328f 100644
--- a/src/google/protobuf/compiler/importer_unittest.cc
+++ b/src/google/protobuf/compiler/importer_unittest.cc
@@ -44,6 +44,7 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/compiler/java/java_enum.cc b/src/google/protobuf/compiler/java/java_enum.cc
index 0353b607..8a09f3a8 100644
--- a/src/google/protobuf/compiler/java/java_enum.cc
+++ b/src/google/protobuf/compiler/java/java_enum.cc
@@ -181,8 +181,8 @@ void EnumGenerator::Generate(io::Printer* printer) {
" internalGetValueMap() {\n"
" return internalValueMap;\n"
"}\n"
- "private static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
- " internalValueMap =\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
" new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
" public $classname$ findValueByNumber(int number) {\n"
" return $classname$.valueOf(number);\n"
diff --git a/src/google/protobuf/compiler/java/java_enum_field.cc b/src/google/protobuf/compiler/java/java_enum_field.cc
index 39318a19..558da968 100644
--- a/src/google/protobuf/compiler/java/java_enum_field.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_enum_field_lite.cc b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
index 697a07a7..2c3608c2 100644
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc
new file mode 100644
index 00000000..62186386
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_lite.cc
@@ -0,0 +1,226 @@
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#include <map>
+#include <string>
+
+#include <google/protobuf/compiler/java/java_context.h>
+#include <google/protobuf/compiler/java/java_enum_lite.h>
+#include <google/protobuf/compiler/java/java_doc_comment.h>
+#include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_name_resolver.h>
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/strutil.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+namespace {
+bool EnumHasCustomOptions(const EnumDescriptor* descriptor) {
+ if (descriptor->options().unknown_fields().field_count() > 0) return true;
+ for (int i = 0; i < descriptor->value_count(); ++i) {
+ const EnumValueDescriptor* value = descriptor->value(i);
+ if (value->options().unknown_fields().field_count() > 0) return true;
+ }
+ return false;
+}
+} // namespace
+
+EnumLiteGenerator::EnumLiteGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context)
+ : descriptor_(descriptor), immutable_api_(immutable_api),
+ name_resolver_(context->GetNameResolver()) {
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ const EnumValueDescriptor* value = descriptor_->value(i);
+ const EnumValueDescriptor* canonical_value =
+ descriptor_->FindValueByNumber(value->number());
+
+ if (value == canonical_value) {
+ canonical_values_.push_back(value);
+ } else {
+ Alias alias;
+ alias.value = value;
+ alias.canonical_value = canonical_value;
+ aliases_.push_back(alias);
+ }
+ }
+}
+
+EnumLiteGenerator::~EnumLiteGenerator() {}
+
+void EnumLiteGenerator::Generate(io::Printer* printer) {
+ WriteEnumDocComment(printer, descriptor_);
+ if (HasDescriptorMethods(descriptor_)) {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.ProtocolMessageEnum {\n",
+ "classname", descriptor_->name());
+ } else {
+ printer->Print(
+ "public enum $classname$\n"
+ " implements com.google.protobuf.Internal.EnumLite {\n",
+ "classname", descriptor_->name());
+ }
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ map<string, string> vars;
+ vars["name"] = canonical_values_[i]->name();
+ vars["index"] = SimpleItoa(canonical_values_[i]->index());
+ vars["number"] = SimpleItoa(canonical_values_[i]->number());
+ WriteEnumValueDocComment(printer, canonical_values_[i]);
+ if (canonical_values_[i]->options().deprecated()) {
+ printer->Print("@java.lang.Deprecated\n");
+ }
+ printer->Print(vars,
+ "$name$($index$, $number$),\n");
+ }
+
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print("UNRECOGNIZED(-1, -1),\n");
+ }
+
+ printer->Print(
+ ";\n"
+ "\n");
+
+ // -----------------------------------------------------------------
+
+ for (int i = 0; i < aliases_.size(); i++) {
+ map<string, string> vars;
+ vars["classname"] = descriptor_->name();
+ vars["name"] = aliases_[i].value->name();
+ vars["canonical_name"] = aliases_[i].canonical_value->name();
+ WriteEnumValueDocComment(printer, aliases_[i].value);
+ printer->Print(vars,
+ "public static final $classname$ $name$ = $canonical_name$;\n");
+ }
+
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ map<string, string> vars;
+ vars["name"] = descriptor_->value(i)->name();
+ vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+ WriteEnumValueDocComment(printer, descriptor_->value(i));
+ printer->Print(vars,
+ "public static final int $name$_VALUE = $number$;\n");
+ }
+ printer->Print("\n");
+
+ // -----------------------------------------------------------------
+
+ printer->Print(
+ "\n"
+ "public final int getNumber() {\n");
+ if (SupportUnknownEnumValue(descriptor_->file())) {
+ printer->Print(
+ " if (index == -1) {\n"
+ " throw new java.lang.IllegalArgumentException(\n"
+ " \"Can't get the number of an unknown enum value.\");\n"
+ " }\n");
+ }
+ printer->Print(
+ " return value;\n"
+ "}\n"
+ "\n"
+ "public static $classname$ valueOf(int value) {\n"
+ " switch (value) {\n",
+ "classname", descriptor_->name());
+ printer->Indent();
+ printer->Indent();
+
+ for (int i = 0; i < canonical_values_.size(); i++) {
+ printer->Print(
+ "case $number$: return $name$;\n",
+ "name", canonical_values_[i]->name(),
+ "number", SimpleItoa(canonical_values_[i]->number()));
+ }
+
+ printer->Outdent();
+ printer->Outdent();
+ printer->Print(
+ " default: return null;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ "public static com.google.protobuf.Internal.EnumLiteMap<$classname$>\n"
+ " internalGetValueMap() {\n"
+ " return internalValueMap;\n"
+ "}\n"
+ "private static final com.google.protobuf.Internal.EnumLiteMap<\n"
+ " $classname$> internalValueMap =\n"
+ " new com.google.protobuf.Internal.EnumLiteMap<$classname$>() {\n"
+ " public $classname$ findValueByNumber(int number) {\n"
+ " return $classname$.valueOf(number);\n"
+ " }\n"
+ " };\n"
+ "\n",
+ "classname", descriptor_->name());
+
+ printer->Print(
+ "private final int value;\n\n"
+ "private $classname$(int index, int value) {\n",
+ "classname", descriptor_->name());
+ printer->Print(
+ " this.value = value;\n"
+ "}\n");
+
+ printer->Print(
+ "\n"
+ "// @@protoc_insertion_point(enum_scope:$full_name$)\n",
+ "full_name", descriptor_->full_name());
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+bool EnumLiteGenerator::CanUseEnumValues() {
+ if (canonical_values_.size() != descriptor_->value_count()) {
+ return false;
+ }
+ for (int i = 0; i < descriptor_->value_count(); i++) {
+ if (descriptor_->value(i)->name() != canonical_values_[i]->name()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/compiler/java/java_enum_lite.h b/src/google/protobuf/compiler/java/java_enum_lite.h
new file mode 100644
index 00000000..ee2f5f7a
--- /dev/null
+++ b/src/google/protobuf/compiler/java/java_enum_lite.h
@@ -0,0 +1,99 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+#define GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
+
+#include <string>
+#include <vector>
+#include <google/protobuf/descriptor.h>
+
+namespace google {
+namespace protobuf {
+ namespace compiler {
+ namespace java {
+ class Context; // context.h
+ class ClassNameResolver; // name_resolver.h
+ }
+ }
+ namespace io {
+ class Printer; // printer.h
+ }
+}
+
+namespace protobuf {
+namespace compiler {
+namespace java {
+
+class EnumLiteGenerator {
+ public:
+ explicit EnumLiteGenerator(const EnumDescriptor* descriptor,
+ bool immutable_api,
+ Context* context);
+ ~EnumLiteGenerator();
+
+ void Generate(io::Printer* printer);
+
+ private:
+ const EnumDescriptor* descriptor_;
+
+ // The proto language allows multiple enum constants to have the same numeric
+ // value. Java, however, does not allow multiple enum constants to be
+ // considered equivalent. We treat the first defined constant for any
+ // given numeric value as "canonical" and the rest as aliases of that
+ // canonical value.
+ vector<const EnumValueDescriptor*> canonical_values_;
+
+ struct Alias {
+ const EnumValueDescriptor* value;
+ const EnumValueDescriptor* canonical_value;
+ };
+ vector<Alias> aliases_;
+
+ bool immutable_api_;
+
+ Context* context_;
+ ClassNameResolver* name_resolver_;
+
+ bool CanUseEnumValues();
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumLiteGenerator);
+};
+
+} // namespace java
+} // namespace compiler
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_COMPILER_JAVA_ENUM_LITE_H__
diff --git a/src/google/protobuf/compiler/java/java_field.cc b/src/google/protobuf/compiler/java/java_field.cc
index 3f0fa11f..c5434767 100644
--- a/src/google/protobuf/compiler/java/java_field.cc
+++ b/src/google/protobuf/compiler/java/java_field.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_enum_field.h>
diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h
index 00f3c601..0e24da24 100644
--- a/src/google/protobuf/compiler/java/java_field.h
+++ b/src/google/protobuf/compiler/java/java_field.h
@@ -44,6 +44,7 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/compiler/java/java_helpers.h b/src/google/protobuf/compiler/java/java_helpers.h
index 96d2545f..5392d6d7 100644
--- a/src/google/protobuf/compiler/java/java_helpers.h
+++ b/src/google/protobuf/compiler/java/java_helpers.h
@@ -310,6 +310,12 @@ inline bool SupportFieldPresence(const FileDescriptor* descriptor) {
return descriptor->syntax() != FileDescriptor::SYNTAX_PROTO3;
}
+// Whether generate classes expose public PARSER instances.
+inline bool ExposePublicParser(const FileDescriptor* descriptor) {
+ // TODO(liujisi): Mark the PARSER private in 3.1.x releases.
+ return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
+}
+
// Whether unknown enum values are kept (i.e., not stored in UnknownFieldSet
// but in the message and can be queried using additional getters that return
// ints.
@@ -332,6 +338,15 @@ inline bool PreserveUnknownFields(const Descriptor* descriptor) {
return descriptor->file()->syntax() != FileDescriptor::SYNTAX_PROTO3;
}
+inline bool IsAnyMessage(const Descriptor* descriptor) {
+ return descriptor->full_name() == "google.protobuf.Any";
+}
+
+inline bool CheckUtf8(const FieldDescriptor* descriptor) {
+ return descriptor->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
+ descriptor->file()->options().java_string_check_utf8();
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_map_field.cc b/src/google/protobuf/compiler/java/java_map_field.cc
index 44b86cd7..3e035c89 100644
--- a/src/google/protobuf/compiler/java/java_map_field.cc
+++ b/src/google/protobuf/compiler/java/java_map_field.cc
@@ -314,6 +314,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" internalGetMutable$capitalized_name$().getMutableMap(),\n"
" $name$ValueConverter);\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(
@@ -331,6 +339,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
"getMutable$capitalized_name$Value() {\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$Value(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " getMutable$capitalized_name$Value().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
} else {
WriteFieldDocComment(printer, descriptor_);
@@ -346,6 +362,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
"getMutable$capitalized_name$() {\n"
" return internalGetMutable$capitalized_name$().getMutableMap();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.cc b/src/google/protobuf/compiler/java/java_map_field_lite.cc
index cd1698f0..4fe656d3 100644
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -303,6 +303,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
if (SupportUnknownEnumValue(descriptor_->file())) {
WriteFieldDocComment(printer, descriptor_);
printer->Print(
@@ -321,6 +329,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$Value();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "$deprecation$public Builder putAll$capitalized_name$Value(\n"
+ " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
+ " getMutable$capitalized_name$Value().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
} else {
WriteFieldDocComment(printer, descriptor_);
@@ -337,6 +353,14 @@ GenerateBuilderMembers(io::Printer* printer) const {
" copyOnWrite();\n"
" return instance.getMutable$capitalized_name$();\n"
"}\n");
+ WriteFieldDocComment(printer, descriptor_);
+ printer->Print(
+ variables_,
+ "public Builder putAll$capitalized_name$(\n"
+ " java.util.Map<$type_parameters$> values) {\n"
+ " getMutable$capitalized_name$().putAll(values);\n"
+ " return this;\n"
+ "}\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc
index 09b0fd94..19ba0707 100644
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -255,6 +255,18 @@ void ImmutableMessageGenerator::GenerateInterface(io::Printer* printer) {
field_generators_.get(descriptor_->field(i))
.GenerateInterfaceMembers(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name,
+ "classname",
+ context_->GetNameResolver()->GetImmutableClassName(
+ descriptor_));
+ }
printer->Outdent();
printer->Print("}\n");
@@ -292,8 +304,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
" com.google.protobuf.GeneratedMessage implements\n"
" $extra_interfaces$\n"
" $classname$OrBuilder {\n");
-
- builder_type = "com.google.protobuf.GeneratedMessage.Builder";
+ builder_type = "com.google.protobuf.GeneratedMessage.Builder<?>";
}
printer->Indent();
// Using builder_type, instead of Builder, prevents the Builder class from
@@ -435,6 +446,10 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
"\n");
}
+ if (IsAnyMessage(descriptor_)) {
+ GenerateAnyMethods(printer);
+ }
+
// Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
printer->Print("public static final int $constant_name$ = $number$;\n",
@@ -578,9 +593,8 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Print(
"}\n"
"\n"
- "private int memoizedSerializedSize = -1;\n"
"public int getSerializedSize() {\n"
- " int size = memoizedSerializedSize;\n"
+ " int size = memoizedSize;\n"
" if (size != -1) return size;\n"
"\n"
" size = 0;\n");
@@ -612,7 +626,7 @@ GenerateMessageSerializationMethods(io::Printer* printer) {
printer->Outdent();
printer->Print(
- " memoizedSerializedSize = size;\n"
+ " memoizedSize = size;\n"
" return size;\n"
"}\n"
"\n");
@@ -948,22 +962,58 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
printer->Print("boolean result = true;\n");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
- const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
- bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
- if (check_has_bits) {
+ if (field->containing_oneof() == NULL) {
+ const FieldGeneratorInfo* info = context_->GetFieldGeneratorInfo(field);
+ bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
+ if (check_has_bits) {
+ printer->Print(
+ "result = result && (has$name$() == other.has$name$());\n"
+ "if (has$name$()) {\n",
+ "name", info->capitalized_name);
+ printer->Indent();
+ }
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ if (check_has_bits) {
+ printer->Outdent();
+ printer->Print(
+ "}\n");
+ }
+ }
+ }
+
+ // Compare oneofs.
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "result = result && get$oneof_capitalized_name$Case().equals(\n"
+ " other.get$oneof_capitalized_name$Case());\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name);
+ printer->Print(
+ "if (!result) return false;\n"
+ "switch ($oneof_name$Case_) {\n",
+ "oneof_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->name);
+ printer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
printer->Print(
- "result = result && (has$name$() == other.has$name$());\n"
- "if (has$name$()) {\n",
- "name", info->capitalized_name);
+ "case $field_number$:\n",
+ "field_number",
+ SimpleItoa(field->number()));
printer->Indent();
- }
- field_generators_.get(field).GenerateEqualsCode(printer);
- if (check_has_bits) {
+ field_generators_.get(field).GenerateEqualsCode(printer);
+ printer->Print("break;\n");
printer->Outdent();
- printer->Print(
- "}\n");
}
+ printer->Print(
+ "case 0:\n"
+ "default:\n");
+ printer->Outdent();
+ printer->Print("}\n");
}
+
if (PreserveUnknownFields(descriptor_)) {
// Always consider unknown fields for equality. This will sometimes return
// false for non-canonical ordering when running in LITE_RUNTIME but it's
@@ -1198,8 +1248,11 @@ GenerateParsingConstructor(io::Printer* printer) {
// ===================================================================
void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
- "public static final com.google.protobuf.Parser<$classname$> PARSER =\n"
- " new com.google.protobuf.AbstractParser<$classname$>() {\n",
+ "$visibility$ static final com.google.protobuf.Parser<$classname$>\n"
+ " PARSER = new com.google.protobuf.AbstractParser<$classname$>() {\n",
+ "visibility",
+ ExposePublicParser(descriptor_->file()) ? "@java.lang.Deprecated public"
+ : "private",
"classname", descriptor_->name());
printer->Indent();
printer->Print(
@@ -1250,6 +1303,10 @@ void ImmutableMessageGenerator::GenerateParser(io::Printer* printer) {
"\n");
printer->Print(
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return PARSER;\n"
+ "}\n"
+ "\n"
"@java.lang.Override\n"
"public com.google.protobuf.Parser<$classname$> getParserForType() {\n"
" return PARSER;\n"
@@ -1269,6 +1326,50 @@ void ImmutableMessageGenerator::GenerateInitializers(io::Printer* printer) {
}
+void ImmutableMessageGenerator::GenerateAnyMethods(io::Printer* printer) {
+ printer->Print(
+ "private static String getTypeUrl(\n"
+ " com.google.protobuf.Descriptors.Descriptor descriptor) {\n"
+ " return \"type.googleapis.com/\" + descriptor.getFullName();\n"
+ "}\n"
+ "\n"
+ "public static <T extends com.google.protobuf.Message> Any pack(\n"
+ " T message) {\n"
+ " return Any.newBuilder()\n"
+ " .setTypeUrl(getTypeUrl(message.getDescriptorForType()))\n"
+ " .setValue(message.toByteString())\n"
+ " .build();\n"
+ "}\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> boolean is(\n"
+ " java.lang.Class<T> clazz) {\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " return getTypeUrl().equals(\n"
+ " getTypeUrl(defaultInstance.getDescriptorForType()));\n"
+ "}\n"
+ "\n"
+ "private volatile com.google.protobuf.Message cachedUnpackValue;\n"
+ "\n"
+ "public <T extends com.google.protobuf.Message> T unpack(\n"
+ " java.lang.Class<T> clazz)\n"
+ " throws com.google.protobuf.InvalidProtocolBufferException {\n"
+ " if (!is(clazz)) {\n"
+ " throw new com.google.protobuf.InvalidProtocolBufferException(\n"
+ " \"Type of the Any messsage does not match the given class.\");\n"
+ " }\n"
+ " if (cachedUnpackValue != null) {\n"
+ " return (T) cachedUnpackValue;\n"
+ " }\n"
+ " T defaultInstance =\n"
+ " com.google.protobuf.Internal.getDefaultInstance(clazz);\n"
+ " T result = (T) defaultInstance.getParserForType()\n"
+ " .parseFrom(getValue());\n"
+ " cachedUnpackValue = result;\n"
+ " return result;\n"
+ "}\n");
+}
+
} // namespace java
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/java/java_message.h b/src/google/protobuf/compiler/java/java_message.h
index c3c37765..be5bfb07 100644
--- a/src/google/protobuf/compiler/java/java_message.h
+++ b/src/google/protobuf/compiler/java/java_message.h
@@ -122,6 +122,7 @@ class ImmutableMessageGenerator : public MessageGenerator {
void GenerateEqualsAndHashCode(io::Printer* printer);
void GenerateParser(io::Printer* printer);
void GenerateParsingConstructor(io::Printer* printer);
+ void GenerateAnyMethods(io::Printer* printer);
Context* context_;
ClassNameResolver* name_resolver_;
diff --git a/src/google/protobuf/compiler/java/java_message_field.cc b/src/google/protobuf/compiler/java/java_message_field.cc
index b180b4a7..b5f8e626 100644
--- a/src/google/protobuf/compiler/java/java_message_field.cc
+++ b/src/google/protobuf/compiler/java/java_message_field.cc
@@ -452,11 +452,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -736,11 +736,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$oneof_name$_ =\n"
+ " input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -1232,11 +1233,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
- "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
+ "$name$_.add(input.readMessage($type$.parser(), extensionRegistry));\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.cc b/src/google/protobuf/compiler/java/java_message_field_lite.cc
index 8332202c..356520ec 100644
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -310,11 +310,11 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -521,11 +521,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$oneof_name$_ = input.readGroup($number$, $type$.PARSER,\n"
+ "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry);\n");
} else {
printer->Print(variables_,
- "$oneof_name$_ = input.readMessage($type$.PARSER, extensionRegistry);\n");
+ "$oneof_name$_ =\n"
+ " input.readMessage($type$.parser(), extensionRegistry);\n");
}
printer->Print(variables_,
@@ -885,11 +886,12 @@ GenerateParsingCode(io::Printer* printer) const {
if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
printer->Print(variables_,
- "$name$_.add(input.readGroup($number$, $type$.PARSER,\n"
+ "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
" extensionRegistry));\n");
} else {
printer->Print(variables_,
- "$name$_.add(input.readMessage($type$.PARSER, extensionRegistry));\n");
+ "$name$_.add(\n"
+ " input.readMessage($type$.parser(), extensionRegistry));\n");
}
}
diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc
index 3accee92..8b6c75b8 100644
--- a/src/google/protobuf/compiler/java/java_message_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_lite.cc
@@ -45,7 +45,7 @@
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
-#include <google/protobuf/compiler/java/java_enum.h>
+#include <google/protobuf/compiler/java/java_enum_lite.h>
#include <google/protobuf/compiler/java/java_extension.h>
#include <google/protobuf/compiler/java/java_generator_factory.h>
#include <google/protobuf/compiler/java/java_helpers.h>
@@ -143,6 +143,17 @@ void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) {
field_generators_.get(descriptor_->field(i))
.GenerateInterfaceMembers(printer);
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ printer->Print(
+ "\n"
+ "public $classname$.$oneof_capitalized_name$Case "
+ "get$oneof_capitalized_name$Case();\n",
+ "oneof_capitalized_name",
+ context_->GetOneofGeneratorInfo(
+ descriptor_->oneof_decl(i))->capitalized_name,
+ "classname",
+ context_->GetNameResolver()->GetImmutableClassName(descriptor_));
+ }
printer->Outdent();
printer->Print("}\n");
@@ -190,7 +201,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
// Nested types
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
- EnumGenerator(descriptor_->enum_type(i), true, context_)
+ EnumLiteGenerator(descriptor_->enum_type(i), true, context_)
.Generate(printer);
}
@@ -321,12 +332,12 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Print(
"protected final Object dynamicMethod(\n"
" com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n"
- " Object... args) {\n"
+ " Object arg0, Object arg1) {\n"
" switch (method) {\n"
" case PARSE_PARTIAL_FROM: {\n"
" return new $classname$("
- " (com.google.protobuf.CodedInputStream) args[0],\n"
- " (com.google.protobuf.ExtensionRegistryLite) args[1]);\n"
+ " (com.google.protobuf.CodedInputStream) arg0,\n"
+ " (com.google.protobuf.ExtensionRegistryLite) arg1);\n"
" }\n"
" case NEW_INSTANCE: {\n"
" return new $classname$(\n"
@@ -370,7 +381,25 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
printer->Outdent();
printer->Print(
- "}\n");
+ "}\n"
+ "case GET_DEFAULT_INSTANCE: {\n"
+ " return DEFAULT_INSTANCE;\n"
+ "}\n"
+ "case GET_PARSER: {\n"
+ // Generally one would use the lazy initialization holder pattern for
+ // manipulating static fields but that has exceptional cost on Android as
+ // it will generate an extra class for every message. Instead, use the
+ // double-check locking pattern which works just as well.
+ " if (PARSER == null) {"
+ " synchronized ($classname$.class) {\n"
+ " if (PARSER == null) {\n"
+ " PARSER = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
+ " }\n"
+ " }\n"
+ " }\n"
+ " return PARSER;\n"
+ "}\n",
+ "classname", name_resolver_->GetImmutableClassName(descriptor_));
printer->Outdent();
printer->Outdent();
@@ -413,18 +442,6 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
GenerateParser(printer);
- // LITE_RUNTIME uses this to implement the *ForType methods at the
- // GeneratedMessageLite level.
- printer->Print(
- "static {\n"
- " com.google.protobuf.GeneratedMessageLite.onLoad(\n"
- " $classname$.class, new com.google.protobuf.GeneratedMessageLite\n"
- " .PrototypeHolder<$classname$, Builder>(\n"
- " DEFAULT_INSTANCE, PARSER));"
- "}\n"
- "\n",
- "classname", name_resolver_->GetImmutableClassName(descriptor_));
-
// Extensions must be declared after the DEFAULT_INSTANCE is initialized
// because the DEFAULT_INSTANCE is used by the extension to lazily retrieve
// the outer class's FileDescriptor.
@@ -554,54 +571,54 @@ GenerateParseFromMethods(io::Printer* printer) {
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data);\n"
+ " return parser().parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.ByteString data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data, extensionRegistry);\n"
+ " return parser().parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(byte[] data)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data);\n"
+ " return parser().parseFrom(data);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" byte[] data,\n"
" com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n"
" throws com.google.protobuf.InvalidProtocolBufferException {\n"
- " return PARSER.parseFrom(data, extensionRegistry);\n"
+ " return parser().parseFrom(data, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return parser().parseFrom(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 PARSER.parseFrom(input, extensionRegistry);\n"
+ " return parser().parseFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseDelimitedFrom(java.io.InputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseDelimitedFrom(input);\n"
+ " return parser().parseDelimitedFrom(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 PARSER.parseDelimitedFrom(input, extensionRegistry);\n"
+ " return parser().parseDelimitedFrom(input, extensionRegistry);\n"
"}\n"
"public static $classname$ parseFrom(\n"
" com.google.protobuf.CodedInputStream input)\n"
" throws java.io.IOException {\n"
- " return PARSER.parseFrom(input);\n"
+ " return parser().parseFrom(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 PARSER.parseFrom(input, extensionRegistry);\n"
+ " return parser().parseFrom(input, extensionRegistry);\n"
"}\n"
"\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
@@ -652,7 +669,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
"if (isInitialized == 1) return DEFAULT_INSTANCE;\n"
"if (isInitialized == 0) return null;\n"
"\n"
- "boolean shouldMemoize = ((Boolean) args[0]).booleanValue();\n");
+ "boolean shouldMemoize = ((Boolean) arg0).booleanValue();\n");
// Check that all required fields in this message are set.
// TODO(kenton): We can optimize this when we switch to putting all the
@@ -778,7 +795,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
.GenerateDynamicMethodMakeImmutableCode(printer);
}
printer->Print(
- "return null;");
+ "return null;\n");
}
// ===================================================================
@@ -786,7 +803,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMakeImmutable(
void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder(
io::Printer* printer) {
printer->Print(
- "return new Builder();");
+ "return new Builder();\n");
}
// ===================================================================
@@ -796,9 +813,8 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFrom(
printer->Print(
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
- "Object arg = args[0];\n"
- "if (arg == $classname$.getDefaultInstance()) return this;\n"
- "$classname$ other = ($classname$) arg;\n",
+ "if (arg0 == $classname$.getDefaultInstance()) return this;\n"
+ "$classname$ other = ($classname$) arg0;\n",
"classname", name_resolver_->GetImmutableClassName(descriptor_));
for (int i = 0; i < descriptor_->field_count(); i++) {
@@ -1151,9 +1167,11 @@ GenerateParsingConstructor(io::Printer* printer) {
// ===================================================================
void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) {
printer->Print(
- "public static final com.google.protobuf.Parser<$classname$> PARSER =\n"
- " new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
- "\n",
+ "private static volatile com.google.protobuf.Parser<$classname$> PARSER;\n"
+ "\n"
+ "public static com.google.protobuf.Parser<$classname$> parser() {\n"
+ " return DEFAULT_INSTANCE.getParserForType();\n"
+ "}\n",
"classname", descriptor_->name());
}
diff --git a/src/google/protobuf/compiler/java/java_primitive_field.cc b/src/google/protobuf/compiler/java/java_primitive_field.cc
index 7bebe12a..178bbe19 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
index 217ff9b6..392333b8 100644
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -35,6 +35,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
diff --git a/src/google/protobuf/compiler/java/java_service.cc b/src/google/protobuf/compiler/java/java_service.cc
index 7baead15..11bfc12d 100644
--- a/src/google/protobuf/compiler/java/java_service.cc
+++ b/src/google/protobuf/compiler/java/java_service.cc
@@ -39,7 +39,6 @@
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_name_resolver.h>
#include <google/protobuf/io/printer.h>
-#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
diff --git a/src/google/protobuf/compiler/java/java_string_field.cc b/src/google/protobuf/compiler/java/java_string_field.cc
index 68e863cc..72ebaeca 100644
--- a/src/google/protobuf/compiler/java/java_string_field.cc
+++ b/src/google/protobuf/compiler/java/java_string_field.cc
@@ -36,6 +36,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
@@ -77,6 +78,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
" if (value == null) {\n"
" throw new NullPointerException();\n"
" }\n";
+ (*variables)["writeString"] =
+ "com.google.protobuf.GeneratedMessage.writeString";
+ (*variables)["computeStringSize"] =
+ "com.google.protobuf.GeneratedMessage.computeStringSize";
// TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
// by the proto compiler
@@ -126,10 +131,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
GenerateSetBitToLocal(messageBitIndex);
}
-bool CheckUtf8(const FieldDescriptor* descriptor) {
- return descriptor->file()->options().java_string_check_utf8();
-}
-
} // namespace
// ===================================================================
@@ -433,7 +434,7 @@ void ImmutableStringFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " $writeString$(output, $number$, $name$_);\n"
"}\n");
}
@@ -441,8 +442,7 @@ void ImmutableStringFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " size += $computeStringSize$($number$, $name$_);\n"
"}\n");
}
@@ -689,7 +689,7 @@ void ImmutableStringOneofFieldGenerator::
GenerateSerializationCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " $writeString$(output, $number$, $oneof_name$_);\n"
"}\n");
}
@@ -697,8 +697,7 @@ void ImmutableStringOneofFieldGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " size += $computeStringSize$($number$, $oneof_name$_);\n"
"}\n");
}
@@ -1007,12 +1006,12 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ " writeStringNoTag(output, $name$_.getRaw(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ " $writeString$(output, $number$, $name$_.getRaw(i));\n"
"}\n");
}
}
@@ -1026,8 +1025,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ " dataSize += computeStringSizeNoTag($name$_.getRaw(i));\n"
"}\n");
printer->Print(
diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.cc b/src/google/protobuf/compiler/java/java_string_field_lite.cc
index 51bb245c..092e3c29 100644
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -36,6 +36,7 @@
#include <map>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
@@ -64,7 +65,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, info, variables);
- (*variables)["empty_list"] = "emptyLazyStringArrayList()";
+ (*variables)["empty_list"] =
+ "com.google.protobuf.GeneratedMessageLite.emptyProtobufList()";
(*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
(*variables)["default_init"] =
@@ -101,7 +103,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
(*variables)["clear_has_field_bit_message"] = "";
(*variables)["is_field_present_message"] =
- "!get" + (*variables)["capitalized_name"] + "Bytes().isEmpty()";
+ "!get" + (*variables)["capitalized_name"] + ".isEmpty()";
}
// For repeated builders, the underlying list tracks mutability state.
@@ -113,10 +115,6 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
GenerateSetBitToLocal(messageBitIndex);
}
-bool CheckUtf8(const FieldDescriptor* descriptor) {
- return descriptor->file()->options().java_string_check_utf8();
-}
-
} // namespace
// ===================================================================
@@ -144,8 +142,9 @@ int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
return 0;
}
-// A note about how strings are handled. This code used to just store a String
-// in the Message. This had two issues:
+// A note about how strings are handled. In the SPEED and CODE_SIZE runtimes,
+// strings are not stored as java.lang.String in the Message because of two
+// issues:
//
// 1. It wouldn't roundtrip byte arrays that were not vaid UTF-8 encoded
// strings, but rather fields that were raw bytes incorrectly marked
@@ -160,22 +159,14 @@ int ImmutableStringFieldLiteGenerator::GetNumBitsForBuilder() const {
// it many cases, the field is never even read by the application code. This
// avoids unnecessary conversions in the common use cases.
//
-// So now, the field for String is maintained as an Object reference which can
-// either store a String or a ByteString. The code uses an instanceof check
-// to see which one it has and converts to the other one if needed. It remembers
-// the last value requested (in a thread safe manner) as this is most likely
-// the one needed next. The thread safety is such that if two threads both
-// convert the field because the changes made by each thread were not visible to
-// the other, they may cause a conversion to happen more times than would
-// otherwise be necessary. This was deemed better than adding synchronization
-// overhead. It will not cause any corruption issues or affect the behavior of
-// the API. The instanceof check is also highly optimized in the JVM and we
-// decided it was better to reduce the memory overhead by not having two
-// separate fields but rather use dynamic type checking.
-//
-// For single fields, the logic for this is done inside the generated code. For
-// repeated fields, the logic is done in LazyStringArrayList and
-// UnmodifiableLazyStringList.
+// In the LITE_RUNTIME, we store strings as java.lang.String because we assume
+// that the users of this runtime are not subject to proto1 constraints and are
+// running code on devices that are user facing. That is, the developers are
+// properly incentivized to only fetch the data they need to read and wish to
+// reduce the number of allocations incurred when running on a user's device.
+
+// TODO(dweis): Consider dropping all of the *Bytes() methods. They really
+// shouldn't be necessary or used on devices.
void ImmutableStringFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
if (SupportFieldPresence(descriptor_->file())) {
@@ -195,7 +186,7 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void ImmutableStringFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private java.lang.Object $name$_;\n");
+ "private java.lang.String $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
if (SupportFieldPresence(descriptor_->file())) {
@@ -209,40 +200,13 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
- " java.lang.Object ref = $name$_;\n"
- " if (ref instanceof java.lang.String) {\n"
- " return (java.lang.String) ref;\n"
- " } else {\n"
- " com.google.protobuf.ByteString bs = \n"
- " (com.google.protobuf.ByteString) ref;\n"
- " java.lang.String s = bs.toStringUtf8();\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " $name$_ = s;\n");
- } else {
- printer->Print(variables_,
- " if (bs.isValidUtf8()) {\n"
- " $name$_ = s;\n"
- " }\n");
- }
- printer->Print(variables_,
- " return s;\n"
- " }\n"
+ " return $name$_;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
- " java.lang.Object ref = $name$_;\n"
- " if (ref instanceof java.lang.String) {\n"
- " com.google.protobuf.ByteString b = \n"
- " com.google.protobuf.ByteString.copyFromUtf8(\n"
- " (java.lang.String) ref);\n"
- " $name$_ = b;\n"
- " return b;\n"
- " } else {\n"
- " return (com.google.protobuf.ByteString) ref;\n"
- " }\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8($name$_);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -273,7 +237,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" $set_has_field_bit_message$\n"
- " $name$_ = value;\n"
+ " $name$_ = value.toStringUtf8();\n"
"}\n");
}
@@ -368,7 +332,7 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readStringRequireUtf8();\n"
"$set_has_field_bit_message$\n"
"$name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
@@ -377,11 +341,6 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readString();\n"
"$set_has_field_bit_message$\n"
"$name$_ = s;\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n"
- "$set_has_field_bit_message$\n"
- "$name$_ = bs;\n");
}
}
@@ -392,18 +351,24 @@ GenerateParsingDoneCode(io::Printer* printer) const {
void ImmutableStringFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " output.writeString($number$, get$capitalized_name$());\n"
"}\n");
}
void ImmutableStringFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($is_field_present_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " .computeStringSize($number$, get$capitalized_name$());\n"
"}\n");
}
@@ -458,51 +423,22 @@ GenerateMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public java.lang.String get$capitalized_name$() {\n"
- " java.lang.Object ref $default_init$;\n"
+ " java.lang.String ref $default_init$;\n"
" if ($has_oneof_case_message$) {\n"
- " ref = $oneof_name$_;\n"
- " }\n"
- " if (ref instanceof java.lang.String) {\n"
- " return (java.lang.String) ref;\n"
- " } else {\n"
- " com.google.protobuf.ByteString bs = \n"
- " (com.google.protobuf.ByteString) ref;\n"
- " java.lang.String s = bs.toStringUtf8();\n");
- if (CheckUtf8(descriptor_)) {
- printer->Print(variables_,
- " if ($has_oneof_case_message$) {\n"
- " $oneof_name$_ = s;\n"
- " }\n");
- } else {
- printer->Print(variables_,
- " if (bs.isValidUtf8() && ($has_oneof_case_message$)) {\n"
- " $oneof_name$_ = s;\n"
- " }\n");
- }
- printer->Print(variables_,
- " return s;\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
" }\n"
+ " return ref;\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes() {\n"
- " java.lang.Object ref $default_init$;\n"
+ " java.lang.String ref $default_init$;\n"
" if ($has_oneof_case_message$) {\n"
- " ref = $oneof_name$_;\n"
- " }\n"
- " if (ref instanceof java.lang.String) {\n"
- " com.google.protobuf.ByteString b = \n"
- " com.google.protobuf.ByteString.copyFromUtf8(\n"
- " (java.lang.String) ref);\n"
- " if ($has_oneof_case_message$) {\n"
- " $oneof_name$_ = b;\n"
- " }\n"
- " return b;\n"
- " } else {\n"
- " return (com.google.protobuf.ByteString) ref;\n"
+ " ref = (java.lang.String) $oneof_name$_;\n"
" }\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(ref);\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -533,7 +469,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" $set_oneof_case_message$;\n"
- " $oneof_name$_ = value;\n"
+ " $oneof_name$_ = value.toStringUtf8();\n"
"}\n");
}
@@ -603,7 +539,7 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readStringRequireUtf8();\n"
"$set_oneof_case_message$;\n"
"$oneof_name$_ = s;\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
@@ -612,28 +548,29 @@ GenerateParsingCode(io::Printer* printer) const {
"String s = input.readString();\n"
"$set_oneof_case_message$;\n"
"$oneof_name$_ = s;\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n"
- "$set_oneof_case_message$;\n"
- "$oneof_name$_ = bs;\n");
}
}
void ImmutableStringOneofFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
- " output.writeBytes($number$, get$capitalized_name$Bytes());\n"
+ " output.writeString($number$, get$capitalized_name$());\n"
"}\n");
}
void ImmutableStringOneofFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"if ($has_oneof_case_message$) {\n"
" size += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSize($number$, get$capitalized_name$Bytes());\n"
+ " .computeStringSize($number$, get$capitalized_name$());\n"
"}\n");
}
@@ -667,7 +604,7 @@ void RepeatedImmutableStringFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$com.google.protobuf.ProtocolStringList\n"
+ "$deprecation$java.util.List<String>\n"
" get$capitalized_name$List();\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -685,12 +622,11 @@ GenerateInterfaceMembers(io::Printer* printer) const {
void RepeatedImmutableStringFieldLiteGenerator::
GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
- "private com.google.protobuf.LazyStringArrayList $name$_;\n");
+ "private com.google.protobuf.Internal.ProtobufList<String> $name$_;\n");
PrintExtraFieldInfo(variables_, printer);
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$public com.google.protobuf.ProtocolStringList\n"
- " get$capitalized_name$List() {\n"
+ "$deprecation$public java.util.List<String> get$capitalized_name$List() {\n"
" return $name$_;\n" // note: unmodifiable list
"}\n");
WriteFieldDocComment(printer, descriptor_);
@@ -707,7 +643,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"$deprecation$public com.google.protobuf.ByteString\n"
" get$capitalized_name$Bytes(int index) {\n"
- " return $name$_.getByteString(index);\n"
+ " return com.google.protobuf.ByteString.copyFromUtf8(\n"
+ " $name$_.get(index));\n"
"}\n");
if (descriptor_->options().packed() &&
@@ -719,7 +656,8 @@ GenerateMembers(io::Printer* printer) const {
printer->Print(variables_,
"private void ensure$capitalized_name$IsMutable() {\n"
" if (!$is_mutable$) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList($name$_);\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList(\n"
+ " $name$_);\n"
" }\n"
"}\n");
@@ -764,7 +702,7 @@ GenerateMembers(io::Printer* printer) const {
}
printer->Print(variables_,
" ensure$capitalized_name$IsMutable();\n"
- " $name$_.add(value);\n"
+ " $name$_.add(value.toStringUtf8());\n"
"}\n");
}
@@ -772,10 +710,10 @@ void RepeatedImmutableStringFieldLiteGenerator::
GenerateBuilderMembers(io::Printer* printer) const {
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
- "$deprecation$public com.google.protobuf.ProtocolStringList\n"
+ "$deprecation$public java.util.List<String>\n"
" get$capitalized_name$List() {\n"
- " return ((com.google.protobuf.LazyStringList)\n"
- " instance.get$capitalized_name$List()).getUnmodifiableView();\n"
+ " return java.util.Collections.unmodifiableList(\n"
+ " instance.get$capitalized_name$List());\n"
"}\n");
WriteFieldDocComment(printer, descriptor_);
printer->Print(variables_,
@@ -875,20 +813,17 @@ GenerateParsingCode(io::Printer* printer) const {
if (CheckUtf8(descriptor_)) {
printer->Print(variables_,
"String s = input.readStringRequireUtf8();\n");
- } else if (!HasDescriptorMethods(descriptor_->file())) {
+ } else {
// Lite runtime should attempt to reduce allocations by attempting to
// construct the string directly from the input stream buffer. This avoids
// spurious intermediary ByteString allocations, cutting overall allocations
// in half.
printer->Print(variables_,
"String s = input.readString();\n");
- } else {
- printer->Print(variables_,
- "com.google.protobuf.ByteString bs = input.readBytes();\n");
}
printer->Print(variables_,
"if (!$is_mutable$) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
"}\n");
if (CheckUtf8(descriptor_) || !HasDescriptorMethods(descriptor_->file())) {
printer->Print(variables_,
@@ -905,7 +840,7 @@ GenerateParsingCodeFromPacked(io::Printer* printer) const {
"int length = input.readRawVarint32();\n"
"int limit = input.pushLimit(length);\n"
"if (!$is_mutable$ && input.getBytesUntilLimit() > 0) {\n"
- " $name$_ = new com.google.protobuf.LazyStringArrayList();\n"
+ " $name$_ = com.google.protobuf.GeneratedMessageLite.newProtobufList();\n"
"}\n"
"while (input.getBytesUntilLimit() > 0) {\n");
if (CheckUtf8(descriptor_)) {
@@ -932,6 +867,9 @@ GenerateParsingDoneCode(io::Printer* printer) const {
void RepeatedImmutableStringFieldLiteGenerator::
GenerateSerializationCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by serializing the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
if (descriptor_->options().packed()) {
printer->Print(variables_,
"if (get$capitalized_name$List().size() > 0) {\n"
@@ -939,18 +877,21 @@ GenerateSerializationCode(io::Printer* printer) const {
" output.writeRawVarint32($name$MemoizedSerializedSize);\n"
"}\n"
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.write$capitalized_type$NoTag($name$_.get(i));\n"
+ " output.writeStringNoTag($name$_.get(i));\n"
"}\n");
} else {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
- " output.writeBytes($number$, $name$_.getByteString(i));\n"
+ " output.writeString($number$, $name$_.get(i));\n"
"}\n");
}
}
void RepeatedImmutableStringFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer* printer) const {
+ // Lite runtime should reduce allocations by computing on the string directly.
+ // This avoids spurious intermediary ByteString allocations, cutting overall
+ // allocations in half.
printer->Print(variables_,
"{\n"
" int dataSize = 0;\n");
@@ -959,7 +900,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
printer->Print(variables_,
"for (int i = 0; i < $name$_.size(); i++) {\n"
" dataSize += com.google.protobuf.CodedOutputStream\n"
- " .computeBytesSizeNoTag($name$_.getByteString(i));\n"
+ " .computeStringSizeNoTag($name$_.get(i));\n"
"}\n");
printer->Print(
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index a2eeee2d..4d018425 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -44,6 +44,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/io/tokenizer.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
@@ -938,6 +939,42 @@ void Parser::GenerateMapEntry(const MapField& map_field,
} else {
value_field->set_type_name(map_field.value_type_name);
}
+ // Propagate the "enforce_utf8" option to key and value fields if they
+ // are strings. This helps simplify the implementation of code generators
+ // and also reflection-based parsing code.
+ //
+ // The following definition:
+ // message Foo {
+ // map<string, string> value = 1 [enforce_utf8 = false];
+ // }
+ // will be interpreted as:
+ // message Foo {
+ // message ValueEntry {
+ // option map_entry = true;
+ // string key = 1 [enforce_utf8 = false];
+ // string value = 2 [enforce_utf8 = false];
+ // }
+ // repeated ValueEntry value = 1 [enforce_utf8 = false];
+ // }
+ //
+ // TODO(xiaofeng): Remove this when the "enforce_utf8" option is removed
+ // from protocol compiler.
+ for (int i = 0; i < field->options().uninterpreted_option_size(); ++i) {
+ const UninterpretedOption& option =
+ field->options().uninterpreted_option(i);
+ if (option.name_size() == 1 &&
+ option.name(0).name_part() == "enforce_utf8" &&
+ !option.name(0).is_extension()) {
+ if (key_field->type() == FieldDescriptorProto::TYPE_STRING) {
+ key_field->mutable_options()->add_uninterpreted_option()
+ ->CopyFrom(option);
+ }
+ if (value_field->type() == FieldDescriptorProto::TYPE_STRING) {
+ value_field->mutable_options()->add_uninterpreted_option()
+ ->CopyFrom(option);
+ }
+ }
+ }
}
bool Parser::ParseFieldOptions(FieldDescriptorProto* field,
diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h
index 16012e96..007b001c 100644
--- a/src/google/protobuf/compiler/parser.h
+++ b/src/google/protobuf/compiler/parser.h
@@ -323,7 +323,7 @@ class LIBPROTOBUF_EXPORT Parser {
const LocationRecorder& service_location,
const FileDescriptorProto* containing_file);
- // Parse one statement within a message, enum, or service block, inclunding
+ // Parse one statement within a message, enum, or service block, including
// final semicolon.
bool ParseMessageStatement(DescriptorProto* message,
const LocationRecorder& message_location,
@@ -364,7 +364,7 @@ class LIBPROTOBUF_EXPORT Parser {
const LocationRecorder& extensions_location,
const FileDescriptorProto* containing_file);
- // Parse an "reserved" declaration.
+ // Parse a "reserved" declaration.
bool ParseReserved(DescriptorProto* message,
const LocationRecorder& message_location);
bool ParseReservedNames(DescriptorProto* message,
@@ -415,7 +415,7 @@ class LIBPROTOBUF_EXPORT Parser {
Message* mutable_options);
// Parse "required", "optional", or "repeated" and fill in "label"
- // with the value. Returns true if shuch a label is consumed.
+ // with the value. Returns true if such a label is consumed.
bool ParseLabel(FieldDescriptorProto::Label* label,
const FileDescriptorProto* containing_file);
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc
index cdcaffde..2bebf1f3 100644
--- a/src/google/protobuf/compiler/plugin.cc
+++ b/src/google/protobuf/compiler/plugin.cc
@@ -48,6 +48,7 @@
#include <unistd.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/compiler/plugin.pb.h>
#include <google/protobuf/compiler/code_generator.h>
diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc
index e7890fae..0792d875 100644
--- a/src/google/protobuf/compiler/plugin.pb.cc
+++ b/src/google/protobuf/compiler/plugin.pb.cc
@@ -340,10 +340,10 @@ void CodeGeneratorRequest::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorRequest)
// repeated string file_to_generate = 1;
for (int i = 0; i < this->file_to_generate_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->file_to_generate(i).data(), this->file_to_generate(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->file_to_generate(i).data(), this->file_to_generate(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->file_to_generate(i), output);
}
@@ -629,28 +629,28 @@ int CodeGeneratorRequest::proto_file_size() const {
void CodeGeneratorRequest::clear_proto_file() {
proto_file_.Clear();
}
- const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
+const ::google::protobuf::FileDescriptorProto& CodeGeneratorRequest::proto_file(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Get(index);
}
- ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
+::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::mutable_proto_file(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Mutable(index);
}
- ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
+::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_file() {
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-CodeGeneratorRequest::proto_file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
- return proto_file_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return &proto_file_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1535,28 +1535,28 @@ int CodeGeneratorResponse::file_size() const {
void CodeGeneratorResponse::clear_file() {
file_.Clear();
}
- const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
+const ::google::protobuf::compiler::CodeGeneratorResponse_File& CodeGeneratorResponse::file(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Get(index);
}
- ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
+::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::mutable_file(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Mutable(index);
}
- ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
+::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorResponse::add_file() {
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
-CodeGeneratorResponse::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
- return file_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return &file_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h
index 6fcaea2e..ab79bdae 100644
--- a/src/google/protobuf/compiler/plugin.pb.h
+++ b/src/google/protobuf/compiler/plugin.pb.h
@@ -144,10 +144,10 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message
const ::google::protobuf::FileDescriptorProto& proto_file(int index) const;
::google::protobuf::FileDescriptorProto* mutable_proto_file(int index);
::google::protobuf::FileDescriptorProto* add_proto_file();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
- proto_file() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
mutable_proto_file();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+ proto_file() const;
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorRequest)
private:
@@ -378,10 +378,10 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag
const ::google::protobuf::compiler::CodeGeneratorResponse_File& file(int index) const;
::google::protobuf::compiler::CodeGeneratorResponse_File* mutable_file(int index);
::google::protobuf::compiler::CodeGeneratorResponse_File* add_file();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
- file() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
mutable_file();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+ file() const;
// @@protoc_insertion_point(class_scope:google.protobuf.compiler.CodeGeneratorResponse)
private:
@@ -534,16 +534,16 @@ inline ::google::protobuf::FileDescriptorProto* CodeGeneratorRequest::add_proto_
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return proto_file_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-CodeGeneratorRequest::proto_file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
- return proto_file_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
CodeGeneratorRequest::mutable_proto_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
return &proto_file_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+CodeGeneratorRequest::proto_file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorRequest.proto_file)
+ return proto_file_;
+}
// -------------------------------------------------------------------
@@ -784,16 +784,16 @@ inline ::google::protobuf::compiler::CodeGeneratorResponse_File* CodeGeneratorRe
// @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorResponse.file)
return file_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
-CodeGeneratorResponse::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
- return file_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >*
CodeGeneratorResponse::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.CodeGeneratorResponse.file)
return &file_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::CodeGeneratorResponse_File >&
+CodeGeneratorResponse::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.compiler.CodeGeneratorResponse.file)
+ return file_;
+}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc
index d4c4c405..e81af700 100644
--- a/src/google/protobuf/compiler/python/python_generator.cc
+++ b/src/google/protobuf/compiler/python/python_generator.cc
@@ -57,6 +57,7 @@
#include <google/protobuf/compiler/python/python_generator.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/printer.h>
diff --git a/src/google/protobuf/compiler/python/python_generator.h b/src/google/protobuf/compiler/python/python_generator.h
index 2ddac601..aa0f5fce 100644
--- a/src/google/protobuf/compiler/python/python_generator.h
+++ b/src/google/protobuf/compiler/python/python_generator.h
@@ -38,6 +38,7 @@
#include <string>
#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/compiler/subprocess.cc b/src/google/protobuf/compiler/subprocess.cc
index a3cff1f8..85429924 100644
--- a/src/google/protobuf/compiler/subprocess.cc
+++ b/src/google/protobuf/compiler/subprocess.cc
@@ -42,6 +42,7 @@
#include <signal.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/substitute.h>
diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc
index 2855c377..5256b83c 100644
--- a/src/google/protobuf/descriptor.cc
+++ b/src/google/protobuf/descriptor.cc
@@ -53,6 +53,8 @@
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/strutil.h>
@@ -1092,6 +1094,7 @@ const DescriptorPool* DescriptorPool::generated_pool() {
return generated_pool_;
}
+
DescriptorPool* DescriptorPool::internal_generated_pool() {
InitGeneratedPoolOnce();
return generated_pool_;
@@ -3699,6 +3702,14 @@ static bool ExistingFileMatchesProto(const FileDescriptor* existing_file,
const FileDescriptorProto& proto) {
FileDescriptorProto existing_proto;
existing_file->CopyTo(&existing_proto);
+ // TODO(liujisi): Remove it when CopyTo supports copying syntax params when
+ // syntax="proto2".
+ if (existing_file->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
+ proto.has_syntax()) {
+ existing_proto.set_syntax(
+ existing_file->SyntaxName(existing_file->syntax()));
+ }
+
return existing_proto.SerializeAsString() == proto.SerializeAsString();
}
@@ -4649,7 +4660,7 @@ void DescriptorBuilder::CrossLinkMessage(
// safe.
if (oneof_decl->field_count() > 0 &&
message->field(i - 1)->containing_oneof() != oneof_decl) {
- AddWarning(
+ AddError(
message->full_name() + "." + message->field(i - 1)->name(),
proto.field(i - 1), DescriptorPool::ErrorCollector::OTHER,
strings::Substitute(
@@ -5088,8 +5099,7 @@ void DescriptorBuilder::ValidateProto3Field(
field->containing_type()->full_name() +
"\" which is a proto3 message type.");
}
- bool allow_groups = false;
- if (field->type() == FieldDescriptor::TYPE_GROUP && !allow_groups) {
+ if (field->type() == FieldDescriptor::TYPE_GROUP) {
AddError(field->full_name(), proto,
DescriptorPool::ErrorCollector::TYPE,
"Groups are not supported in proto3 syntax.");
@@ -5307,6 +5317,14 @@ bool DescriptorBuilder::ValidateMapEntry(FieldDescriptor* field,
// are added.
}
+ if (value->type() == FieldDescriptor::TYPE_ENUM) {
+ if (value->enum_type()->value(0)->number() != 0) {
+ AddError(
+ field->full_name(), proto, DescriptorPool::ErrorCollector::TYPE,
+ "Enum value in map must define 0 as the first value.");
+ }
+ }
+
return true;
}
diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h
index ca87d634..2ab316a5 100644
--- a/src/google/protobuf/descriptor.h
+++ b/src/google/protobuf/descriptor.h
@@ -58,6 +58,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
// TYPE_BOOL is defined in the MacOS's ConditionalMacros.h.
#ifdef TYPE_BOOL
@@ -860,7 +861,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptor {
friend class FieldDescriptor;
friend class EnumValueDescriptor;
friend class FileDescriptor;
- friend class LIBPROTOBUF_EXPORT internal::GeneratedMessageReflection;
+ friend class internal::GeneratedMessageReflection;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
};
@@ -1332,6 +1333,7 @@ class LIBPROTOBUF_EXPORT DescriptorPool {
// this pool. Do not add your own descriptors to this pool.
static const DescriptorPool* generated_pool();
+
// Find a FileDescriptor in the pool by file name. Returns NULL if not
// found.
const FileDescriptor* FindFileByName(const string& name) const;
diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc
index 5e7eeaa7..fe23c0ab 100644
--- a/src/google/protobuf/descriptor.pb.cc
+++ b/src/google/protobuf/descriptor.pb.cc
@@ -755,9 +755,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
"tion\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004s"
"pan\030\002 \003(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022"
"\031\n\021trailing_comments\030\004 \001(\t\022!\n\031leading_de"
- "tached_comments\030\006 \003(\tB[\n\023com.google.prot"
+ "tached_comments\030\006 \003(\tB;\n\023com.google.prot"
"obufB\020DescriptorProtosH\001Z\ndescriptor\242\002\003G"
- "PB\252\002\032Google.Protobuf.Reflection\260\002\001", 4994);
+ "PB", 4962);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -1066,28 +1066,28 @@ int FileDescriptorSet::file_size() const {
void FileDescriptorSet::clear_file() {
file_.Clear();
}
- const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
+const ::google::protobuf::FileDescriptorProto& FileDescriptorSet::file(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorSet.file)
return file_.Get(index);
}
- ::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
+::google::protobuf::FileDescriptorProto* FileDescriptorSet::mutable_file(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorSet.file)
return file_.Mutable(index);
}
- ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
+::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
return file_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-FileDescriptorSet::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
- return file_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
FileDescriptorSet::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
return &file_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
+ return file_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1466,10 +1466,10 @@ void FileDescriptorProto::SerializeWithCachedSizes(
// repeated string dependency = 3;
for (int i = 0; i < this->dependency_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->dependency(i).data(), this->dependency(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.FileDescriptorProto.dependency");
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->dependency(i).data(), this->dependency(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.FileDescriptorProto.dependency");
::google::protobuf::internal::WireFormatLite::WriteString(
3, this->dependency(i), output);
}
@@ -2091,28 +2091,28 @@ int FileDescriptorProto::message_type_size() const {
void FileDescriptorProto::clear_message_type() {
message_type_.Clear();
}
- const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
+const ::google::protobuf::DescriptorProto& FileDescriptorProto::message_type(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Get(index);
}
- ::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
+::google::protobuf::DescriptorProto* FileDescriptorProto::mutable_message_type(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Mutable(index);
}
- ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
+::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_type() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
-FileDescriptorProto::message_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
- return message_type_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
FileDescriptorProto::mutable_message_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
return &message_type_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
+ return message_type_;
+}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
int FileDescriptorProto::enum_type_size() const {
@@ -2121,28 +2121,28 @@ int FileDescriptorProto::enum_type_size() const {
void FileDescriptorProto::clear_enum_type() {
enum_type_.Clear();
}
- const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
+const ::google::protobuf::EnumDescriptorProto& FileDescriptorProto::enum_type(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Get(index);
}
- ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
+::google::protobuf::EnumDescriptorProto* FileDescriptorProto::mutable_enum_type(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Mutable(index);
}
- ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
+::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_type() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
-FileDescriptorProto::enum_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
- return enum_type_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
FileDescriptorProto::mutable_enum_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
return &enum_type_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
+ return enum_type_;
+}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
int FileDescriptorProto::service_size() const {
@@ -2151,28 +2151,28 @@ int FileDescriptorProto::service_size() const {
void FileDescriptorProto::clear_service() {
service_.Clear();
}
- const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
+const ::google::protobuf::ServiceDescriptorProto& FileDescriptorProto::service(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.service)
return service_.Get(index);
}
- ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
+::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::mutable_service(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.service)
return service_.Mutable(index);
}
- ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
+::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_service() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
return service_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
-FileDescriptorProto::service() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
- return service_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
FileDescriptorProto::mutable_service() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
return &service_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
+ return service_;
+}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
int FileDescriptorProto::extension_size() const {
@@ -2181,28 +2181,28 @@ int FileDescriptorProto::extension_size() const {
void FileDescriptorProto::clear_extension() {
extension_.Clear();
}
- const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
+const ::google::protobuf::FieldDescriptorProto& FileDescriptorProto::extension(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.extension)
return extension_.Get(index);
}
- ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
+::google::protobuf::FieldDescriptorProto* FileDescriptorProto::mutable_extension(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.extension)
return extension_.Mutable(index);
}
- ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
+::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extension() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
return extension_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-FileDescriptorProto::extension() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
- return extension_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
FileDescriptorProto::mutable_extension() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
return &extension_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
+ return extension_;
+}
// optional .google.protobuf.FileOptions options = 8;
bool FileDescriptorProto::has_options() const {
@@ -2218,11 +2218,11 @@ void FileDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
+const ::google::protobuf::FileOptions& FileDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
+::google::protobuf::FileOptions* FileDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::FileOptions;
@@ -2230,13 +2230,13 @@ void FileDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.options)
return options_;
}
- ::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
+::google::protobuf::FileOptions* FileDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::FileOptions* temp = options_;
options_ = NULL;
return temp;
}
- void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
+void FileDescriptorProto::set_allocated_options(::google::protobuf::FileOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -2261,11 +2261,11 @@ void FileDescriptorProto::clear_source_code_info() {
if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
clear_has_source_code_info();
}
- const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
+const ::google::protobuf::SourceCodeInfo& FileDescriptorProto::source_code_info() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileDescriptorProto.source_code_info)
return source_code_info_ != NULL ? *source_code_info_ : *default_instance_->source_code_info_;
}
- ::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
+::google::protobuf::SourceCodeInfo* FileDescriptorProto::mutable_source_code_info() {
set_has_source_code_info();
if (source_code_info_ == NULL) {
source_code_info_ = new ::google::protobuf::SourceCodeInfo;
@@ -2273,13 +2273,13 @@ void FileDescriptorProto::clear_source_code_info() {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileDescriptorProto.source_code_info)
return source_code_info_;
}
- ::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
+::google::protobuf::SourceCodeInfo* FileDescriptorProto::release_source_code_info() {
clear_has_source_code_info();
::google::protobuf::SourceCodeInfo* temp = source_code_info_;
source_code_info_ = NULL;
return temp;
}
- void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
+void FileDescriptorProto::set_allocated_source_code_info(::google::protobuf::SourceCodeInfo* source_code_info) {
delete source_code_info_;
source_code_info_ = source_code_info;
if (source_code_info) {
@@ -3269,10 +3269,10 @@ void DescriptorProto::SerializeWithCachedSizes(
// repeated string reserved_name = 10;
for (int i = 0; i < this->reserved_name_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->reserved_name(i).data(), this->reserved_name(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.DescriptorProto.reserved_name");
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->reserved_name(i).data(), this->reserved_name(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.DescriptorProto.reserved_name");
::google::protobuf::internal::WireFormatLite::WriteString(
10, this->reserved_name(i), output);
}
@@ -3720,28 +3720,28 @@ int DescriptorProto::field_size() const {
void DescriptorProto::clear_field() {
field_.Clear();
}
- const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
+const ::google::protobuf::FieldDescriptorProto& DescriptorProto::field(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.field)
return field_.Get(index);
}
- ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
+::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_field(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.field)
return field_.Mutable(index);
}
- ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
+::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
return field_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-DescriptorProto::field() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
- return field_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_field() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
return &field_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
+ return field_;
+}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
int DescriptorProto::extension_size() const {
@@ -3750,28 +3750,28 @@ int DescriptorProto::extension_size() const {
void DescriptorProto::clear_extension() {
extension_.Clear();
}
- const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
+const ::google::protobuf::FieldDescriptorProto& DescriptorProto::extension(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension)
return extension_.Get(index);
}
- ::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
+::google::protobuf::FieldDescriptorProto* DescriptorProto::mutable_extension(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension)
return extension_.Mutable(index);
}
- ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
+::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
return extension_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-DescriptorProto::extension() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
- return extension_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_extension() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
return &extension_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
+ return extension_;
+}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
int DescriptorProto::nested_type_size() const {
@@ -3780,28 +3780,28 @@ int DescriptorProto::nested_type_size() const {
void DescriptorProto::clear_nested_type() {
nested_type_.Clear();
}
- const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
+const ::google::protobuf::DescriptorProto& DescriptorProto::nested_type(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Get(index);
}
- ::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
+::google::protobuf::DescriptorProto* DescriptorProto::mutable_nested_type(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Mutable(index);
}
- ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
+::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
-DescriptorProto::nested_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
- return nested_type_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
DescriptorProto::mutable_nested_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
return &nested_type_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
+ return nested_type_;
+}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
int DescriptorProto::enum_type_size() const {
@@ -3810,28 +3810,28 @@ int DescriptorProto::enum_type_size() const {
void DescriptorProto::clear_enum_type() {
enum_type_.Clear();
}
- const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
+const ::google::protobuf::EnumDescriptorProto& DescriptorProto::enum_type(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Get(index);
}
- ::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
+::google::protobuf::EnumDescriptorProto* DescriptorProto::mutable_enum_type(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Mutable(index);
}
- ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
+::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
-DescriptorProto::enum_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
- return enum_type_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
DescriptorProto::mutable_enum_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
return &enum_type_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
+ return enum_type_;
+}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
int DescriptorProto::extension_range_size() const {
@@ -3840,28 +3840,28 @@ int DescriptorProto::extension_range_size() const {
void DescriptorProto::clear_extension_range() {
extension_range_.Clear();
}
- const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
+const ::google::protobuf::DescriptorProto_ExtensionRange& DescriptorProto::extension_range(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Get(index);
}
- ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
+::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::mutable_extension_range(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Mutable(index);
}
- ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
+::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_extension_range() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
-DescriptorProto::extension_range() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
- return extension_range_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
DescriptorProto::mutable_extension_range() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
return &extension_range_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
+ return extension_range_;
+}
// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
int DescriptorProto::oneof_decl_size() const {
@@ -3870,28 +3870,28 @@ int DescriptorProto::oneof_decl_size() const {
void DescriptorProto::clear_oneof_decl() {
oneof_decl_.Clear();
}
- const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
+const ::google::protobuf::OneofDescriptorProto& DescriptorProto::oneof_decl(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.oneof_decl)
return oneof_decl_.Get(index);
}
- ::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
+::google::protobuf::OneofDescriptorProto* DescriptorProto::mutable_oneof_decl(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.oneof_decl)
return oneof_decl_.Mutable(index);
}
- ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
+::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
return oneof_decl_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
-DescriptorProto::oneof_decl() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
- return oneof_decl_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
DescriptorProto::mutable_oneof_decl() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
return &oneof_decl_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_;
+}
// optional .google.protobuf.MessageOptions options = 7;
bool DescriptorProto::has_options() const {
@@ -3907,11 +3907,11 @@ void DescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
+const ::google::protobuf::MessageOptions& DescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
+::google::protobuf::MessageOptions* DescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::MessageOptions;
@@ -3919,13 +3919,13 @@ void DescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.options)
return options_;
}
- ::google::protobuf::MessageOptions* DescriptorProto::release_options() {
+::google::protobuf::MessageOptions* DescriptorProto::release_options() {
clear_has_options();
::google::protobuf::MessageOptions* temp = options_;
options_ = NULL;
return temp;
}
- void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
+void DescriptorProto::set_allocated_options(::google::protobuf::MessageOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -3943,28 +3943,28 @@ int DescriptorProto::reserved_range_size() const {
void DescriptorProto::clear_reserved_range() {
reserved_range_.Clear();
}
- const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const {
+const ::google::protobuf::DescriptorProto_ReservedRange& DescriptorProto::reserved_range(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.DescriptorProto.reserved_range)
return reserved_range_.Get(index);
}
- ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) {
+::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::mutable_reserved_range(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.DescriptorProto.reserved_range)
return reserved_range_.Mutable(index);
}
- ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() {
+::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range)
return reserved_range_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
-DescriptorProto::reserved_range() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
- return reserved_range_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
DescriptorProto::mutable_reserved_range() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range)
return &reserved_range_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
+DescriptorProto::reserved_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
+ return reserved_range_;
+}
// repeated string reserved_name = 10;
int DescriptorProto::reserved_name_size() const {
@@ -5062,11 +5062,11 @@ void FieldDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
+const ::google::protobuf::FieldOptions& FieldDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.FieldDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
+::google::protobuf::FieldOptions* FieldDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::FieldOptions;
@@ -5074,13 +5074,13 @@ void FieldDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.FieldDescriptorProto.options)
return options_;
}
- ::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
+::google::protobuf::FieldOptions* FieldDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::FieldOptions* temp = options_;
options_ = NULL;
return temp;
}
- void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
+void FieldDescriptorProto::set_allocated_options(::google::protobuf::FieldOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -5804,28 +5804,28 @@ int EnumDescriptorProto::value_size() const {
void EnumDescriptorProto::clear_value() {
value_.Clear();
}
- const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
+const ::google::protobuf::EnumValueDescriptorProto& EnumDescriptorProto::value(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.value)
return value_.Get(index);
}
- ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
+::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::mutable_value(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.value)
return value_.Mutable(index);
}
- ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
+::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_value() {
// @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
return value_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
-EnumDescriptorProto::value() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
- return value_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
EnumDescriptorProto::mutable_value() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
return &value_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
+ return value_;
+}
// optional .google.protobuf.EnumOptions options = 3;
bool EnumDescriptorProto::has_options() const {
@@ -5841,11 +5841,11 @@ void EnumDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
+const ::google::protobuf::EnumOptions& EnumDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
+::google::protobuf::EnumOptions* EnumDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::EnumOptions;
@@ -5853,13 +5853,13 @@ void EnumDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumDescriptorProto.options)
return options_;
}
- ::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
+::google::protobuf::EnumOptions* EnumDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::EnumOptions* temp = options_;
options_ = NULL;
return temp;
}
- void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
+void EnumDescriptorProto::set_allocated_options(::google::protobuf::EnumOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -6304,11 +6304,11 @@ void EnumValueDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
+const ::google::protobuf::EnumValueOptions& EnumValueDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumValueDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
+::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::EnumValueOptions;
@@ -6316,13 +6316,13 @@ void EnumValueDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueDescriptorProto.options)
return options_;
}
- ::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
+::google::protobuf::EnumValueOptions* EnumValueDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::EnumValueOptions* temp = options_;
options_ = NULL;
return temp;
}
- void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
+void EnumValueDescriptorProto::set_allocated_options(::google::protobuf::EnumValueOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -6740,28 +6740,28 @@ int ServiceDescriptorProto::method_size() const {
void ServiceDescriptorProto::clear_method() {
method_.Clear();
}
- const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
+const ::google::protobuf::MethodDescriptorProto& ServiceDescriptorProto::method(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.method)
return method_.Get(index);
}
- ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
+::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::mutable_method(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.method)
return method_.Mutable(index);
}
- ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
+::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_method() {
// @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
return method_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
-ServiceDescriptorProto::method() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
- return method_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
ServiceDescriptorProto::mutable_method() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
return &method_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
+ return method_;
+}
// optional .google.protobuf.ServiceOptions options = 3;
bool ServiceDescriptorProto::has_options() const {
@@ -6777,11 +6777,11 @@ void ServiceDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
+const ::google::protobuf::ServiceOptions& ServiceDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.ServiceDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
+::google::protobuf::ServiceOptions* ServiceDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::ServiceOptions;
@@ -6789,13 +6789,13 @@ void ServiceDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.ServiceDescriptorProto.options)
return options_;
}
- ::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
+::google::protobuf::ServiceOptions* ServiceDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::ServiceOptions* temp = options_;
options_ = NULL;
return temp;
}
- void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
+void ServiceDescriptorProto::set_allocated_options(::google::protobuf::ServiceOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -7480,11 +7480,11 @@ void MethodDescriptorProto::clear_options() {
if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
clear_has_options();
}
- const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
+const ::google::protobuf::MethodOptions& MethodDescriptorProto::options() const {
// @@protoc_insertion_point(field_get:google.protobuf.MethodDescriptorProto.options)
return options_ != NULL ? *options_ : *default_instance_->options_;
}
- ::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
+::google::protobuf::MethodOptions* MethodDescriptorProto::mutable_options() {
set_has_options();
if (options_ == NULL) {
options_ = new ::google::protobuf::MethodOptions;
@@ -7492,13 +7492,13 @@ void MethodDescriptorProto::clear_options() {
// @@protoc_insertion_point(field_mutable:google.protobuf.MethodDescriptorProto.options)
return options_;
}
- ::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
+::google::protobuf::MethodOptions* MethodDescriptorProto::release_options() {
clear_has_options();
::google::protobuf::MethodOptions* temp = options_;
options_ = NULL;
return temp;
}
- void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
+void MethodDescriptorProto::set_allocated_options(::google::protobuf::MethodOptions* options) {
delete options_;
options_ = options;
if (options) {
@@ -9025,28 +9025,28 @@ int FileOptions::uninterpreted_option_size() const {
void FileOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& FileOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* FileOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-FileOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FileOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -9568,28 +9568,28 @@ int MessageOptions::uninterpreted_option_size() const {
void MessageOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& MessageOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* MessageOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* MessageOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-MessageOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MessageOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -10298,28 +10298,28 @@ int FieldOptions::uninterpreted_option_size() const {
void FieldOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& FieldOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* FieldOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-FieldOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FieldOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -10721,28 +10721,28 @@ int EnumOptions::uninterpreted_option_size() const {
void EnumOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& EnumOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* EnumOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-EnumOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -11070,28 +11070,28 @@ int EnumValueOptions::uninterpreted_option_size() const {
void EnumValueOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& EnumValueOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* EnumValueOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-EnumValueOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumValueOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -11419,28 +11419,28 @@ int ServiceOptions::uninterpreted_option_size() const {
void ServiceOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& ServiceOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* ServiceOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-ServiceOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
ServiceOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -11768,28 +11768,28 @@ int MethodOptions::uninterpreted_option_size() const {
void MethodOptions::clear_uninterpreted_option() {
uninterpreted_option_.Clear();
}
- const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
+const ::google::protobuf::UninterpretedOption& MethodOptions::uninterpreted_option(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Get(index);
}
- ::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
+::google::protobuf::UninterpretedOption* MethodOptions::mutable_uninterpreted_option(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
+::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted_option() {
// @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-MethodOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MethodOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -12710,28 +12710,28 @@ int UninterpretedOption::name_size() const {
void UninterpretedOption::clear_name() {
name_.Clear();
}
- const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
+const ::google::protobuf::UninterpretedOption_NamePart& UninterpretedOption::name(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.UninterpretedOption.name)
return name_.Get(index);
}
- ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
+::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::mutable_name(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.UninterpretedOption.name)
return name_.Mutable(index);
}
- ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
+::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::add_name() {
// @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
return name_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
-UninterpretedOption::name() const {
- // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
- return name_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_name() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
return &name_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
+ return name_;
+}
// optional string identifier_value = 3;
bool UninterpretedOption::has_identifier_value() const {
@@ -13221,10 +13221,10 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes(
// repeated string leading_detached_comments = 6;
for (int i = 0; i < this->leading_detached_comments_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
+ ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ this->leading_detached_comments(i).data(), this->leading_detached_comments(i).length(),
+ ::google::protobuf::internal::WireFormat::SERIALIZE,
+ "google.protobuf.SourceCodeInfo.Location.leading_detached_comments");
::google::protobuf::internal::WireFormatLite::WriteString(
6, this->leading_detached_comments(i), output);
}
@@ -13916,28 +13916,28 @@ int SourceCodeInfo::location_size() const {
void SourceCodeInfo::clear_location() {
location_.Clear();
}
- const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
+const ::google::protobuf::SourceCodeInfo_Location& SourceCodeInfo::location(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.SourceCodeInfo.location)
return location_.Get(index);
}
- ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
+::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::mutable_location(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.SourceCodeInfo.location)
return location_.Mutable(index);
}
- ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
+::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location() {
// @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
return location_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
-SourceCodeInfo::location() const {
- // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
- return location_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
SourceCodeInfo::mutable_location() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
return &location_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+ return location_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h
index 2aa076ae..931ff02d 100644
--- a/src/google/protobuf/descriptor.pb.h
+++ b/src/google/protobuf/descriptor.pb.h
@@ -38,28 +38,28 @@ void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto(
void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
-class FileDescriptorSet;
-class FileDescriptorProto;
class DescriptorProto;
class DescriptorProto_ExtensionRange;
class DescriptorProto_ReservedRange;
-class FieldDescriptorProto;
-class OneofDescriptorProto;
class EnumDescriptorProto;
+class EnumOptions;
class EnumValueDescriptorProto;
-class ServiceDescriptorProto;
-class MethodDescriptorProto;
+class EnumValueOptions;
+class FieldDescriptorProto;
+class FieldOptions;
+class FileDescriptorProto;
+class FileDescriptorSet;
class FileOptions;
class MessageOptions;
-class FieldOptions;
-class EnumOptions;
-class EnumValueOptions;
-class ServiceOptions;
+class MethodDescriptorProto;
class MethodOptions;
-class UninterpretedOption;
-class UninterpretedOption_NamePart;
+class OneofDescriptorProto;
+class ServiceDescriptorProto;
+class ServiceOptions;
class SourceCodeInfo;
class SourceCodeInfo_Location;
+class UninterpretedOption;
+class UninterpretedOption_NamePart;
enum FieldDescriptorProto_Type {
FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
@@ -249,10 +249,10 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message
const ::google::protobuf::FileDescriptorProto& file(int index) const;
::google::protobuf::FileDescriptorProto* mutable_file(int index);
::google::protobuf::FileDescriptorProto* add_file();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
- file() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
mutable_file();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+ file() const;
// @@protoc_insertion_point(class_scope:google.protobuf.FileDescriptorSet)
private:
@@ -405,10 +405,10 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
const ::google::protobuf::DescriptorProto& message_type(int index) const;
::google::protobuf::DescriptorProto* mutable_message_type(int index);
::google::protobuf::DescriptorProto* add_message_type();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
- message_type() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
mutable_message_type();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+ message_type() const;
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
int enum_type_size() const;
@@ -417,10 +417,10 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
::google::protobuf::EnumDescriptorProto* add_enum_type();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
- enum_type() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
mutable_enum_type();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+ enum_type() const;
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
int service_size() const;
@@ -429,10 +429,10 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
const ::google::protobuf::ServiceDescriptorProto& service(int index) const;
::google::protobuf::ServiceDescriptorProto* mutable_service(int index);
::google::protobuf::ServiceDescriptorProto* add_service();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
- service() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
mutable_service();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+ service() const;
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
int extension_size() const;
@@ -441,10 +441,10 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag
const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
::google::protobuf::FieldDescriptorProto* add_extension();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
- extension() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_extension();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ extension() const;
// optional .google.protobuf.FileOptions options = 8;
bool has_options() const;
@@ -797,10 +797,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::FieldDescriptorProto& field(int index) const;
::google::protobuf::FieldDescriptorProto* mutable_field(int index);
::google::protobuf::FieldDescriptorProto* add_field();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
- field() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_field();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ field() const;
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
int extension_size() const;
@@ -809,10 +809,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::FieldDescriptorProto& extension(int index) const;
::google::protobuf::FieldDescriptorProto* mutable_extension(int index);
::google::protobuf::FieldDescriptorProto* add_extension();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
- extension() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
mutable_extension();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+ extension() const;
// repeated .google.protobuf.DescriptorProto nested_type = 3;
int nested_type_size() const;
@@ -821,10 +821,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::DescriptorProto& nested_type(int index) const;
::google::protobuf::DescriptorProto* mutable_nested_type(int index);
::google::protobuf::DescriptorProto* add_nested_type();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
- nested_type() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
mutable_nested_type();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+ nested_type() const;
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
int enum_type_size() const;
@@ -833,10 +833,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::EnumDescriptorProto& enum_type(int index) const;
::google::protobuf::EnumDescriptorProto* mutable_enum_type(int index);
::google::protobuf::EnumDescriptorProto* add_enum_type();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
- enum_type() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
mutable_enum_type();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+ enum_type() const;
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
int extension_range_size() const;
@@ -845,10 +845,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::DescriptorProto_ExtensionRange& extension_range(int index) const;
::google::protobuf::DescriptorProto_ExtensionRange* mutable_extension_range(int index);
::google::protobuf::DescriptorProto_ExtensionRange* add_extension_range();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
- extension_range() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
mutable_extension_range();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+ extension_range() const;
// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
int oneof_decl_size() const;
@@ -857,10 +857,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::OneofDescriptorProto& oneof_decl(int index) const;
::google::protobuf::OneofDescriptorProto* mutable_oneof_decl(int index);
::google::protobuf::OneofDescriptorProto* add_oneof_decl();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
- oneof_decl() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
mutable_oneof_decl();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+ oneof_decl() const;
// optional .google.protobuf.MessageOptions options = 7;
bool has_options() const;
@@ -878,10 +878,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message {
const ::google::protobuf::DescriptorProto_ReservedRange& reserved_range(int index) const;
::google::protobuf::DescriptorProto_ReservedRange* mutable_reserved_range(int index);
::google::protobuf::DescriptorProto_ReservedRange* add_reserved_range();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
- reserved_range() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
mutable_reserved_range();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
+ reserved_range() const;
// repeated string reserved_name = 10;
int reserved_name_size() const;
@@ -1361,10 +1361,10 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag
const ::google::protobuf::EnumValueDescriptorProto& value(int index) const;
::google::protobuf::EnumValueDescriptorProto* mutable_value(int index);
::google::protobuf::EnumValueDescriptorProto* add_value();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
- value() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
mutable_value();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+ value() const;
// optional .google.protobuf.EnumOptions options = 3;
bool has_options() const;
@@ -1596,10 +1596,10 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes
const ::google::protobuf::MethodDescriptorProto& method(int index) const;
::google::protobuf::MethodDescriptorProto* mutable_method(int index);
::google::protobuf::MethodDescriptorProto* add_method();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
- method() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
mutable_method();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ method() const;
// optional .google.protobuf.ServiceOptions options = 3;
bool has_options() const;
@@ -2014,10 +2014,10 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FileOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FileOptions)
@@ -2182,10 +2182,10 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MessageOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MessageOptions)
@@ -2381,10 +2381,10 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions)
@@ -2508,10 +2508,10 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumOptions)
@@ -2616,10 +2616,10 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(EnumValueOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValueOptions)
@@ -2721,10 +2721,10 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(ServiceOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.ServiceOptions)
@@ -2826,10 +2826,10 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message {
const ::google::protobuf::UninterpretedOption& uninterpreted_option(int index) const;
::google::protobuf::UninterpretedOption* mutable_uninterpreted_option(int index);
::google::protobuf::UninterpretedOption* add_uninterpreted_option();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
- uninterpreted_option() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
mutable_uninterpreted_option();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ uninterpreted_option() const;
GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(MethodOptions)
// @@protoc_insertion_point(class_scope:google.protobuf.MethodOptions)
@@ -3033,10 +3033,10 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag
const ::google::protobuf::UninterpretedOption_NamePart& name(int index) const;
::google::protobuf::UninterpretedOption_NamePart* mutable_name(int index);
::google::protobuf::UninterpretedOption_NamePart* add_name();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
- name() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
mutable_name();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+ name() const;
// optional string identifier_value = 3;
bool has_identifier_value() const;
@@ -3356,10 +3356,10 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message {
const ::google::protobuf::SourceCodeInfo_Location& location(int index) const;
::google::protobuf::SourceCodeInfo_Location* mutable_location(int index);
::google::protobuf::SourceCodeInfo_Location* add_location();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
- location() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
mutable_location();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+ location() const;
// @@protoc_insertion_point(class_scope:google.protobuf.SourceCodeInfo)
private:
@@ -3402,16 +3402,16 @@ inline ::google::protobuf::FileDescriptorProto* FileDescriptorSet::add_file() {
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorSet.file)
return file_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
-FileDescriptorSet::file() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
- return file_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >*
FileDescriptorSet::mutable_file() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorSet.file)
return &file_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FileDescriptorProto >&
+FileDescriptorSet::file() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorSet.file)
+ return file_;
+}
// -------------------------------------------------------------------
@@ -3656,16 +3656,16 @@ inline ::google::protobuf::DescriptorProto* FileDescriptorProto::add_message_typ
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.message_type)
return message_type_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
-FileDescriptorProto::message_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
- return message_type_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
FileDescriptorProto::mutable_message_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.message_type)
return &message_type_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+FileDescriptorProto::message_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.message_type)
+ return message_type_;
+}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
inline int FileDescriptorProto::enum_type_size() const {
@@ -3686,16 +3686,16 @@ inline ::google::protobuf::EnumDescriptorProto* FileDescriptorProto::add_enum_ty
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.enum_type)
return enum_type_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
-FileDescriptorProto::enum_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
- return enum_type_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
FileDescriptorProto::mutable_enum_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.enum_type)
return &enum_type_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+FileDescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.enum_type)
+ return enum_type_;
+}
// repeated .google.protobuf.ServiceDescriptorProto service = 6;
inline int FileDescriptorProto::service_size() const {
@@ -3716,16 +3716,16 @@ inline ::google::protobuf::ServiceDescriptorProto* FileDescriptorProto::add_serv
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.service)
return service_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
-FileDescriptorProto::service() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
- return service_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >*
FileDescriptorProto::mutable_service() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.service)
return &service_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto >&
+FileDescriptorProto::service() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.service)
+ return service_;
+}
// repeated .google.protobuf.FieldDescriptorProto extension = 7;
inline int FileDescriptorProto::extension_size() const {
@@ -3746,16 +3746,16 @@ inline ::google::protobuf::FieldDescriptorProto* FileDescriptorProto::add_extens
// @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.extension)
return extension_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-FileDescriptorProto::extension() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
- return extension_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
FileDescriptorProto::mutable_extension() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileDescriptorProto.extension)
return &extension_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+FileDescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileDescriptorProto.extension)
+ return extension_;
+}
// optional .google.protobuf.FileOptions options = 8;
inline bool FileDescriptorProto::has_options() const {
@@ -4076,16 +4076,16 @@ inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_field() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.field)
return field_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-DescriptorProto::field() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
- return field_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_field() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.field)
return &field_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::field() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.field)
+ return field_;
+}
// repeated .google.protobuf.FieldDescriptorProto extension = 6;
inline int DescriptorProto::extension_size() const {
@@ -4106,16 +4106,16 @@ inline ::google::protobuf::FieldDescriptorProto* DescriptorProto::add_extension(
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension)
return extension_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
-DescriptorProto::extension() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
- return extension_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >*
DescriptorProto::mutable_extension() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension)
return &extension_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >&
+DescriptorProto::extension() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension)
+ return extension_;
+}
// repeated .google.protobuf.DescriptorProto nested_type = 3;
inline int DescriptorProto::nested_type_size() const {
@@ -4136,16 +4136,16 @@ inline ::google::protobuf::DescriptorProto* DescriptorProto::add_nested_type() {
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.nested_type)
return nested_type_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
-DescriptorProto::nested_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
- return nested_type_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >*
DescriptorProto::mutable_nested_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.nested_type)
return &nested_type_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto >&
+DescriptorProto::nested_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.nested_type)
+ return nested_type_;
+}
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
inline int DescriptorProto::enum_type_size() const {
@@ -4166,16 +4166,16 @@ inline ::google::protobuf::EnumDescriptorProto* DescriptorProto::add_enum_type()
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.enum_type)
return enum_type_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
-DescriptorProto::enum_type() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
- return enum_type_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >*
DescriptorProto::mutable_enum_type() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.enum_type)
return &enum_type_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto >&
+DescriptorProto::enum_type() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.enum_type)
+ return enum_type_;
+}
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
inline int DescriptorProto::extension_range_size() const {
@@ -4196,16 +4196,16 @@ inline ::google::protobuf::DescriptorProto_ExtensionRange* DescriptorProto::add_
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.extension_range)
return extension_range_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
-DescriptorProto::extension_range() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
- return extension_range_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >*
DescriptorProto::mutable_extension_range() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.extension_range)
return &extension_range_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >&
+DescriptorProto::extension_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.extension_range)
+ return extension_range_;
+}
// repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8;
inline int DescriptorProto::oneof_decl_size() const {
@@ -4226,16 +4226,16 @@ inline ::google::protobuf::OneofDescriptorProto* DescriptorProto::add_oneof_decl
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.oneof_decl)
return oneof_decl_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
-DescriptorProto::oneof_decl() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
- return oneof_decl_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >*
DescriptorProto::mutable_oneof_decl() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.oneof_decl)
return &oneof_decl_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto >&
+DescriptorProto::oneof_decl() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.oneof_decl)
+ return oneof_decl_;
+}
// optional .google.protobuf.MessageOptions options = 7;
inline bool DescriptorProto::has_options() const {
@@ -4299,16 +4299,16 @@ inline ::google::protobuf::DescriptorProto_ReservedRange* DescriptorProto::add_r
// @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_range)
return reserved_range_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
-DescriptorProto::reserved_range() const {
- // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
- return reserved_range_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >*
DescriptorProto::mutable_reserved_range() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.DescriptorProto.reserved_range)
return &reserved_range_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange >&
+DescriptorProto::reserved_range() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.DescriptorProto.reserved_range)
+ return reserved_range_;
+}
// repeated string reserved_name = 10;
inline int DescriptorProto::reserved_name_size() const {
@@ -4854,16 +4854,16 @@ inline ::google::protobuf::EnumValueDescriptorProto* EnumDescriptorProto::add_va
// @@protoc_insertion_point(field_add:google.protobuf.EnumDescriptorProto.value)
return value_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
-EnumDescriptorProto::value() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
- return value_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >*
EnumDescriptorProto::mutable_value() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumDescriptorProto.value)
return &value_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValueDescriptorProto >&
+EnumDescriptorProto::value() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumDescriptorProto.value)
+ return value_;
+}
// optional .google.protobuf.EnumOptions options = 3;
inline bool EnumDescriptorProto::has_options() const {
@@ -5108,16 +5108,16 @@ inline ::google::protobuf::MethodDescriptorProto* ServiceDescriptorProto::add_me
// @@protoc_insertion_point(field_add:google.protobuf.ServiceDescriptorProto.method)
return method_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
-ServiceDescriptorProto::method() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
- return method_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >*
ServiceDescriptorProto::mutable_method() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceDescriptorProto.method)
return &method_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::MethodDescriptorProto >&
+ServiceDescriptorProto::method() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceDescriptorProto.method)
+ return method_;
+}
// optional .google.protobuf.ServiceOptions options = 3;
inline bool ServiceDescriptorProto::has_options() const {
@@ -5945,16 +5945,16 @@ inline ::google::protobuf::UninterpretedOption* FileOptions::add_uninterpreted_o
// @@protoc_insertion_point(field_add:google.protobuf.FileOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-FileOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FileOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FileOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FileOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FileOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6075,16 +6075,16 @@ inline ::google::protobuf::UninterpretedOption* MessageOptions::add_uninterprete
// @@protoc_insertion_point(field_add:google.protobuf.MessageOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-MessageOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MessageOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.MessageOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MessageOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MessageOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6255,16 +6255,16 @@ inline ::google::protobuf::UninterpretedOption* FieldOptions::add_uninterpreted_
// @@protoc_insertion_point(field_add:google.protobuf.FieldOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-FieldOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
FieldOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.FieldOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+FieldOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.FieldOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6337,16 +6337,16 @@ inline ::google::protobuf::UninterpretedOption* EnumOptions::add_uninterpreted_o
// @@protoc_insertion_point(field_add:google.protobuf.EnumOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-EnumOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6395,16 +6395,16 @@ inline ::google::protobuf::UninterpretedOption* EnumValueOptions::add_uninterpre
// @@protoc_insertion_point(field_add:google.protobuf.EnumValueOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-EnumValueOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
EnumValueOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValueOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+EnumValueOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValueOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6453,16 +6453,16 @@ inline ::google::protobuf::UninterpretedOption* ServiceOptions::add_uninterprete
// @@protoc_insertion_point(field_add:google.protobuf.ServiceOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-ServiceOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
ServiceOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ServiceOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+ServiceOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ServiceOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6511,16 +6511,16 @@ inline ::google::protobuf::UninterpretedOption* MethodOptions::add_uninterpreted
// @@protoc_insertion_point(field_add:google.protobuf.MethodOptions.uninterpreted_option)
return uninterpreted_option_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
-MethodOptions::uninterpreted_option() const {
- // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
- return uninterpreted_option_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >*
MethodOptions::mutable_uninterpreted_option() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.MethodOptions.uninterpreted_option)
return &uninterpreted_option_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption >&
+MethodOptions::uninterpreted_option() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.MethodOptions.uninterpreted_option)
+ return uninterpreted_option_;
+}
// -------------------------------------------------------------------
@@ -6626,16 +6626,16 @@ inline ::google::protobuf::UninterpretedOption_NamePart* UninterpretedOption::ad
// @@protoc_insertion_point(field_add:google.protobuf.UninterpretedOption.name)
return name_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
-UninterpretedOption::name() const {
- // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
- return name_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >*
UninterpretedOption::mutable_name() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.UninterpretedOption.name)
return &name_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption_NamePart >&
+UninterpretedOption::name() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.UninterpretedOption.name)
+ return name_;
+}
// optional string identifier_value = 3;
inline bool UninterpretedOption::has_identifier_value() const {
@@ -7115,16 +7115,16 @@ inline ::google::protobuf::SourceCodeInfo_Location* SourceCodeInfo::add_location
// @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.location)
return location_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
-SourceCodeInfo::location() const {
- // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
- return location_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >*
SourceCodeInfo::mutable_location() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.SourceCodeInfo.location)
return &location_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::SourceCodeInfo_Location >&
+SourceCodeInfo::location() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.SourceCodeInfo.location)
+ return location_;
+}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto
index 9d3dd8fb..8f90a956 100644
--- a/src/google/protobuf/descriptor.proto
+++ b/src/google/protobuf/descriptor.proto
@@ -42,9 +42,9 @@ syntax = "proto2";
package google.protobuf;
option go_package = "descriptor";
option java_package = "com.google.protobuf";
-option javanano_use_deprecated_package = true;
option java_outer_classname = "DescriptorProtos";
-option csharp_namespace = "Google.Protobuf.Reflection";
+// Re-enable this once the tools have picked up the csharp_namespace option.
+// option csharp_namespace = "Google.ProtocolBuffers.DescriptorProtos";
option objc_class_prefix = "GPB";
// descriptor.proto must be optimized for speed because reflection-based
@@ -301,10 +301,12 @@ message FileOptions {
// If set true, then the Java code generator will generate equals() and
// hashCode() methods for all messages defined in the .proto file.
- // - In the full runtime, this is purely a speed optimization, as the
+ // This increases generated code size, potentially substantially for large
+ // protos, which may harm a memory-constrained application.
+ // - In the full runtime this is a speed optimization, as the
// AbstractMessage base class includes reflection-based implementations of
// these methods.
- //- In the lite runtime, setting this option changes the semantics of
+ // - In the lite runtime, setting this option changes the semantics of
// equals() and hashCode() to more closely match those of the full runtime;
// the generated methods compute their results based on field values rather
// than object identity. (Implementations should not assume that hashcodes
@@ -525,6 +527,7 @@ message FieldOptions {
// For Google-internal migration only. Do not use.
optional bool weak = 10 [default=false];
+
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc
index 1c03c443..a87fa049 100644
--- a/src/google/protobuf/descriptor_database_unittest.cc
+++ b/src/google/protobuf/descriptor_database_unittest.cc
@@ -42,7 +42,9 @@
#include <google/protobuf/text_format.h>
#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc
index 760df097..e9b027db 100644
--- a/src/google/protobuf/descriptor_unittest.cc
+++ b/src/google/protobuf/descriptor_unittest.cc
@@ -49,6 +49,8 @@
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -368,6 +370,37 @@ TEST_F(FileDescriptorTest, BuildAgain) {
EXPECT_TRUE(pool_.BuildFile(file) == NULL);
}
+TEST_F(FileDescriptorTest, BuildAgainWithSyntax) {
+ // Test that if te call BuildFile again on the same input we get the same
+ // FileDescriptor back even if syntax param is specified.
+ FileDescriptorProto proto_syntax2;
+ proto_syntax2.set_name("foo_syntax2");
+ proto_syntax2.set_syntax("proto2");
+
+ const FileDescriptor* proto2_descriptor = pool_.BuildFile(proto_syntax2);
+ EXPECT_TRUE(proto2_descriptor != NULL);
+ EXPECT_EQ(proto2_descriptor, pool_.BuildFile(proto_syntax2));
+
+ FileDescriptorProto implicit_proto2;
+ implicit_proto2.set_name("foo_implicit_syntax2");
+
+ const FileDescriptor* implicit_proto2_descriptor =
+ pool_.BuildFile(implicit_proto2);
+ EXPECT_TRUE(implicit_proto2_descriptor != NULL);
+ // We get the same FileDescriptor back if syntax param is explicitly
+ // specified.
+ implicit_proto2.set_syntax("proto2");
+ EXPECT_EQ(implicit_proto2_descriptor, pool_.BuildFile(implicit_proto2));
+
+ FileDescriptorProto proto_syntax3;
+ proto_syntax3.set_name("foo_syntax3");
+ proto_syntax3.set_syntax("proto3");
+
+ const FileDescriptor* proto3_descriptor = pool_.BuildFile(proto_syntax3);
+ EXPECT_TRUE(proto3_descriptor != NULL);
+ EXPECT_EQ(proto3_descriptor, pool_.BuildFile(proto_syntax3));
+}
+
TEST_F(FileDescriptorTest, Syntax) {
FileDescriptorProto proto;
proto.set_name("foo");
@@ -3583,7 +3616,7 @@ TEST_F(ValidationErrorTest, FieldOneofIndexNegative) {
TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
// Fields belonging to the same oneof must be defined consecutively.
- BuildFileWithWarnings(
+ BuildFileWithErrors(
"name: \"foo.proto\" "
"message_type {"
" name: \"Foo\""
@@ -3600,7 +3633,7 @@ TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
"\"foos\" oneof definition.\n");
// Prevent interleaved fields, which belong to different oneofs.
- BuildFileWithWarnings(
+ BuildFileWithErrors(
"name: \"foo2.proto\" "
"message_type {"
" name: \"Foo2\""
@@ -3621,6 +3654,25 @@ TEST_F(ValidationErrorTest, OneofFieldsConsecutiveDefinition) {
"foo2.proto: Foo2.foo2: OTHER: Fields in the same oneof must be defined "
"consecutively. \"foo2\" cannot be defined before the completion of the "
"\"bars\" oneof definition.\n");
+
+ // Another case for normal fields and different oneof fields interleave.
+ BuildFileWithErrors(
+ "name: \"foo3.proto\" "
+ "message_type {"
+ " name: \"Foo3\""
+ " field { name:\"foo1\" number: 1 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " field { name:\"bar1\" number: 2 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 1 }"
+ " field { name:\"baz\" number: 3 label:LABEL_OPTIONAL type:TYPE_INT32 }"
+ " field { name:\"foo2\" number: 4 label:LABEL_OPTIONAL type:TYPE_INT32 "
+ " oneof_index: 0 }"
+ " oneof_decl { name:\"foos\" }"
+ " oneof_decl { name:\"bars\" }"
+ "}",
+ "foo3.proto: Foo3.baz: OTHER: Fields in the same oneof must be defined "
+ "consecutively. \"baz\" cannot be defined before the completion of the "
+ "\"foos\" oneof definition.\n");
}
TEST_F(ValidationErrorTest, FieldNumberConflict) {
@@ -5369,6 +5421,35 @@ TEST_F(ValidationErrorTest, MapEntryConflictsWithOneof) {
"with an existing oneof type.\n");
}
+TEST_F(ValidationErrorTest, MapEntryUsesNoneZeroEnumDefaultValue) {
+ BuildFileWithErrors(
+ "name: \"foo.proto\" "
+ "enum_type {"
+ " name: \"Bar\""
+ " value { name:\"ENUM_A\" number:1 }"
+ " value { name:\"ENUM_B\" number:2 }"
+ "}"
+ "message_type {"
+ " name: 'Foo' "
+ " field { "
+ " name: 'foo_map' number: 1 label:LABEL_REPEATED "
+ " type_name: 'FooMapEntry' "
+ " } "
+ " nested_type { "
+ " name: 'FooMapEntry' "
+ " options { map_entry: true } "
+ " field { "
+ " name: 'key' number: 1 type:TYPE_INT32 label:LABEL_OPTIONAL "
+ " } "
+ " field { "
+ " name: 'value' number: 2 type_name:\"Bar\" label:LABEL_OPTIONAL "
+ " } "
+ " } "
+ "}",
+ "foo.proto: Foo.foo_map: "
+ "TYPE: Enum value in map must define 0 as the first value.\n");
+}
+
TEST_F(ValidationErrorTest, Proto3RequiredFields) {
BuildFileWithErrors(
"name: 'foo.proto' "
diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto
index 0762c3c2..7f172aa6 100644
--- a/src/google/protobuf/duration.proto
+++ b/src/google/protobuf/duration.proto
@@ -80,6 +80,7 @@ option objc_class_prefix = "GPB";
// }
//
message Duration {
+
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive.
int64 seconds = 1;
diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc
index 318ce6f9..2324d952 100644
--- a/src/google/protobuf/dynamic_message.cc
+++ b/src/google/protobuf/dynamic_message.cc
@@ -65,6 +65,7 @@
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/dynamic_message.h>
@@ -79,6 +80,7 @@
#include <google/protobuf/map_type_handler.h>
#include <google/protobuf/extension_set.h>
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/map_field.h>
namespace google {
namespace protobuf {
@@ -87,7 +89,7 @@ using internal::WireFormat;
using internal::ExtensionSet;
using internal::GeneratedMessageReflection;
using internal::MapField;
-using internal::MapFieldBase;
+using internal::DynamicMapField;
using internal::ArenaStringPtr;
@@ -116,7 +118,7 @@ int FieldSpaceUsed(const FieldDescriptor* field) {
case FD::CPPTYPE_ENUM : return sizeof(RepeatedField<int >);
case FD::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
- return sizeof(MapFieldBase);
+ return sizeof(DynamicMapField);
} else {
return sizeof(RepeatedPtrField<Message>);
}
@@ -389,7 +391,8 @@ void DynamicMessage::SharedCtor() {
new(field_ptr) Message*(NULL);
} else {
if (IsMapFieldInApi(field)) {
- new (field_ptr) MapFieldBase();
+ new (field_ptr) DynamicMapField(
+ type_info_->factory->GetPrototypeNoLock(field->message_type()));
} else {
new (field_ptr) RepeatedPtrField<Message>();
}
@@ -437,8 +440,8 @@ DynamicMessage::~DynamicMessage() {
&(reinterpret_cast<const ArenaStringPtr*>(
type_info_->prototype->OffsetToPointer(
type_info_->offsets[i]))->Get(NULL));
- reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
- NULL);
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
+ default_value, NULL);
break;
}
}
@@ -480,7 +483,7 @@ DynamicMessage::~DynamicMessage() {
case FieldDescriptor::CPPTYPE_MESSAGE:
if (IsMapFieldInApi(field)) {
- reinterpret_cast<MapFieldBase*>(field_ptr)->~MapFieldBase();
+ reinterpret_cast<DynamicMapField*>(field_ptr)->~DynamicMapField();
} else {
reinterpret_cast<RepeatedPtrField<Message>*>(field_ptr)
->~RepeatedPtrField<Message>();
@@ -496,8 +499,8 @@ DynamicMessage::~DynamicMessage() {
&(reinterpret_cast<const ArenaStringPtr*>(
type_info_->prototype->OffsetToPointer(
type_info_->offsets[i]))->Get(NULL));
- reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(default_value,
- NULL);
+ reinterpret_cast<ArenaStringPtr*>(field_ptr)->Destroy(
+ default_value, NULL);
break;
}
}
@@ -723,8 +726,14 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
// Allocate the prototype.
void* base = operator new(size);
memset(base, 0, size);
+ // The prototype in type_info has to be set before creating the prototype
+ // instance on memory. e.g., message Foo { map<int32, Foo> a = 1; }. When
+ // creating prototype for Foo, prototype of the map entry will also be
+ // created, which needs the address of the prototype of Foo (the value in
+ // map). To break the cyclic dependency, we have to assgin the address of
+ // prototype into type_info first.
+ type_info->prototype = static_cast<DynamicMessage*>(base);
DynamicMessage* prototype = new(base) DynamicMessage(type_info);
- type_info->prototype = prototype;
// Construct the reflection object.
if (type->oneof_decl_count() > 0) {
diff --git a/src/google/protobuf/dynamic_message.h b/src/google/protobuf/dynamic_message.h
index b5928a52..f74cd7dd 100644
--- a/src/google/protobuf/dynamic_message.h
+++ b/src/google/protobuf/dynamic_message.h
@@ -45,6 +45,7 @@
#include <google/protobuf/message.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/mutex.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/dynamic_message_unittest.cc b/src/google/protobuf/dynamic_message_unittest.cc
index 522a092a..b9796c76 100644
--- a/src/google/protobuf/dynamic_message_unittest.cc
+++ b/src/google/protobuf/dynamic_message_unittest.cc
@@ -40,6 +40,7 @@
// reflection_ops_unittest, cover the rest of the functionality used by
// DynamicMessage.
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/dynamic_message.h>
#include <google/protobuf/descriptor.h>
@@ -48,6 +49,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_no_field_presence.pb.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc
index 1e1c2c8c..50cbd9a8 100644
--- a/src/google/protobuf/empty.pb.cc
+++ b/src/google/protobuf/empty.pb.cc
@@ -79,9 +79,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fempty_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\033google/protobuf/empty.proto\022\017google.pr"
- "otobuf\"\007\n\005EmptyBJ\n\023com.google.protobufB\n"
- "EmptyProtoP\001\242\002\003GPB\252\002\036Google.Protobuf.Wel"
- "lKnownTypesb\006proto3", 139);
+ "otobuf\"\007\n\005EmptyBM\n\023com.google.protobufB\n"
+ "EmptyProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Protobuf."
+ "WellKnownTypesb\006proto3", 142);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/empty.proto", &protobuf_RegisterTypes);
Empty::default_instance_ = new Empty();
diff --git a/src/google/protobuf/empty.proto b/src/google/protobuf/empty.proto
index 363ec175..9dddc6c5 100644
--- a/src/google/protobuf/empty.proto
+++ b/src/google/protobuf/empty.proto
@@ -34,10 +34,10 @@ package google.protobuf;
option java_multiple_files = true;
option java_outer_classname = "EmptyProto";
option java_package = "com.google.protobuf";
+option java_generate_equals_and_hash = true;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// A generic empty message that you can re-use to avoid defining duplicated
// empty messages in your APIs. A typical example is to use it as the request
// or the response type of an API method. For instance:
@@ -46,6 +46,5 @@ option objc_class_prefix = "GPB";
// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
// }
//
-message Empty {
-
-}
+// The JSON representation for `Empty` is empty JSON object `{}`.
+message Empty {}
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 35f14b9c..09681259 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -45,6 +45,7 @@
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/repeated_field.h>
@@ -331,6 +332,8 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
const MessageLite& prototype, desc);
MessageLite* AddMessage(const FieldDescriptor* descriptor,
MessageFactory* factory);
+ void AddAllocatedMessage(const FieldDescriptor* descriptor,
+ MessageLite* new_entry);
#undef desc
void RemoveLast(int number);
@@ -579,6 +582,10 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
Extension** result);
+ // Gets the repeated extension for the given descriptor, creating it if
+ // it does not exist.
+ Extension* MaybeNewRepeatedExtension(const FieldDescriptor* descriptor);
+
// Parse a single MessageSet item -- called just after the item group start
// tag has been read.
bool ParseMessageSetItem(io::CodedInputStream* input,
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index 330bd828..82e3e099 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -213,8 +213,7 @@ MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
}
}
-MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
- MessageFactory* factory) {
+ExtensionSet::Extension* ExtensionSet::MaybeNewRepeatedExtension(const FieldDescriptor* descriptor) {
Extension* extension;
if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
extension->type = descriptor->type();
@@ -225,6 +224,12 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
} else {
GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
}
+ return extension;
+}
+
+MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
+ MessageFactory* factory) {
+ Extension* extension = MaybeNewRepeatedExtension(descriptor);
// RepeatedPtrField<Message> does not know how to Add() since it cannot
// allocate an abstract object, so we have to be tricky.
@@ -244,6 +249,13 @@ MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
return result;
}
+void ExtensionSet::AddAllocatedMessage(const FieldDescriptor* descriptor,
+ MessageLite* new_entry) {
+ Extension* extension = MaybeNewRepeatedExtension(descriptor);
+
+ extension->repeated_message_value->AddAllocated(new_entry);
+}
+
static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
return reinterpret_cast<const EnumDescriptor*>(arg)
->FindValueByNumber(number) != NULL;
diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc
index 684ce002..1569120d 100644
--- a/src/google/protobuf/extension_set_unittest.cc
+++ b/src/google/protobuf/extension_set_unittest.cc
@@ -44,6 +44,7 @@
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
@@ -173,7 +174,7 @@ TEST(ExtensionSetTest, SetAllocatedExtension) {
}
TEST(ExtensionSetTest, ReleaseExtension) {
- unittest::TestMessageSet message;
+ proto2_wireformat_unittest::TestMessageSet message;
EXPECT_FALSE(message.HasExtension(
unittest::TestMessageSetExtension1::message_set_extension));
// Add a extension using SetAllocatedExtension
diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc
index 88020ef2..d8f4ee91 100644
--- a/src/google/protobuf/field_mask.pb.cc
+++ b/src/google/protobuf/field_mask.pb.cc
@@ -81,9 +81,9 @@ void protobuf_AddDesc_google_2fprotobuf_2ffield_5fmask_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n google/protobuf/field_mask.proto\022\017goog"
"le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
- "N\n\023com.google.protobufB\016FieldMaskProtoP\001"
- "\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTypesb"
- "\006proto3", 167);
+ "Q\n\023com.google.protobufB\016FieldMaskProtoP\001"
+ "\240\001\001\242\002\003GPB\252\002\036Google.Protobuf.WellKnownTyp"
+ "esb\006proto3", 170);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/field_mask.proto", &protobuf_RegisterTypes);
FieldMask::default_instance_ = new FieldMask();
@@ -193,11 +193,11 @@ bool FieldMask::MergePartialFromCodedStream(
parse_paths:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->add_paths()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->paths(this->paths_size() - 1).data(),
this->paths(this->paths_size() - 1).length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.FieldMask.paths");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.FieldMask.paths"));
} else {
goto handle_unusual;
}
@@ -232,10 +232,10 @@ void FieldMask::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.FieldMask)
// repeated string paths = 1;
for (int i = 0; i < this->paths_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->paths(i).data(), this->paths(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.FieldMask.paths");
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->paths(i).data(), this->paths(i).length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.FieldMask.paths");
::google::protobuf::internal::WireFormatLite::WriteString(
1, this->paths(i), output);
}
@@ -248,9 +248,9 @@ void FieldMask::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask)
// repeated string paths = 1;
for (int i = 0; i < this->paths_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->paths(i).data(), this->paths(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.FieldMask.paths");
target = ::google::protobuf::internal::WireFormatLite::
WriteStringToArray(1, this->paths(i), target);
diff --git a/src/google/protobuf/field_mask.proto b/src/google/protobuf/field_mask.proto
index c19f4410..8b21c692 100644
--- a/src/google/protobuf/field_mask.proto
+++ b/src/google/protobuf/field_mask.proto
@@ -31,13 +31,13 @@ syntax = "proto3";
package google.protobuf;
+option java_generate_equals_and_hash = true;
option java_multiple_files = true;
option java_outer_classname = "FieldMaskProto";
option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// `FieldMask` represents a set of symbolic field paths, for example:
//
// paths: "f.a"
@@ -52,6 +52,7 @@ option objc_class_prefix = "GPB";
// Field masks also have a custom JSON encoding (see below).
//
// # Field Masks in Projections
+//
// When used in the context of a projection, a response message or
// sub-message is filtered by the API to only contain those fields as
// specified in the mask. For example, if the mask in the previous
@@ -97,6 +98,7 @@ option objc_class_prefix = "GPB";
// behavior for APIs.
//
// # Field Masks in Update Operations
+//
// A field mask in update operations specifies which fields of the
// targeted resource are going to be updated. The API is required
// to only change the values of the fields as specified in the mask
@@ -124,11 +126,13 @@ option objc_class_prefix = "GPB";
// required to be honored by the API.
//
// ## Considerations for HTTP REST
+//
// The HTTP kind of an update operation which uses a field mask must
// be set to PATCH instead of PUT in order to satisfy HTTP semantics
// (PUT must only be used for full updates).
//
// # JSON Encoding of Field Masks
+//
// In JSON, a field mask is encoded as a single string where paths are
// separated by a comma. Fields name in each path are converted
// to/from lower-camel naming conventions.
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 0b01e73a..eee024ee 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -35,6 +35,7 @@
#include <algorithm>
#include <set>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
@@ -806,7 +807,16 @@ void GeneratedMessageReflection::ClearField(
}
case FieldDescriptor::CPPTYPE_MESSAGE:
- (*MutableRaw<Message*>(message, field))->Clear();
+ if (has_bits_offset_ == -1) {
+ // Proto3 does not have has-bits and we need to set a message field
+ // to NULL in order to indicate its un-presence.
+ if (GetArena(message) == NULL) {
+ delete *MutableRaw<Message*>(message, field);
+ }
+ *MutableRaw<Message*>(message, field) = NULL;
+ } else {
+ (*MutableRaw<Message*>(message, field))->Clear();
+ }
break;
}
}
@@ -1637,6 +1647,25 @@ Message* GeneratedMessageReflection::AddMessage(
}
}
+void GeneratedMessageReflection::AddAllocatedMessage(
+ Message* message, const FieldDescriptor* field,
+ Message* new_entry) const {
+ USAGE_CHECK_ALL(AddAllocatedMessage, REPEATED, MESSAGE);
+
+ if (field->is_extension()) {
+ MutableExtensionSet(message)->AddAllocatedMessage(field, new_entry);
+ } else {
+ RepeatedPtrFieldBase* repeated = NULL;
+ if (IsMapFieldInApi(field)) {
+ repeated =
+ MutableRaw<MapFieldBase>(message, field)->MutableRepeatedField();
+ } else {
+ repeated = MutableRaw<RepeatedPtrFieldBase>(message, field);
+ }
+ repeated->AddAllocated<GenericTypeHandler<Message> >(new_entry);
+ }
+}
+
void* GeneratedMessageReflection::MutableRawRepeatedField(
Message* message, const FieldDescriptor* field,
FieldDescriptor::CppType cpptype,
@@ -1663,6 +1692,37 @@ void* GeneratedMessageReflection::MutableRawRepeatedField(
}
}
+const void* GeneratedMessageReflection::GetRawRepeatedField(
+ const Message& message, const FieldDescriptor* field,
+ FieldDescriptor::CppType cpptype,
+ int ctype, const Descriptor* desc) const {
+ USAGE_CHECK_REPEATED("GetRawRepeatedField");
+ if (field->cpp_type() != cpptype)
+ ReportReflectionUsageTypeError(descriptor_,
+ field, "GetRawRepeatedField", cpptype);
+ if (ctype >= 0)
+ GOOGLE_CHECK_EQ(field->options().ctype(), ctype) << "subtype mismatch";
+ if (desc != NULL)
+ GOOGLE_CHECK_EQ(field->message_type(), desc) << "wrong submessage type";
+ if (field->is_extension()) {
+ // Should use extension_set::GetRawRepeatedField. However, the required
+ // parameter "default repeated value" is not very easy to get here.
+ // Map is not supported in extensions, it is acceptable to use
+ // extension_set::MutableRawRepeatedField which does not change the message.
+ return MutableExtensionSet(const_cast<Message*>(&message))
+ ->MutableRawRepeatedField(
+ field->number(), field->type(), field->is_packed(), field);
+ } else {
+ // Trigger transform for MapField
+ if (IsMapFieldInApi(field)) {
+ return &(reinterpret_cast<const MapFieldBase*>(
+ reinterpret_cast<const uint8*>(&message) +
+ offsets_[field->index()])->GetRepeatedField());
+ }
+ return reinterpret_cast<const uint8*>(&message) + offsets_[field->index()];
+ }
+}
+
const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
const Message& message,
const OneofDescriptor* oneof_descriptor) const {
@@ -1673,6 +1733,69 @@ const FieldDescriptor* GeneratedMessageReflection::GetOneofFieldDescriptor(
return descriptor_->FindFieldByNumber(field_number);
}
+bool GeneratedMessageReflection::ContainsMapKey(
+ const Message& message,
+ const FieldDescriptor* field,
+ const MapKey& key) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "LookupMapValue",
+ "Field is not a map field.");
+ return GetRaw<MapFieldBase>(message, field).ContainsMapKey(key);
+}
+
+bool GeneratedMessageReflection::InsertOrLookupMapValue(
+ Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key,
+ MapValueRef* val) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "InsertOrLookupMapValue",
+ "Field is not a map field.");
+ val->SetType(field->message_type()->FindFieldByName("value")->cpp_type());
+ return MutableRaw<MapFieldBase>(message, field)->InsertMapValue(key, val);
+}
+
+bool GeneratedMessageReflection::DeleteMapValue(
+ Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "DeleteMapValue",
+ "Field is not a map field.");
+ return MutableRaw<MapFieldBase>(message, field)->DeleteMapValue(key);
+}
+
+MapIterator GeneratedMessageReflection::MapBegin(
+ Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "MapBegin",
+ "Field is not a map field.");
+ MapIterator iter(message, field);
+ GetRaw<MapFieldBase>(*message, field).MapBegin(&iter);
+ return iter;
+}
+
+MapIterator GeneratedMessageReflection::MapEnd(
+ Message* message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "MapEnd",
+ "Field is not a map field.");
+ MapIterator iter(message, field);
+ GetRaw<MapFieldBase>(*message, field).MapEnd(&iter);
+ return iter;
+}
+
+int GeneratedMessageReflection::MapSize(
+ const Message& message,
+ const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "MapSize",
+ "Field is not a map field.");
+ return GetRaw<MapFieldBase>(message, field).size();
+}
+
// -----------------------------------------------------------------------------
const FieldDescriptor* GeneratedMessageReflection::FindKnownExtensionByName(
@@ -2086,6 +2209,14 @@ void* GeneratedMessageReflection::RepeatedFieldData(
}
}
+MapFieldBase* GeneratedMessageReflection::MapData(
+ Message* message, const FieldDescriptor* field) const {
+ USAGE_CHECK(IsMapFieldInApi(field),
+ "GetMapData",
+ "Field is not a map field.");
+ return MutableRaw<MapFieldBase>(message, field);
+}
+
GeneratedMessageReflection*
GeneratedMessageReflection::NewGeneratedMessageReflection(
const Descriptor* descriptor,
diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h
index dc8abb98..9ef78710 100644
--- a/src/google/protobuf/generated_message_reflection.h
+++ b/src/google/protobuf/generated_message_reflection.h
@@ -58,7 +58,9 @@ class GMR_Handlers;
} // namespace upb
namespace protobuf {
- class DescriptorPool;
+class DescriptorPool;
+class MapKey;
+class MapValueRef;
}
namespace protobuf {
@@ -261,6 +263,25 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
const Message& message,
const OneofDescriptor* oneof_descriptor) const;
+ private:
+ bool ContainsMapKey(const Message& message,
+ const FieldDescriptor* field,
+ const MapKey& key) const;
+ bool InsertOrLookupMapValue(Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key,
+ MapValueRef* val) const;
+ bool DeleteMapValue(Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key) const;
+ MapIterator MapBegin(
+ Message* message,
+ const FieldDescriptor* field) const;
+ MapIterator MapEnd(
+ Message* message,
+ const FieldDescriptor* field) const;
+ int MapSize(const Message& message, const FieldDescriptor* field) const;
+
public:
void SetInt32 (Message* message,
const FieldDescriptor* field, int32 value) const;
@@ -371,6 +392,9 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
int value) const;
Message* AddMessage(Message* message, const FieldDescriptor* field,
MessageFactory* factory = NULL) const;
+ void AddAllocatedMessage(
+ Message* message, const FieldDescriptor* field,
+ Message* new_entry) const;
const FieldDescriptor* FindKnownExtensionByName(const string& name) const;
const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
@@ -391,10 +415,15 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
static const int kUnknownFieldSetInMetadata = -1;
protected:
- virtual void* MutableRawRepeatedField(
+ void* MutableRawRepeatedField(
Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
int ctype, const Descriptor* desc) const;
+ const void* GetRawRepeatedField(
+ const Message& message, const FieldDescriptor* field,
+ FieldDescriptor::CppType, int ctype,
+ const Descriptor* desc) const;
+
virtual MessageFactory* GetMessageFactory() const;
virtual void* RepeatedFieldData(
@@ -407,7 +436,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
// To parse directly into a proto2 generated class, the class GMR_Handlers
// needs access to member offsets and hasbits.
- friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+ friend class upb::google_opensource::GMR_Handlers;
const Descriptor* descriptor_;
const Message* default_instance_;
@@ -539,6 +568,9 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection : public Reflection {
Message* sub_message,
const FieldDescriptor* field) const;
+ internal::MapFieldBase* MapData(
+ Message* message, const FieldDescriptor* field) const;
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
};
diff --git a/src/google/protobuf/generated_message_reflection_unittest.cc b/src/google/protobuf/generated_message_reflection_unittest.cc
index ca1a2918..df043844 100644
--- a/src/google/protobuf/generated_message_reflection_unittest.cc
+++ b/src/google/protobuf/generated_message_reflection_unittest.cc
@@ -47,6 +47,7 @@
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -546,6 +547,57 @@ TEST(GeneratedMessageReflectionTest, SetAllocatedExtensionMessageTest) {
&to_message, TestUtil::ReflectionTester::IS_NULL);
}
+TEST(GeneratedMessageReflectionTest, AddRepeatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+ const Reflection* nested_reflection =
+ unittest::TestAllTypes::NestedMessage::default_instance().GetReflection();
+
+ const FieldDescriptor* nested_bb =
+ unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName(
+ "bb");
+
+ Message* nested = reflection->AddMessage(
+ &message, F("repeated_nested_message"));
+ nested_reflection->SetInt32(nested, nested_bb, 11);
+
+ EXPECT_EQ(11, message.repeated_nested_message(0).bb());
+}
+
+TEST(GeneratedMessageReflectionTest, MutableRepeatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+ const Reflection* nested_reflection =
+ unittest::TestAllTypes::NestedMessage::default_instance().GetReflection();
+
+ const FieldDescriptor* nested_bb =
+ unittest::TestAllTypes::NestedMessage::descriptor()->FindFieldByName(
+ "bb");
+
+ message.add_repeated_nested_message()->set_bb(12);
+
+ Message* nested = reflection->MutableRepeatedMessage(
+ &message, F("repeated_nested_message"), 0);
+ EXPECT_EQ(12, nested_reflection->GetInt32(*nested, nested_bb));
+ nested_reflection->SetInt32(nested, nested_bb, 13);
+ EXPECT_EQ(13, message.repeated_nested_message(0).bb());
+}
+
+TEST(GeneratedMessageReflectionTest, AddAllocatedMessage) {
+ unittest::TestAllTypes message;
+
+ const Reflection* reflection = message.GetReflection();
+
+ unittest::TestAllTypes::NestedMessage* nested =
+ new unittest::TestAllTypes::NestedMessage();
+ nested->set_bb(11);
+ reflection->AddAllocatedMessage(&message, F("repeated_nested_message"), nested);
+ EXPECT_EQ(1, message.repeated_nested_message_size());
+ EXPECT_EQ(11, message.repeated_nested_message(0).bb());
+}
+
TEST(GeneratedMessageReflectionTest, ListFieldsOneOf) {
unittest::TestOneof2 message;
TestUtil::SetOneof1(&message);
diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc
index 3b8650d6..4bcd354f 100644
--- a/src/google/protobuf/io/coded_stream.cc
+++ b/src/google/protobuf/io/coded_stream.cc
@@ -44,6 +44,7 @@
#include <limits.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/arena.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util.h>
@@ -338,9 +339,9 @@ namespace {
// The first part of the pair is true iff the read was successful. The second
// part is buffer + (number of bytes read). This function is always inlined,
// so returning a pair is costless.
-inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE ::std::pair<bool, const uint8*> ReadVarint32FromArray(
uint32 first_byte, const uint8* buffer,
- uint32* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ uint32* value);
inline ::std::pair<bool, const uint8*> ReadVarint32FromArray(
uint32 first_byte, const uint8* buffer, uint32* value) {
// Fast path: We have enough bytes left in the buffer to guarantee that
diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h
index ad351dc3..361c406b 100644
--- a/src/google/protobuf/io/coded_stream.h
+++ b/src/google/protobuf/io/coded_stream.h
@@ -191,16 +191,15 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Like GetDirectBufferPointer, but this method is inlined, and does not
// attempt to Refresh() if the buffer is currently empty.
- inline void GetDirectBufferPointerInline(const void** data,
- int* size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void GetDirectBufferPointerInline(const void** data,
+ int* size);
// Read raw bytes, copying them into the given buffer.
bool ReadRaw(void* buffer, int size);
// Like the above, with inlined optimizations. This should only be used
// by the protobuf implementation.
- inline bool InternalReadRawInline(void* buffer,
- int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadRawInline(void* buffer, int size);
// Like ReadRaw, but reads into a string.
//
@@ -212,8 +211,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
bool ReadString(string* buffer, int size);
// Like the above, with inlined optimizations. This should only be used
// by the protobuf implementation.
- inline bool InternalReadStringInline(string* buffer,
- int size) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InternalReadStringInline(string* buffer,
+ int size);
// Read a 32-bit little-endian integer.
@@ -243,7 +242,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// Always inline because this is only called in one place per parse loop
// but it is called for every iteration of said loop, so it should be fast.
// GCC doesn't want to inline this by default.
- uint32 ReadTag() GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE uint32 ReadTag();
// This usually a faster alternative to ReadTag() when cutoff is a manifest
// constant. It does particularly well for cutoff >= 127. The first part
@@ -253,8 +252,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// above cutoff or is 0. (There's intentional wiggle room when tag is 0,
// because that can arise in several ways, and for best performance we want
// to avoid an extra "is tag == 0?" check here.)
- inline std::pair<uint32, bool> ReadTagWithCutoff(uint32 cutoff)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE std::pair<uint32, bool> ReadTagWithCutoff(
+ uint32 cutoff);
// Usually returns true if calling ReadVarint32() now would produce the given
// value. Will always return false if ReadVarint32() would not return the
@@ -263,7 +262,7 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
// parameter.
// Always inline because this collapses to a small number of instructions
// when given a constant parameter, but GCC doesn't want to inline by default.
- bool ExpectTag(uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool ExpectTag(uint32 expected);
// Like above, except this reads from the specified buffer. The caller is
// responsible for ensuring that the buffer is large enough to read a varint
@@ -272,9 +271,9 @@ class LIBPROTOBUF_EXPORT CodedInputStream {
//
// Returns a pointer beyond the expected tag if it was found, or NULL if it
// was not.
- static const uint8* ExpectTagFromArray(
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE static const uint8* ExpectTagFromArray(
const uint8* buffer,
- uint32 expected) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ uint32 expected);
// Usually returns true if no more bytes can be read. Always returns false
// if more bytes can be read. If ExpectAtEnd() returns true, a subsequent
@@ -766,8 +765,8 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// but GCC by default doesn't want to inline this.
void WriteTag(uint32 value);
// Like WriteTag() but writing directly to the target array.
- static uint8* WriteTagToArray(
- uint32 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteTagToArray(uint32 value,
+ uint8* target);
// Returns the number of bytes needed to encode the given value as a varint.
static int VarintSize32(uint32 value);
@@ -831,8 +830,8 @@ class LIBPROTOBUF_EXPORT CodedOutputStream {
// WriteVarint32FallbackToArray. Meanwhile, WriteVarint32() is already
// out-of-line, so it should just invoke this directly to avoid any extra
// function call overhead.
- static uint8* WriteVarint64ToArrayInline(
- uint64 value, uint8* target) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE static uint8* WriteVarint64ToArrayInline(
+ uint64 value, uint8* target);
static int VarintSize32Fallback(uint32 value);
};
diff --git a/src/google/protobuf/io/coded_stream_inl.h b/src/google/protobuf/io/coded_stream_inl.h
index fa20f208..d95b06e0 100644
--- a/src/google/protobuf/io/coded_stream_inl.h
+++ b/src/google/protobuf/io/coded_stream_inl.h
@@ -36,6 +36,7 @@
#ifndef GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
#define GOOGLE_PROTOBUF_IO_CODED_STREAM_INL_H__
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc
index 02d5bad3..630c9086 100644
--- a/src/google/protobuf/io/coded_stream_unittest.cc
+++ b/src/google/protobuf/io/coded_stream_unittest.cc
@@ -41,6 +41,8 @@
#include <limits.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
diff --git a/src/google/protobuf/io/gzip_stream.cc b/src/google/protobuf/io/gzip_stream.cc
index dd7c036e..1be6c863 100644
--- a/src/google/protobuf/io/gzip_stream.cc
+++ b/src/google/protobuf/io/gzip_stream.cc
@@ -33,10 +33,12 @@
// This file contains the implementation of classes GzipInputStream and
// GzipOutputStream.
+
#if HAVE_ZLIB
#include <google/protobuf/io/gzip_stream.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/io/printer.cc b/src/google/protobuf/io/printer.cc
index 3ae8c268..7d886506 100644
--- a/src/google/protobuf/io/printer.cc
+++ b/src/google/protobuf/io/printer.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/io/printer_unittest.cc b/src/google/protobuf/io/printer_unittest.cc
index 1331a8d9..258dd986 100644
--- a/src/google/protobuf/io/printer_unittest.cc
+++ b/src/google/protobuf/io/printer_unittest.cc
@@ -37,6 +37,7 @@
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/io/strtod.cc b/src/google/protobuf/io/strtod.cc
index 56973439..579de9aa 100644
--- a/src/google/protobuf/io/strtod.cc
+++ b/src/google/protobuf/io/strtod.cc
@@ -34,6 +34,7 @@
#include <cstring>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/io/tokenizer.cc b/src/google/protobuf/io/tokenizer.cc
index 60bd7957..7ccd633d 100644
--- a/src/google/protobuf/io/tokenizer.cc
+++ b/src/google/protobuf/io/tokenizer.cc
@@ -90,6 +90,7 @@
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/strtod.h>
#include <google/protobuf/io/zero_copy_stream.h>
diff --git a/src/google/protobuf/io/tokenizer.h b/src/google/protobuf/io/tokenizer.h
index 98576f56..49885eda 100644
--- a/src/google/protobuf/io/tokenizer.h
+++ b/src/google/protobuf/io/tokenizer.h
@@ -40,6 +40,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/io/tokenizer_unittest.cc b/src/google/protobuf/io/tokenizer_unittest.cc
index de096fb9..6526056a 100644
--- a/src/google/protobuf/io/tokenizer_unittest.cc
+++ b/src/google/protobuf/io/tokenizer_unittest.cc
@@ -41,6 +41,7 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/testing/googletest.h>
diff --git a/src/google/protobuf/io/zero_copy_stream.cc b/src/google/protobuf/io/zero_copy_stream.cc
index f77c768f..186de001 100644
--- a/src/google/protobuf/io/zero_copy_stream.cc
+++ b/src/google/protobuf/io/zero_copy_stream.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc
index f7901b27..7ec2b5da 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -46,6 +46,7 @@
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stl_util.h>
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
index 97b73b88..686e63f2 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/stl_util.h>
namespace google {
diff --git a/src/google/protobuf/io/zero_copy_stream_impl_lite.h b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
index 4360b18f..9cdf0378 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl_lite.h
+++ b/src/google/protobuf/io/zero_copy_stream_impl_lite.h
@@ -48,6 +48,7 @@
#include <iosfwd>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/stl_util.h>
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index f2e5b629..3850e76c 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -46,6 +46,7 @@
// "parametized tests" so that one set of tests can be used on all the
// implementations.
+
#ifdef _MSC_VER
#include <io.h>
#else
@@ -66,6 +67,8 @@
#endif
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/testing/googletest.h>
#include <google/protobuf/testing/file.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/lite_arena_unittest.cc b/src/google/protobuf/lite_arena_unittest.cc
new file mode 100644
index 00000000..f0bee880
--- /dev/null
+++ b/src/google/protobuf/lite_arena_unittest.cc
@@ -0,0 +1,83 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/arena_test_util.h>
+#include <google/protobuf/map_lite_test_util.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace {
+
+TEST(LiteArenaTest, MapNoHeapAllocation) {
+ // Allocate a large initial block to avoid mallocs during hooked test.
+ std::vector<char> arena_block(128 * 1024);
+ google::protobuf::ArenaOptions options;
+ options.initial_block = &arena_block[0];
+ options.initial_block_size = arena_block.size();
+ google::protobuf::Arena arena(options);
+ string data;
+ data.reserve(128 * 1024);
+
+ {
+ // TODO(teboring): Enable no heap check when ArenaStringPtr is used in
+ // Map.
+ // google::protobuf::internal::NoHeapChecker no_heap;
+
+ protobuf_unittest::TestArenaMapLite* from =
+ google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(&arena);
+ google::protobuf::MapLiteTestUtil::SetArenaMapFields(from);
+ from->SerializeToString(&data);
+
+ protobuf_unittest::TestArenaMapLite* to =
+ google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(&arena);
+ to->ParseFromString(data);
+ google::protobuf::MapLiteTestUtil::ExpectArenaMapFieldsSet(*to);
+ }
+}
+
+TEST(LiteArenaTest, UnknownFieldMemLeak) {
+ google::protobuf::Arena arena;
+ protobuf_unittest::ForeignMessageArenaLite* message =
+ google::protobuf::Arena::CreateMessage<protobuf_unittest::ForeignMessageArenaLite>(
+ &arena);
+ string data = "\012\000";
+ int original_capacity = data.capacity();
+ while (data.capacity() <= original_capacity) {
+ data.append("a");
+ }
+ data[1] = data.size() - 2;
+ message->ParseFromString(data);
+}
+
+} // namespace
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc
index 5af8b24d..d1948ab5 100644
--- a/src/google/protobuf/lite_unittest.cc
+++ b/src/google/protobuf/lite_unittest.cc
@@ -33,6 +33,7 @@
#include <string>
#include <iostream>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena_test_util.h>
#include <google/protobuf/map_lite_unittest.pb.h>
@@ -377,13 +378,6 @@ int main(int argc, char* argv[]) {
}
{
- // Proto2SetMapFieldsInitialized
- protobuf_unittest::TestEnumStartWithNonZeroMapLite message;
- EXPECT_EQ(protobuf_unittest::PROTO2_NON_ZERO_MAP_ENUM_FOO_LITE,
- (*message.mutable_map_field())[0]);
- }
-
- {
// Clear
protobuf_unittest::TestMapLite message;
@@ -692,37 +686,6 @@ int main(int argc, char* argv[]) {
EXPECT_TRUE(map_message.IsInitialized());
}
- // arena support for map =========================================
-
- {
- // ParsingAndSerializingNoHeapAllocation
-
- // Allocate a large initial block to avoid mallocs during hooked test.
- std::vector<char> arena_block(128 * 1024);
- google::protobuf::ArenaOptions options;
- options.initial_block = &arena_block[0];
- options.initial_block_size = arena_block.size();
- google::protobuf::Arena arena(options);
- string data;
- data.reserve(128 * 1024);
-
- {
- google::protobuf::internal::NoHeapChecker no_heap;
-
- protobuf_unittest::TestArenaMapLite* from =
- google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(
- &arena);
- google::protobuf::MapLiteTestUtil::SetArenaMapFields(from);
- from->SerializeToString(&data);
-
- protobuf_unittest::TestArenaMapLite* to =
- google::protobuf::Arena::CreateMessage<protobuf_unittest::TestArenaMapLite>(
- &arena);
- to->ParseFromString(data);
- google::protobuf::MapLiteTestUtil::ExpectArenaMapFieldsSet(*to);
- }
- }
-
std::cout << "PASS" << std::endl;
return 0;
}
diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h
index d928b7a7..8b61573d 100644
--- a/src/google/protobuf/map.h
+++ b/src/google/protobuf/map.h
@@ -35,9 +35,12 @@
#include <google/protobuf/stubs/hash.h>
#include <limits> // To support Visual Studio 2008
+#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/generated_enum_util.h>
#include <google/protobuf/map_type_handler.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/descriptor.h>
namespace google {
namespace protobuf {
@@ -47,13 +50,379 @@ class Map;
template <typename Enum> struct is_proto_enum;
+class MapIterator;
+
namespace internal {
template <typename Key, typename T,
WireFormatLite::FieldType key_wire_type,
WireFormatLite::FieldType value_wire_type,
int default_enum_value>
class MapFieldLite;
-}
+
+template <typename Key, typename T,
+ WireFormatLite::FieldType key_wire_type,
+ WireFormatLite::FieldType value_wire_type,
+ int default_enum_value>
+class MapField;
+
+template <typename Key, typename T>
+class TypeDefinedMapFieldBase;
+
+class DynamicMapField;
+
+class GeneratedMessageReflection;
+} // namespace internal
+
+#define TYPE_CHECK(EXPECTEDTYPE, METHOD) \
+ if (type() != EXPECTEDTYPE) { \
+ GOOGLE_LOG(FATAL) \
+ << "Protocol Buffer map usage error:\n" \
+ << METHOD << " type does not match\n" \
+ << " Expected : " \
+ << FieldDescriptor::CppTypeName(EXPECTEDTYPE) << "\n" \
+ << " Actual : " \
+ << FieldDescriptor::CppTypeName(type()); \
+ }
+
+// MapKey is an union type for representing any possible
+// map key.
+class LIBPROTOBUF_EXPORT MapKey {
+ public:
+ MapKey() : type_(0) {
+ }
+ MapKey(const MapKey& other) : type_(0) {
+ CopyFrom(other);
+ }
+
+ ~MapKey() {
+ if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+ delete val_.string_value_;
+ }
+ }
+
+ FieldDescriptor::CppType type() const {
+ if (type_ == 0) {
+ GOOGLE_LOG(FATAL)
+ << "Protocol Buffer map usage error:\n"
+ << "MapKey::type MapKey is not initialized. "
+ << "Call set methods to initialize MapKey.";
+ }
+ return (FieldDescriptor::CppType)type_;
+ }
+
+ void SetInt64Value(int64 value) {
+ SetType(FieldDescriptor::CPPTYPE_INT64);
+ val_.int64_value_ = value;
+ }
+ void SetUInt64Value(uint64 value) {
+ SetType(FieldDescriptor::CPPTYPE_UINT64);
+ val_.uint64_value_ = value;
+ }
+ void SetInt32Value(int32 value) {
+ SetType(FieldDescriptor::CPPTYPE_INT32);
+ val_.int32_value_ = value;
+ }
+ void SetUInt32Value(uint32 value) {
+ SetType(FieldDescriptor::CPPTYPE_UINT32);
+ val_.uint32_value_ = value;
+ }
+ void SetBoolValue(bool value) {
+ SetType(FieldDescriptor::CPPTYPE_BOOL);
+ val_.bool_value_ = value;
+ }
+ void SetStringValue(const string& val) {
+ SetType(FieldDescriptor::CPPTYPE_STRING);
+ *val_.string_value_ = val;
+ }
+
+ int64 GetInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+ "MapKey::GetInt64Value");
+ return val_.int64_value_;
+ }
+ uint64 GetUInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+ "MapKey::GetUInt64Value");
+ return val_.uint64_value_;
+ }
+ int32 GetInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+ "MapKey::GetInt32Value");
+ return val_.int32_value_;
+ }
+ uint32 GetUInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+ "MapKey::GetUInt32Value");
+ return val_.uint32_value_;
+ }
+ int32 GetBoolValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+ "MapKey::GetBoolValue");
+ return val_.bool_value_;
+ }
+ const string& GetStringValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+ "MapKey::GetStringValue");
+ return *val_.string_value_;
+ }
+
+ bool operator==(const MapKey& other) const {
+ if (type_ != other.type_) {
+ return false;
+ }
+ switch (type()) {
+ case FieldDescriptor::CPPTYPE_STRING:
+ return *val_.string_value_ == *other.val_.string_value_;
+ case FieldDescriptor::CPPTYPE_INT64:
+ return val_.int64_value_ == other.val_.int64_value_;
+ case FieldDescriptor::CPPTYPE_INT32:
+ return val_.int32_value_ == other.val_.int32_value_;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return val_.uint64_value_ == other.val_.uint64_value_;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return val_.uint32_value_ == other.val_.uint32_value_;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return val_.bool_value_ == other.val_.bool_value_;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return false;
+ }
+ }
+
+ void CopyFrom(const MapKey& other) {
+ SetType(other.type());
+ switch (type_) {
+ case FieldDescriptor::CPPTYPE_STRING:
+ *val_.string_value_ = *other.val_.string_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_INT64:
+ val_.int64_value_ = other.val_.int64_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_INT32:
+ val_.int32_value_ = other.val_.int32_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT64:
+ val_.uint64_value_ = other.val_.uint64_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_UINT32:
+ val_.uint32_value_ = other.val_.uint32_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_BOOL:
+ val_.bool_value_ = other.val_.bool_value_;
+ break;
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ case FieldDescriptor::CPPTYPE_ENUM:
+ case FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+ }
+
+ private:
+ template <typename K, typename V>
+ friend class internal::TypeDefinedMapFieldBase;
+ friend class MapIterator;
+ friend class internal::DynamicMapField;
+
+ union KeyValue {
+ KeyValue() {}
+ string* string_value_;
+ int64 int64_value_;
+ int32 int32_value_;
+ uint64 uint64_value_;
+ uint32 uint32_value_;
+ bool bool_value_;
+ } val_;
+
+ void SetType(FieldDescriptor::CppType type) {
+ if (type_ == type) return;
+ if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+ delete val_.string_value_;
+ }
+ type_ = type;
+ if (type_ == FieldDescriptor::CPPTYPE_STRING) {
+ val_.string_value_ = new string;
+ }
+ }
+
+ // type_ is 0 or a valid FieldDescriptor::CppType.
+ int type_;
+};
+
+// MapValueRef points to a map value.
+class LIBPROTOBUF_EXPORT MapValueRef {
+ public:
+ MapValueRef() : data_(NULL), type_(0) {}
+
+ void SetInt64Value(int64 value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+ "MapValueRef::SetInt64Value");
+ *reinterpret_cast<int64*>(data_) = value;
+ }
+ void SetUInt64Value(uint64 value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+ "MapValueRef::SetUInt64Value");
+ *reinterpret_cast<uint64*>(data_) = value;
+ }
+ void SetInt32Value(int32 value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+ "MapValueRef::SetInt32Value");
+ *reinterpret_cast<int32*>(data_) = value;
+ }
+ void SetUInt32Value(uint64 value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+ "MapValueRef::SetUInt32Value");
+ *reinterpret_cast<uint32*>(data_) = value;
+ }
+ void SetBoolValue(bool value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+ "MapValueRef::SetBoolValue");
+ *reinterpret_cast<bool*>(data_) = value;
+ }
+ // TODO(jieluo) - Checks that enum is member.
+ void SetEnumValue(int value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
+ "MapValueRef::SetEnumValue");
+ *reinterpret_cast<int*>(data_) = value;
+ }
+ void SetStringValue(const string& value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+ "MapValueRef::SetStringValue");
+ *reinterpret_cast<string*>(data_) = value;
+ }
+ void SetFloatValue(float value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
+ "MapValueRef::SetFloatValue");
+ *reinterpret_cast<float*>(data_) = value;
+ }
+ void SetDoubleValue(double value) {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
+ "MapValueRef::SetDoubleValue");
+ *reinterpret_cast<double*>(data_) = value;
+ }
+
+ int64 GetInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64,
+ "MapValueRef::GetInt64Value");
+ return *reinterpret_cast<int64*>(data_);
+ }
+ uint64 GetUInt64Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64,
+ "MapValueRef::GetUInt64Value");
+ return *reinterpret_cast<uint64*>(data_);
+ }
+ int32 GetInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32,
+ "MapValueRef::GetInt32Value");
+ return *reinterpret_cast<int32*>(data_);
+ }
+ uint32 GetUInt32Value() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32,
+ "MapValueRef::GetUInt32Value");
+ return *reinterpret_cast<uint32*>(data_);
+ }
+ bool GetBoolValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL,
+ "MapValueRef::GetBoolValue");
+ return *reinterpret_cast<bool*>(data_);
+ }
+ int GetEnumValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM,
+ "MapValueRef::GetEnumValue");
+ return *reinterpret_cast<int*>(data_);
+ }
+ const string& GetStringValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING,
+ "MapValueRef::GetStringValue");
+ return *reinterpret_cast<string*>(data_);
+ }
+ float GetFloatValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT,
+ "MapValueRef::GetFloatValue");
+ return *reinterpret_cast<float*>(data_);
+ }
+ double GetDoubleValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE,
+ "MapValueRef::GetDoubleValue");
+ return *reinterpret_cast<double*>(data_);
+ }
+
+ const Message& GetMessageValue() const {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
+ "MapValueRef::GetMessageValue");
+ return *reinterpret_cast<Message*>(data_);
+ }
+
+ Message* MutableMessageValue() {
+ TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE,
+ "MapValueRef::MutableMessageValue");
+ return reinterpret_cast<Message*>(data_);
+ }
+
+ private:
+ template <typename K, typename V,
+ internal::WireFormatLite::FieldType key_wire_type,
+ internal::WireFormatLite::FieldType value_wire_type,
+ int default_enum_value>
+ friend class internal::MapField;
+ template <typename K, typename V>
+ friend class internal::TypeDefinedMapFieldBase;
+ friend class MapIterator;
+ friend class internal::GeneratedMessageReflection;
+ friend class internal::DynamicMapField;
+
+ void SetType(FieldDescriptor::CppType type) {
+ type_ = type;
+ }
+
+ FieldDescriptor::CppType type() const {
+ if (type_ == 0 || data_ == NULL) {
+ GOOGLE_LOG(FATAL)
+ << "Protocol Buffer map usage error:\n"
+ << "MapValueRef::type MapValueRef is not initialized.";
+ }
+ return (FieldDescriptor::CppType)type_;
+ }
+ void SetValue(const void* val) {
+ data_ = const_cast<void*>(val);
+ }
+ void CopyFrom(const MapValueRef& other) {
+ type_ = other.type_;
+ data_ = other.data_;
+ }
+ // Only used in DynamicMapField
+ void DeleteData() {
+ switch (type_) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+ delete reinterpret_cast<TYPE*>(data_); \
+ break; \
+ }
+ HANDLE_TYPE(INT32, int32);
+ HANDLE_TYPE(INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, string);
+ HANDLE_TYPE(ENUM, int32);
+ HANDLE_TYPE(MESSAGE, Message);
+#undef HANDLE_TYPE
+ }
+ }
+ // data_ point to a map value. MapValueRef does not
+ // own this value.
+ void* data_;
+ // type_ is 0 or a valid FieldDescriptor::CppType.
+ int type_;
+};
+
+#undef TYPE_CHECK
// This is the class for google::protobuf::Map's internal value_type. Instead of using
// std::pair as value_type, we use this class which provides us more control of
@@ -82,7 +451,6 @@ class MapPair {
T second;
private:
- typedef void DestructorSkippable_;
friend class ::google::protobuf::Arena;
friend class Map<Key, T>;
};
@@ -92,9 +460,6 @@ class MapPair {
// interface directly to visit or change map fields.
template <typename Key, typename T>
class Map {
- typedef internal::MapCppTypeHandler<Key> KeyTypeHandler;
- typedef internal::MapCppTypeHandler<T> ValueTypeHandler;
-
public:
typedef Key key_type;
typedef T mapped_type;
@@ -118,7 +483,9 @@ class Map {
: arena_(arena),
allocator_(arena_),
elements_(0, hasher(), key_equal(), allocator_),
- default_enum_value_(0) {}
+ default_enum_value_(0) {
+ arena_->OwnDestructor(&elements_);
+ }
Map(const Map& other)
: arena_(NULL),
@@ -127,6 +494,14 @@ class Map {
default_enum_value_(other.default_enum_value_) {
insert(other.begin(), other.end());
}
+ template <class InputIt>
+ explicit Map(const InputIt& first, const InputIt& last)
+ : arena_(NULL),
+ allocator_(arena_),
+ elements_(0, hasher(), key_equal(), allocator_),
+ default_enum_value_(0) {
+ insert(first, last);
+ }
~Map() { clear(); }
@@ -172,7 +547,7 @@ class Map {
!defined(GOOGLE_PROTOBUF_OS_NACL) && !defined(GOOGLE_PROTOBUF_OS_ANDROID)
template<class NodeType, class... Args>
void construct(NodeType* p, Args&&... args) {
- new ((void*)p) NodeType(std::forward<Args>(args)...);
+ new (static_cast<void*>(p)) NodeType(std::forward<Args>(args)...);
}
template<class NodeType>
@@ -206,6 +581,7 @@ class Map {
}
private:
+ typedef void DestructorSkippable_;
Arena* arena_;
template <typename X>
@@ -449,6 +825,58 @@ class Map {
};
} // namespace protobuf
-
} // namespace google
+
+GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START
+template<>
+struct hash<google::protobuf::MapKey> {
+ size_t
+ operator()(const google::protobuf::MapKey& map_key) const {
+ switch (map_key.type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+ return hash<string>()(map_key.GetStringValue());
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+ return hash< ::google::protobuf::int64>()(map_key.GetInt64Value());
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+ return hash< ::google::protobuf::int32>()(map_key.GetInt32Value());
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value());
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+ return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value());
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ return hash<bool>()(map_key.GetBoolValue());
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return 0;
+ }
+ }
+ bool
+ operator()(const google::protobuf::MapKey& map_key1,
+ const google::protobuf::MapKey& map_key2) const {
+ switch (map_key1.type()) {
+#define COMPARE_CPPTYPE(CPPTYPE, CPPTYPE_METHOD) \
+ case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: \
+ return map_key1.Get##CPPTYPE_METHOD##Value() < \
+ map_key2.Get##CPPTYPE_METHOD##Value();
+ COMPARE_CPPTYPE(STRING, String)
+ COMPARE_CPPTYPE(INT64, Int64)
+ COMPARE_CPPTYPE(INT32, Int32)
+ COMPARE_CPPTYPE(UINT64, UInt64)
+ COMPARE_CPPTYPE(UINT32, UInt32)
+ COMPARE_CPPTYPE(BOOL, Bool)
+#undef COMPARE_CPPTYPE
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ return true;
+ }
+ }
+};
+GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END
+
#endif // GOOGLE_PROTOBUF_MAP_H__
diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h
index e93d0348..987c4e29 100644
--- a/src/google/protobuf/map_entry.h
+++ b/src/google/protobuf/map_entry.h
@@ -34,6 +34,7 @@
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/map_entry_lite.h>
#include <google/protobuf/map_type_handler.h>
+#include <google/protobuf/metadata.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/unknown_field_set.h>
#include <google/protobuf/wire_format_lite_inl.h>
@@ -79,40 +80,46 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message {
// MapEntry is the returned google::protobuf::Message when calling AddMessage of
// google::protobuf::Reflection. In order to let it work with generated message
-// reflection, its internal layout is the same as generated message with the
-// same fields. However, in order to decide the internal layout of key/value, we
-// need to know both their cpp type in generated api and proto type.
+// reflection, its in-memory type is the same as generated message with the same
+// fields. However, in order to decide the in-memory type of key/value, we need
+// to know both their cpp type in generated api and proto type. In
+// implmentation, all in-memory types have related wire format functions to
+// support except ArenaStringPtr. Therefore, we need to define another type with
+// supporting wire format functions. Since this type is only used as return type
+// of MapEntry accessors, it's named MapEntry accessor type.
//
-// cpp type | proto type | internal layout
-// int32 TYPE_INT32 int32
-// int32 TYPE_FIXED32 int32
-// FooEnum TYPE_ENUM int
-// FooMessage TYPE_MESSAGE FooMessage*
+// cpp type: the type visible to users in public API.
+// proto type: WireFormatLite::FieldType of the field.
+// in-memory type: type of the data member used to stored this field.
+// MapEntry accessor type: type used in MapEntry getters/mutators to access the
+// field.
//
-// The internal layouts of primitive types can be inferred from its proto type,
-// while we need to explicitly tell cpp type if proto type is TYPE_MESSAGE to
-// get internal layout.
-// Moreover, default_enum_value is used to initialize enum field in proto2.
+// cpp type | proto type | in-memory type | MapEntry accessor type
+// int32 TYPE_INT32 int32 int32
+// int32 TYPE_FIXED32 int32 int32
+// string TYPE_STRING ArenaStringPtr string
+// FooEnum TYPE_ENUM int int
+// FooMessage TYPE_MESSAGE FooMessage* FooMessage
+//
+// The in-memory types of primitive types can be inferred from its proto type,
+// while we need to explicitly specify the cpp type if proto type is
+// TYPE_MESSAGE to infer the in-memory type. Moreover, default_enum_value is
+// used to initialize enum field in proto2.
template <typename Key, typename Value,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType,
int default_enum_value>
class MapEntry : public MapEntryBase {
- // Handlers for key/value wire type. Provide utilities to parse/serialize
- // key/value.
- typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
- typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
-
- // Define key/value's internal stored type. Message is the only one whose
- // internal stored type cannot be inferred from its proto type.
- static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
- static const bool kIsValueMessage = ValueWireHandler::kIsMessage;
- typedef typename KeyWireHandler::CppType KeyInternalType;
- typedef typename ValueWireHandler::CppType ValueInternalType;
- typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type
- KeyCppType;
- typedef typename MapIf<kIsValueMessage, Value, ValueInternalType>::type
- ValCppType;
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
+
+ // Enum type cannot be used for MapTypeHandler::Read. Define a type
+ // which will replace Enum with int.
+ typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
+ typedef typename ValueTypeHandler::MapEntryAccessorType
+ ValueMapEntryAccessorType;
// Abbreviation for MapEntry
typedef typename google::protobuf::internal::MapEntry<
@@ -132,16 +139,16 @@ class MapEntry : public MapEntryBase {
// accessors ======================================================
- virtual inline const KeyCppType& key() const {
+ virtual inline const KeyMapEntryAccessorType& key() const {
return entry_lite_.key();
}
- inline KeyCppType* mutable_key() {
+ inline KeyMapEntryAccessorType* mutable_key() {
return entry_lite_.mutable_key();
}
- virtual inline const ValCppType& value() const {
+ virtual inline const ValueMapEntryAccessorType& value() const {
return entry_lite_.value();
}
- inline ValCppType* mutable_value() {
+ inline ValueMapEntryAccessorType* mutable_value() {
return entry_lite_.mutable_value();
}
@@ -240,7 +247,9 @@ class MapEntry : public MapEntryBase {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _unknown_fields_), -1,
DescriptorPool::generated_pool(),
- ::google::protobuf::MessageFactory::generated_factory(), sizeof(MapEntry), -1);
+ ::google::protobuf::MessageFactory::generated_factory(),
+ sizeof(MapEntry),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_));
entry->descriptor_ = descriptor;
entry->reflection_ = reflection;
entry->set_default_instance(entry);
@@ -250,10 +259,13 @@ class MapEntry : public MapEntryBase {
}
private:
- MapEntry() : default_instance_(NULL), entry_lite_() {}
+ MapEntry()
+ : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {}
explicit MapEntry(Arena* arena)
- : default_instance_(NULL), entry_lite_(arena) {}
+ : _internal_metadata_(arena),
+ default_instance_(NULL),
+ entry_lite_(arena) {}
inline Arena* GetArenaNoVirtual() const {
return entry_lite_.GetArenaNoVirtual();
@@ -266,6 +278,7 @@ class MapEntry : public MapEntryBase {
static int offsets_[2];
UnknownFieldSet _unknown_fields_;
+ InternalMetadataWithArena _internal_metadata_;
MapEntry* default_instance_;
EntryLiteType entry_lite_;
diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h
index 52746da5..7cdf1b93 100644
--- a/src/google/protobuf/map_entry_lite.h
+++ b/src/google/protobuf/map_entry_lite.h
@@ -61,38 +61,21 @@ template <typename Key, typename Value,
WireFormatLite::FieldType kValueFieldType,
int default_enum_value>
class MapEntryLite : public MessageLite {
- // Handlers for key/value wire type. Provide utilities to parse/serialize
- // key/value.
- typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
- typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
-
- // Define key/value's internal stored type. Message is the only one whose
- // internal stored type cannot be inferred from its proto type
- static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
- static const bool kIsValueMessage = ValueWireHandler::kIsMessage;
- typedef typename KeyWireHandler::CppType KeyInternalType;
- typedef typename ValueWireHandler::CppType ValueInternalType;
- typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type
- KeyCppType;
- typedef typename MapIf<kIsValueMessage, Value, ValueInternalType>::type
- ValCppType;
-
- // Handlers for key/value's internal stored type. Provide utilities to
- // manipulate internal stored type. We need it because some types are stored
- // as values and others are stored as pointers (Message and string), but we
- // need to keep the code in MapEntry unified instead of providing different
- // codes for each type.
- typedef MapCppTypeHandler<KeyCppType> KeyCppHandler;
- typedef MapCppTypeHandler<ValCppType> ValueCppHandler;
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, Value> ValueTypeHandler;
// Define internal memory layout. Strings and messages are stored as
// pointers, while other types are stored as values.
- static const bool kKeyIsStringOrMessage = KeyCppHandler::kIsStringOrMessage;
- static const bool kValIsStringOrMessage = ValueCppHandler::kIsStringOrMessage;
- typedef typename MapIf<kKeyIsStringOrMessage, KeyCppType*, KeyCppType>::type
- KeyBase;
- typedef typename MapIf<kValIsStringOrMessage, ValCppType*, ValCppType>::type
- ValueBase;
+ typedef typename KeyTypeHandler::TypeOnMemory KeyOnMemory;
+ typedef typename ValueTypeHandler::TypeOnMemory ValueOnMemory;
+
+ // Enum type cannot be used for MapTypeHandler::Read. Define a type
+ // which will replace Enum with int.
+ typedef typename KeyTypeHandler::MapEntryAccessorType KeyMapEntryAccessorType;
+ typedef typename ValueTypeHandler::MapEntryAccessorType
+ ValueMapEntryAccessorType;
// Constants for field number.
static const int kKeyFieldNumber = 1;
@@ -100,38 +83,37 @@ class MapEntryLite : public MessageLite {
// Constants for field tag.
static const uint8 kKeyTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
- kKeyFieldNumber, KeyWireHandler::kWireType);
+ kKeyFieldNumber, KeyTypeHandler::kWireType);
static const uint8 kValueTag = GOOGLE_PROTOBUF_WIRE_FORMAT_MAKE_TAG(
- kValueFieldNumber, ValueWireHandler::kWireType);
+ kValueFieldNumber, ValueTypeHandler::kWireType);
static const int kTagSize = 1;
public:
~MapEntryLite() {
if (this != default_instance_) {
- KeyCppHandler::Delete(key_);
- ValueCppHandler::Delete(value_);
+ if (GetArenaNoVirtual() != NULL) return;
+ KeyTypeHandler::DeleteNoArena(key_);
+ ValueTypeHandler::DeleteNoArena(value_);
}
}
// accessors ======================================================
- virtual inline const KeyCppType& key() const {
- return KeyCppHandler::Reference(key_);
- }
- inline KeyCppType* mutable_key() {
- set_has_key();
- KeyCppHandler::EnsureMutable(&key_, GetArenaNoVirtual());
- return KeyCppHandler::Pointer(key_);
+ virtual inline const KeyMapEntryAccessorType& key() const {
+ return KeyTypeHandler::GetExternalReference(key_);
}
- virtual inline const ValCppType& value() const {
+ virtual inline const ValueMapEntryAccessorType& value() const {
GOOGLE_CHECK(default_instance_ != NULL);
- return ValueCppHandler::DefaultIfNotInitialized(value_,
+ return ValueTypeHandler::DefaultIfNotInitialized(value_,
default_instance_->value_);
}
- inline ValCppType* mutable_value() {
+ inline KeyMapEntryAccessorType* mutable_key() {
+ set_has_key();
+ return KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
+ }
+ inline ValueMapEntryAccessorType* mutable_value() {
set_has_value();
- ValueCppHandler::EnsureMutable(&value_, GetArenaNoVirtual());
- return ValueCppHandler::Pointer(value_);
+ return ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
}
// implements MessageLite =========================================
@@ -159,13 +141,17 @@ class MapEntryLite : public MessageLite {
tag = input->ReadTag();
switch (tag) {
case kKeyTag:
- if (!KeyWireHandler::Read(input, mutable_key())) return false;
+ if (!KeyTypeHandler::Read(input, mutable_key())) {
+ return false;
+ }
set_has_key();
if (!input->ExpectTag(kValueTag)) break;
GOOGLE_FALLTHROUGH_INTENDED;
case kValueTag:
- if (!ValueWireHandler::Read(input, mutable_value())) return false;
+ if (!ValueTypeHandler::Read(input, mutable_value())) {
+ return false;
+ }
set_has_value();
if (input->ExpectAtEnd()) return true;
break;
@@ -184,32 +170,35 @@ class MapEntryLite : public MessageLite {
int ByteSize() const {
int size = 0;
- size += has_key() ? kTagSize + KeyWireHandler::ByteSize(key()) : 0;
- size += has_value() ? kTagSize + ValueWireHandler::ByteSize(value()) : 0;
+ size += has_key() ? kTagSize + KeyTypeHandler::ByteSize(key()) : 0;
+ size += has_value() ? kTagSize + ValueTypeHandler::ByteSize(value()) : 0;
return size;
}
void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const {
- KeyWireHandler::Write(kKeyFieldNumber, key(), output);
- ValueWireHandler::Write(kValueFieldNumber, value(), output);
+ KeyTypeHandler::Write(kKeyFieldNumber, key(), output);
+ ValueTypeHandler::Write(kValueFieldNumber, value(), output);
}
::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const {
- output = KeyWireHandler::WriteToArray(kKeyFieldNumber, key(), output);
- output =
- ValueWireHandler::WriteToArray(kValueFieldNumber, value(), output);
+ output = KeyTypeHandler::WriteToArray(kKeyFieldNumber, key(), output);
+ output = ValueTypeHandler::WriteToArray(kValueFieldNumber, value(), output);
return output;
}
int GetCachedSize() const {
int size = 0;
- size += has_key() ? kTagSize + KeyWireHandler::GetCachedSize(key()) : 0;
- size +=
- has_value() ? kTagSize + ValueWireHandler::GetCachedSize(value()) : 0;
+ size += has_key()
+ ? kTagSize + KeyTypeHandler::GetCachedSize(key())
+ : 0;
+ size += has_value()
+ ? kTagSize + ValueTypeHandler::GetCachedSize(
+ value())
+ : 0;
return size;
}
- bool IsInitialized() const { return ValueCppHandler::IsInitialized(value_); }
+ bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); }
MessageLite* New() const {
MapEntryLite* entry = new MapEntryLite;
@@ -225,36 +214,37 @@ class MapEntryLite : public MessageLite {
int SpaceUsed() const {
int size = sizeof(MapEntryLite);
- size += KeyCppHandler::SpaceUsedInMapEntry(key_);
- size += ValueCppHandler::SpaceUsedInMapEntry(value_);
+ size += KeyTypeHandler::SpaceUsedInMapEntry(key_);
+ size += ValueTypeHandler::SpaceUsedInMapEntry(value_);
return size;
}
void MergeFrom(const MapEntryLite& from) {
if (from._has_bits_[0]) {
if (from.has_key()) {
- KeyCppHandler::EnsureMutable(&key_, GetArenaNoVirtual());
- KeyCppHandler::Merge(from.key(), &key_);
+ KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual());
+ KeyTypeHandler::Merge(from.key(), &key_, GetArenaNoVirtual());
set_has_key();
}
if (from.has_value()) {
- ValueCppHandler::EnsureMutable(&value_, GetArenaNoVirtual());
- ValueCppHandler::Merge(from.value(), &value_);
+ ValueTypeHandler::EnsureMutable(&value_, GetArenaNoVirtual());
+ ValueTypeHandler::Merge(from.value(), &value_, GetArenaNoVirtual());
set_has_value();
}
}
}
void Clear() {
- KeyCppHandler::Clear(&key_);
- ValueCppHandler::ClearMaybeByDefaultEnum(&value_, default_enum_value);
+ KeyTypeHandler::Clear(&key_, GetArenaNoVirtual());
+ ValueTypeHandler::ClearMaybeByDefaultEnum(
+ &value_, GetArenaNoVirtual(), default_enum_value);
clear_has_key();
clear_has_value();
}
void InitAsDefaultInstance() {
- KeyCppHandler::AssignDefaultValue(&key_);
- ValueCppHandler::AssignDefaultValue(&value_);
+ KeyTypeHandler::AssignDefaultValue(&key_);
+ ValueTypeHandler::AssignDefaultValue(&value_);
}
Arena* GetArena() const {
@@ -305,8 +295,8 @@ class MapEntryLite : public MessageLite {
class MapEntryWrapper
: public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base;
- typedef typename Base::KeyCppType KeyCppType;
- typedef typename Base::ValCppType ValCppType;
+ typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType;
+ typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
public:
MapEntryWrapper(Arena* arena, const K& key, const V& value)
@@ -316,8 +306,8 @@ class MapEntryLite : public MessageLite {
Base::set_has_key();
Base::set_has_value();
}
- inline const KeyCppType& key() const { return key_; }
- inline const ValCppType& value() const { return value_; }
+ inline const KeyMapEntryAccessorType& key() const { return key_; }
+ inline const ValueMapEntryAccessorType& value() const { return value_; }
private:
const Key& key_;
@@ -339,8 +329,8 @@ class MapEntryLite : public MessageLite {
class MapEnumEntryWrapper
: public MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> {
typedef MapEntryLite<K, V, k_wire_type, v_wire_type, default_enum> Base;
- typedef typename Base::KeyCppType KeyCppType;
- typedef typename Base::ValCppType ValCppType;
+ typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType;
+ typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType;
public:
MapEnumEntryWrapper(Arena* arena, const K& key, const V& value)
@@ -350,28 +340,28 @@ class MapEntryLite : public MessageLite {
Base::set_has_key();
Base::set_has_value();
}
- inline const KeyCppType& key() const { return key_; }
- inline const ValCppType& value() const { return value_; }
+ inline const KeyMapEntryAccessorType& key() const { return key_; }
+ inline const ValueMapEntryAccessorType& value() const { return value_; }
private:
- const KeyCppType& key_;
- const ValCppType value_;
+ const KeyMapEntryAccessorType& key_;
+ const ValueMapEntryAccessorType value_;
friend class google::protobuf::Arena;
typedef void DestructorSkippable_;
};
MapEntryLite() : default_instance_(NULL), arena_(NULL) {
- KeyCppHandler::Initialize(&key_, NULL);
- ValueCppHandler::InitializeMaybeByDefaultEnum(
+ KeyTypeHandler::Initialize(&key_, NULL);
+ ValueTypeHandler::InitializeMaybeByDefaultEnum(
&value_, default_enum_value, NULL);
_has_bits_[0] = 0;
}
explicit MapEntryLite(Arena* arena)
: default_instance_(NULL), arena_(arena) {
- KeyCppHandler::Initialize(&key_, arena);
- ValueCppHandler::InitializeMaybeByDefaultEnum(
+ KeyTypeHandler::Initialize(&key_, arena);
+ ValueTypeHandler::InitializeMaybeByDefaultEnum(
&value_, default_enum_value, arena);
_has_bits_[0] = 0;
}
@@ -386,8 +376,8 @@ class MapEntryLite : public MessageLite {
MapEntryLite* default_instance_;
- KeyBase key_;
- ValueBase value_;
+ KeyOnMemory key_;
+ ValueOnMemory value_;
Arena* arena_;
uint32 _has_bits_[1];
diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc
index 6ff1936e..eddc95c4 100644
--- a/src/google/protobuf/map_field.cc
+++ b/src/google/protobuf/map_field.cc
@@ -29,6 +29,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <google/protobuf/map_field.h>
+#include <google/protobuf/map_field_inl.h>
#include <vector>
@@ -145,6 +146,321 @@ void MapFieldBase::SyncMapWithRepeatedField() const {
}
}
+// ------------------DynamicMapField------------------
+DynamicMapField::DynamicMapField(const Message* default_entry)
+ : default_entry_(default_entry) {
+}
+
+DynamicMapField::DynamicMapField(const Message* default_entry,
+ Arena* arena)
+ : TypeDefinedMapFieldBase<MapKey, MapValueRef>(arena),
+ default_entry_(default_entry) {
+}
+
+DynamicMapField::~DynamicMapField() {
+ // DynamicMapField owns map values. Need to delete them before clearing
+ // the map.
+ for (Map<MapKey, MapValueRef>::iterator iter = map_.begin();
+ iter != map_.end(); ++iter) {
+ iter->second.DeleteData();
+ }
+ map_.clear();
+}
+
+int DynamicMapField::size() const {
+ return GetMap().size();
+}
+
+bool DynamicMapField::ContainsMapKey(
+ const MapKey& map_key) const {
+ const Map<MapKey, MapValueRef>& map = GetMap();
+ Map<MapKey, MapValueRef>::const_iterator iter = map.find(map_key);
+ return iter != map.end();
+}
+
+bool DynamicMapField::InsertMapValue(
+ const MapKey& map_key, MapValueRef* val) {
+ bool result = false;
+
+ MapValueRef& map_val = (*MutableMap())[map_key];
+ // If map_val.data_ is not set, it is newly inserted by map_[map_key].
+ if (map_val.data_ == NULL) {
+ result = true;
+ const FieldDescriptor* val_des =
+ default_entry_->GetDescriptor()->FindFieldByName("value");
+ map_val.SetType(val_des->cpp_type());
+ // Allocate momery for the inserted MapValueRef, and initialize to
+ // default value.
+ switch (val_des->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+ TYPE * value = new TYPE(); \
+ map_val.SetValue(value); \
+ break; \
+ }
+ HANDLE_TYPE(INT32, int32);
+ HANDLE_TYPE(INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, string);
+ HANDLE_TYPE(ENUM, int32);
+#undef HANDLE_TYPE
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ const Message& message = default_entry_->GetReflection()->GetMessage(
+ *default_entry_, val_des);
+ Message* value = message.New();
+ map_val.SetValue(value);
+ break;
+ }
+ }
+ }
+ val->CopyFrom(map_val);
+ return result;
+}
+
+bool DynamicMapField::DeleteMapValue(const MapKey& map_key) {
+ MapFieldBase::SyncMapWithRepeatedField();
+ Map<MapKey, MapValueRef>::iterator iter = map_.find(map_key);
+ if (iter == map_.end()) {
+ return false;
+ }
+ // Set map dirty only if the delete is successful.
+ MapFieldBase::SetMapDirty();
+ iter->second.DeleteData();
+ map_.erase(iter);
+ return true;
+}
+
+const Map<MapKey, MapValueRef>& DynamicMapField::GetMap() const {
+ MapFieldBase::SyncMapWithRepeatedField();
+ return map_;
+}
+
+Map<MapKey, MapValueRef>* DynamicMapField::MutableMap() {
+ MapFieldBase::SyncMapWithRepeatedField();
+ MapFieldBase::SetMapDirty();
+ return &map_;
+}
+
+void DynamicMapField::SetMapIteratorValue(MapIterator* map_iter) const {
+ Map<MapKey, MapValueRef>::const_iterator iter =
+ TypeDefinedMapFieldBase<MapKey, MapValueRef>::InternalGetIterator(
+ map_iter);
+ if (iter == map_.end()) return;
+ map_iter->key_.CopyFrom(iter->first);
+ map_iter->value_.CopyFrom(iter->second);
+}
+
+void DynamicMapField::SyncRepeatedFieldWithMapNoLock() const {
+ const Reflection* reflection = default_entry_->GetReflection();
+ const FieldDescriptor* key_des =
+ default_entry_->GetDescriptor()->FindFieldByName("key");
+ const FieldDescriptor* val_des =
+ default_entry_->GetDescriptor()->FindFieldByName("value");
+ if (MapFieldBase::repeated_field_ == NULL) {
+ if (MapFieldBase::arena_ == NULL) {
+ MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
+ } else {
+ MapFieldBase::repeated_field_ =
+ Arena::CreateMessage<RepeatedPtrField<Message> >(
+ MapFieldBase::arena_);
+ }
+ }
+
+ MapFieldBase::repeated_field_->Clear();
+
+ for (Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
+ it != map_.end(); ++it) {
+ Message* new_entry = default_entry_->New();
+ MapFieldBase::repeated_field_->AddAllocated(new_entry);
+ const MapKey& map_key = it->first;
+ switch (key_des->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+ reflection->SetString(new_entry, key_des, map_key.GetStringValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+ reflection->SetInt64(new_entry, key_des, map_key.GetInt64Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+ reflection->SetInt32(new_entry, key_des, map_key.GetInt32Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ reflection->SetUInt64(new_entry, key_des, map_key.GetUInt64Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+ reflection->SetUInt32(new_entry, key_des, map_key.GetUInt32Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ reflection->SetBool(new_entry, key_des, map_key.GetBoolValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+ const MapValueRef& map_val = it->second;
+ switch (val_des->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+ reflection->SetString(new_entry, val_des, map_val.GetStringValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+ reflection->SetInt64(new_entry, val_des, map_val.GetInt64Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+ reflection->SetInt32(new_entry, val_des, map_val.GetInt32Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ reflection->SetUInt64(new_entry, val_des, map_val.GetUInt64Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+ reflection->SetUInt32(new_entry, val_des, map_val.GetUInt32Value());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ reflection->SetBool(new_entry, val_des, map_val.GetBoolValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ reflection->SetDouble(new_entry, val_des, map_val.GetDoubleValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ reflection->SetFloat(new_entry, val_des, map_val.GetFloatValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ reflection->SetEnumValue(new_entry, val_des, map_val.GetEnumValue());
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ const Message& message = map_val.GetMessageValue();
+ reflection->MutableMessage(new_entry, val_des)->CopyFrom(message);
+ break;
+ }
+ }
+ }
+}
+
+void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const {
+ Map<MapKey, MapValueRef>* map = &const_cast<DynamicMapField*>(this)->map_;
+ const Reflection* reflection = default_entry_->GetReflection();
+ const FieldDescriptor* key_des =
+ default_entry_->GetDescriptor()->FindFieldByName("key");
+ const FieldDescriptor* val_des =
+ default_entry_->GetDescriptor()->FindFieldByName("value");
+ // DynamicMapField owns map values. Need to delete them before clearing
+ // the map.
+ for (Map<MapKey, MapValueRef>::iterator iter = map->begin();
+ iter != map->end(); ++iter) {
+ iter->second.DeleteData();
+ }
+ map->clear();
+ for (RepeatedPtrField<Message>::iterator it =
+ MapFieldBase::repeated_field_->begin();
+ it != MapFieldBase::repeated_field_->end(); ++it) {
+ MapKey map_key;
+ switch (key_des->cpp_type()) {
+ case google::protobuf::FieldDescriptor::CPPTYPE_STRING:
+ map_key.SetStringValue(reflection->GetString(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT64:
+ map_key.SetInt64Value(reflection->GetInt64(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_INT32:
+ map_key.SetInt32Value(reflection->GetInt32(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT64:
+ map_key.SetUInt64Value(reflection->GetUInt64(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_UINT32:
+ map_key.SetUInt32Value(reflection->GetUInt32(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_BOOL:
+ map_key.SetBoolValue(reflection->GetBool(*it, key_des));
+ break;
+ case google::protobuf::FieldDescriptor::CPPTYPE_DOUBLE:
+ case google::protobuf::FieldDescriptor::CPPTYPE_FLOAT:
+ case google::protobuf::FieldDescriptor::CPPTYPE_ENUM:
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE:
+ GOOGLE_LOG(FATAL) << "Can't get here.";
+ break;
+ }
+ MapValueRef& map_val = (*map)[map_key];
+ map_val.SetType(val_des->cpp_type());
+ switch (val_des->cpp_type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE, METHOD) \
+ case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+ TYPE * value = new TYPE; \
+ *value = reflection->Get##METHOD(*it, val_des); \
+ map_val.SetValue(value); \
+ break; \
+ }
+ HANDLE_TYPE(INT32, int32, Int32);
+ HANDLE_TYPE(INT64, int64, Int64);
+ HANDLE_TYPE(UINT32, uint32, UInt32);
+ HANDLE_TYPE(UINT64, uint64, UInt64);
+ HANDLE_TYPE(DOUBLE, double, Double);
+ HANDLE_TYPE(FLOAT, float, Float);
+ HANDLE_TYPE(BOOL, bool, Bool);
+ HANDLE_TYPE(STRING, string, String);
+ HANDLE_TYPE(ENUM, int32, EnumValue);
+#undef HANDLE_TYPE
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ const Message& message = reflection->GetMessage(*it, val_des);
+ Message* value = message.New();
+ value->CopyFrom(message);
+ map_val.SetValue(value);
+ break;
+ }
+ }
+ }
+}
+
+int DynamicMapField::SpaceUsedExcludingSelfNoLock() const {
+ int size = 0;
+ if (MapFieldBase::repeated_field_ != NULL) {
+ size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf();
+ }
+ size += sizeof(map_);
+ int map_size = map_.size();
+ if (map_size) {
+ Map<MapKey, MapValueRef>::const_iterator it = map_.begin();
+ size += sizeof(it->first) * map_size;
+ size += sizeof(it->second) * map_size;
+ // If key is string, add the allocated space.
+ if (it->first.type() == google::protobuf::FieldDescriptor::CPPTYPE_STRING) {
+ size += sizeof(string) * map_size;
+ }
+ // Add the allocated space in MapValueRef.
+ switch (it->second.type()) {
+#define HANDLE_TYPE(CPPTYPE, TYPE) \
+ case google::protobuf::FieldDescriptor::CPPTYPE_##CPPTYPE: { \
+ size += sizeof(TYPE) * map_size; \
+ break; \
+ }
+ HANDLE_TYPE(INT32, int32);
+ HANDLE_TYPE(INT64, int64);
+ HANDLE_TYPE(UINT32, uint32);
+ HANDLE_TYPE(UINT64, uint64);
+ HANDLE_TYPE(DOUBLE, double);
+ HANDLE_TYPE(FLOAT, float);
+ HANDLE_TYPE(BOOL, bool);
+ HANDLE_TYPE(STRING, string);
+ HANDLE_TYPE(ENUM, int32);
+#undef HANDLE_TYPE
+ case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: {
+ while (it != map_.end()) {
+ const Message& message = it->second.GetMessageValue();
+ size += message.GetReflection()->SpaceUsed(message);
+ ++it;
+ }
+ break;
+ }
+ }
+ }
+ return size;
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h
index 56d3d0f4..9130166b 100644
--- a/src/google/protobuf/map_field.h
+++ b/src/google/protobuf/map_field.h
@@ -32,6 +32,7 @@
#define GOOGLE_PROTOBUF_MAP_FIELD_H__
#include <google/protobuf/stubs/atomicops.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/arena.h>
@@ -45,7 +46,8 @@
namespace google {
namespace protobuf {
-
+class DynamicMessage;
+class MapKey;
namespace internal {
class ContendedMapCleanTest;
@@ -83,6 +85,17 @@ class LIBPROTOBUF_EXPORT MapFieldBase {
// Like above. Returns mutable pointer to the internal repeated field.
RepeatedPtrFieldBase* MutableRepeatedField();
+ // Pure virtual map APIs for Map Reflection.
+ virtual bool ContainsMapKey(const MapKey& map_key) const = 0;
+ virtual bool InsertMapValue(const MapKey& map_key, MapValueRef* val) = 0;
+ virtual bool DeleteMapValue(const MapKey& map_key) = 0;
+ virtual bool EqualIterator(const MapIterator& a,
+ const MapIterator& b) const = 0;
+ virtual void MapBegin(MapIterator* map_iter) const = 0;
+ virtual void MapEnd(MapIterator* map_iter) const = 0;
+ // Sync Map with repeated field and returns the size of map.
+ virtual int size() const = 0;
+
// Returns the number of bytes used by the repeated field, excluding
// sizeof(*this)
int SpaceUsedExcludingSelf() const;
@@ -141,6 +154,57 @@ class LIBPROTOBUF_EXPORT MapFieldBase {
friend class ContendedMapCleanTest;
friend class GeneratedMessageReflection;
friend class MapFieldAccessor;
+ friend class ::google::protobuf::DynamicMessage;
+
+ // Virtual helper methods for MapIterator. MapIterator doesn't have the
+ // type helper for key and value. Call these help methods to deal with
+ // different types. Real helper methods are implemented in
+ // TypeDefinedMapFieldBase.
+ friend class ::google::protobuf::MapIterator;
+ // Allocate map<...>::iterator for MapIterator.
+ virtual void InitializeIterator(MapIterator* map_iter) const = 0;
+
+ // DeleteIterator() is called by the destructor of MapIterator only.
+ // It deletes map<...>::iterator for MapIterator.
+ virtual void DeleteIterator(MapIterator* map_iter) const = 0;
+
+ // Copy the map<...>::iterator from other_iterator to
+ // this_iterator.
+ virtual void CopyIterator(MapIterator* this_iterator,
+ const MapIterator& other_iterator) const = 0;
+
+ // IncreaseIterator() is called by operator++() of MapIterator only.
+ // It implements the ++ operator of MapIterator.
+ virtual void IncreaseIterator(MapIterator* map_iter) const = 0;
+};
+
+// This class provides common Map Reflection implementations for generated
+// message and dynamic message.
+template<typename Key, typename T>
+class TypeDefinedMapFieldBase : public MapFieldBase {
+ public:
+ TypeDefinedMapFieldBase() {}
+ explicit TypeDefinedMapFieldBase(Arena* arena) : MapFieldBase(arena) {}
+ ~TypeDefinedMapFieldBase() {}
+ void MapBegin(MapIterator* map_iter) const;
+ void MapEnd(MapIterator* map_iter) const;
+ bool EqualIterator(const MapIterator& a, const MapIterator& b) const;
+
+ virtual const Map<Key, T>& GetMap() const = 0;
+ virtual Map<Key, T>* MutableMap() = 0;
+
+ protected:
+ typename Map<Key, T>::const_iterator& InternalGetIterator(
+ const MapIterator* map_iter) const;
+
+ private:
+ void InitializeIterator(MapIterator* map_iter) const;
+ void DeleteIterator(MapIterator* map_iter) const;
+ void CopyIterator(MapIterator* this_iteratorm,
+ const MapIterator& that_iterator) const;
+ void IncreaseIterator(MapIterator* map_iter) const;
+
+ virtual void SetMapIteratorValue(MapIterator* map_iter) const = 0;
};
// This class provides accesss to map field using generated api. It is used for
@@ -150,25 +214,13 @@ template <typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType,
WireFormatLite::FieldType kValueFieldType,
int default_enum_value = 0>
-class MapField : public MapFieldBase,
+class MapField : public TypeDefinedMapFieldBase<Key, T>,
public MapFieldLite<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value> {
- // Handlers for key/value wire type. Provide utilities to parse/serialize
- // key/value.
- typedef MapWireFieldTypeHandler<kKeyFieldType> KeyWireHandler;
- typedef MapWireFieldTypeHandler<kValueFieldType> ValueWireHandler;
-
- // Define key/value's internal stored type.
- static const bool kIsKeyMessage = KeyWireHandler::kIsMessage;
- static const bool kIsValMessage = ValueWireHandler::kIsMessage;
- typedef typename KeyWireHandler::CppType KeyInternalType;
- typedef typename ValueWireHandler::CppType ValueInternalType;
- typedef typename MapIf<kIsKeyMessage, Key, KeyInternalType>::type KeyCpp;
- typedef typename MapIf<kIsValMessage, T , ValueInternalType>::type ValCpp;
-
- // Handlers for key/value's internal stored type.
- typedef MapCppTypeHandler<KeyCpp> KeyHandler;
- typedef MapCppTypeHandler<ValCpp> ValHandler;
+ // Provide utilities to parse/serialize key/value. Provide utilities to
+ // manipulate internal stored type.
+ typedef MapTypeHandler<kKeyFieldType, Key> KeyTypeHandler;
+ typedef MapTypeHandler<kValueFieldType, T> ValueTypeHandler;
// Define message type for internal repeated field.
typedef MapEntry<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>
@@ -183,8 +235,8 @@ class MapField : public MapFieldBase,
// Enum needs to be handled differently from other types because it has
// different exposed type in google::protobuf::Map's api and repeated field's api. For
// details see the comment in the implementation of
- // SyncMapWithRepeatedFieldNoLocki.
- static const bool kIsValueEnum = ValueWireHandler::kIsEnum;
+ // SyncMapWithRepeatedFieldNoLock.
+ static const bool kIsValueEnum = ValueTypeHandler::kIsEnum;
typedef typename MapIf<kIsValueEnum, T, const T&>::type CastValueType;
public:
@@ -197,6 +249,11 @@ class MapField : public MapFieldBase,
MapField(Arena* arena, const Message* default_entry);
~MapField();
+ // Implement MapFieldBase
+ bool ContainsMapKey(const MapKey& map_key) const;
+ bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
+ bool DeleteMapValue(const MapKey& map_key);
+
// Accessors
const Map<Key, T>& GetMap() const;
Map<Key, T>* MutableMap();
@@ -230,12 +287,109 @@ class MapField : public MapFieldBase,
void SyncMapWithRepeatedFieldNoLock() const;
int SpaceUsedExcludingSelfNoLock() const;
+ void SetMapIteratorValue(MapIterator* map_iter) const;
+
mutable const EntryType* default_entry_;
friend class ::google::protobuf::Arena;
};
+class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase<MapKey, MapValueRef> {
+ public:
+ explicit DynamicMapField(const Message* default_entry);
+ DynamicMapField(const Message* default_entry, Arena* arena);
+ ~DynamicMapField();
+
+ // Implement MapFieldBase
+ bool ContainsMapKey(const MapKey& map_key) const;
+ bool InsertMapValue(const MapKey& map_key, MapValueRef* val);
+ bool DeleteMapValue(const MapKey& map_key);
+
+ const Map<MapKey, MapValueRef>& GetMap() const;
+ Map<MapKey, MapValueRef>* MutableMap();
+
+ int size() const;
+
+ private:
+ Map<MapKey, MapValueRef> map_;
+ const Message* default_entry_;
+
+ // Implements MapFieldBase
+ void SyncRepeatedFieldWithMapNoLock() const;
+ void SyncMapWithRepeatedFieldNoLock() const;
+ int SpaceUsedExcludingSelfNoLock() const;
+ void SetMapIteratorValue(MapIterator* map_iter) const;
+};
+
} // namespace internal
+
+class LIBPROTOBUF_EXPORT MapIterator {
+ public:
+ MapIterator(Message* message, const FieldDescriptor* field) {
+ const Reflection* reflection = message->GetReflection();
+ map_ = reflection->MapData(message, field);
+ key_.SetType(field->message_type()->FindFieldByName("key")->cpp_type());
+ value_.SetType(field->message_type()->FindFieldByName("value")->cpp_type());
+ map_->InitializeIterator(this);
+ }
+ MapIterator(const MapIterator& other) {
+ map_ = other.map_;
+ map_->InitializeIterator(this);
+ map_->CopyIterator(this, other);
+ }
+ ~MapIterator() {
+ map_->DeleteIterator(this);
+ }
+ friend bool operator==(const MapIterator& a, const MapIterator& b) {
+ return a.map_->EqualIterator(a, b);
+ }
+ friend bool operator!=(const MapIterator& a, const MapIterator& b) {
+ return !a.map_->EqualIterator(a, b);
+ }
+ MapIterator& operator++() {
+ map_->IncreaseIterator(this);
+ return *this;
+ }
+ MapIterator operator++(int) {
+ // iter_ is copied from Map<...>::iterator, no need to
+ // copy from its self again. Use the same implementation
+ // with operator++()
+ map_->IncreaseIterator(this);
+ return *this;
+ }
+ const MapKey& GetKey() {
+ return key_;
+ }
+ const MapValueRef& GetValueRef() {
+ return value_;
+ }
+ MapValueRef* MutableValueRef() {
+ map_->SetMapDirty();
+ return &value_;
+ }
+
+ private:
+ template <typename Key, typename T>
+ friend class internal::TypeDefinedMapFieldBase;
+ friend class internal::DynamicMapField;
+ template <typename Key, typename T,
+ internal::WireFormatLite::FieldType kKeyFieldType,
+ internal::WireFormatLite::FieldType kValueFieldType,
+ int default_enum_value>
+ friend class internal::MapField;
+
+ // reinterpret_cast from heap-allocated Map<...>::iterator*. MapIterator owns
+ // the iterator. It is allocated by MapField<...>::InitializeIterator() called
+ // in constructor and deleted by MapField<...>::DeleteIterator() called in
+ // destructor.
+ void* iter_;
+ // Point to a MapField to call helper methods implemented in MapField.
+ // MapIterator does not own this object.
+ internal::MapFieldBase* map_;
+ MapKey key_;
+ MapValueRef value_;
+};
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h
index 5b4305f9..16c4a08f 100644
--- a/src/google/protobuf/map_field_inl.h
+++ b/src/google/protobuf/map_field_inl.h
@@ -36,12 +36,130 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <google/protobuf/map.h>
#include <google/protobuf/map_field.h>
#include <google/protobuf/map_type_handler.h>
namespace google {
namespace protobuf {
namespace internal {
+// UnwrapMapKey template
+template<typename T>
+T UnwrapMapKey(const MapKey& map_key);
+template<>
+inline int32 UnwrapMapKey<int32>(const MapKey& map_key) {
+ return map_key.GetInt32Value();
+}
+template<>
+inline uint32 UnwrapMapKey<uint32>(const MapKey& map_key) {
+ return map_key.GetUInt32Value();
+}
+template<>
+inline int64 UnwrapMapKey<int64>(const MapKey& map_key) {
+ return map_key.GetInt64Value();
+}
+template<>
+inline uint64 UnwrapMapKey<uint64>(const MapKey& map_key) {
+ return map_key.GetUInt64Value();
+}
+template<>
+inline bool UnwrapMapKey<bool>(const MapKey& map_key) {
+ return map_key.GetBoolValue();
+}
+template<>
+inline string UnwrapMapKey<string>(const MapKey& map_key) {
+ return map_key.GetStringValue();
+}
+
+// SetMapKey template
+template<typename T>
+inline void SetMapKey(MapKey* map_key, const T& value);
+template<>
+inline void SetMapKey<int32>(MapKey* map_key, const int32& value) {
+ map_key->SetInt32Value(value);
+}
+template<>
+inline void SetMapKey<uint32>(MapKey* map_key, const uint32& value) {
+ map_key->SetUInt32Value(value);
+}
+template<>
+inline void SetMapKey<int64>(MapKey* map_key, const int64& value) {
+ map_key->SetInt64Value(value);
+}
+template<>
+inline void SetMapKey<uint64>(MapKey* map_key, const uint64& value) {
+ map_key->SetUInt64Value(value);
+}
+template<>
+inline void SetMapKey<bool>(MapKey* map_key, const bool& value) {
+ map_key->SetBoolValue(value);
+}
+template<>
+inline void SetMapKey<string>(MapKey* map_key, const string& value) {
+ map_key->SetStringValue(value);
+}
+
+// ------------------------TypeDefinedMapFieldBase---------------
+template <typename Key, typename T>
+typename Map<Key, T>::const_iterator&
+TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(
+ const MapIterator* map_iter) const {
+ return *reinterpret_cast<typename Map<Key, T>::const_iterator *>(
+ map_iter->iter_);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::MapBegin(MapIterator* map_iter) const {
+ InternalGetIterator(map_iter) = GetMap().begin();
+ SetMapIteratorValue(map_iter);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::MapEnd(MapIterator* map_iter) const {
+ InternalGetIterator(map_iter) = GetMap().end();
+}
+
+template <typename Key, typename T>
+bool TypeDefinedMapFieldBase<Key, T>::EqualIterator(const MapIterator& a,
+ const MapIterator& b)
+ const {
+ return InternalGetIterator(&a) == InternalGetIterator(&b);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::IncreaseIterator(MapIterator* map_iter)
+ const {
+ ++InternalGetIterator(map_iter);
+ SetMapIteratorValue(map_iter);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::InitializeIterator(
+ MapIterator* map_iter) const {
+ map_iter->iter_ = new typename Map<Key, T>::const_iterator;
+ GOOGLE_CHECK(map_iter->iter_ != NULL);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::DeleteIterator(MapIterator* map_iter)
+ const {
+ delete reinterpret_cast<typename Map<Key, T>::const_iterator *>(
+ map_iter->iter_);
+}
+
+template <typename Key, typename T>
+void TypeDefinedMapFieldBase<Key, T>::CopyIterator(
+ MapIterator* this_iter,
+ const MapIterator& that_iter) const {
+ InternalGetIterator(this_iter) = InternalGetIterator(&that_iter);
+ this_iter->key_.SetType(that_iter.key_.type());
+ // MapValueRef::type() fails when containing data is null. However, if
+ // this_iter points to MapEnd, data can be null.
+ this_iter->value_.SetType((FieldDescriptor::CppType)that_iter.value_.type_);
+ SetMapIteratorValue(this_iter);
+}
+
+// ----------------------------------------------------------------------
template <typename Key, typename T,
WireFormatLite::FieldType kKeyFieldType,
@@ -56,7 +174,7 @@ template <typename Key, typename T,
int default_enum_value>
MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
Arena* arena)
- : MapFieldBase(arena),
+ : TypeDefinedMapFieldBase<Key, T>(arena),
MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
arena),
default_entry_(NULL) {}
@@ -75,7 +193,7 @@ template <typename Key, typename T,
int default_enum_value>
MapField<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>::MapField(
Arena* arena, const Message* default_entry)
- : MapFieldBase(arena),
+ : TypeDefinedMapFieldBase<Key, T>(arena),
MapFieldLite<Key, T, kKeyFieldType, kValueFieldType, default_enum_value>(
arena),
default_entry_(down_cast<const EntryType*>(default_entry)) {}
@@ -94,7 +212,7 @@ template <typename Key, typename T,
int
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::size() const {
- SyncMapWithRepeatedField();
+ MapFieldBase::SyncMapWithRepeatedField();
return MapFieldLiteType::GetInternalMap().size();
}
@@ -105,9 +223,65 @@ template <typename Key, typename T,
void
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::Clear() {
- SyncMapWithRepeatedField();
+ MapFieldBase::SyncMapWithRepeatedField();
MapFieldLiteType::MutableInternalMap()->clear();
- SetMapDirty();
+ MapFieldBase::SetMapDirty();
+}
+
+template <typename Key, typename T,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType,
+ int default_enum_value>
+void MapField<Key, T, kKeyFieldType, kValueFieldType,
+ default_enum_value>::SetMapIteratorValue(
+ MapIterator* map_iter) const {
+ const Map<Key, T>& map = GetMap();
+ typename Map<Key, T>::const_iterator iter =
+ TypeDefinedMapFieldBase<Key, T>::InternalGetIterator(map_iter);
+ if (iter == map.end()) return;
+ SetMapKey(&map_iter->key_, iter->first);
+ map_iter->value_.SetValue(&iter->second);
+}
+
+template <typename Key, typename T,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType,
+ int default_enum_value>
+bool MapField<Key, T, kKeyFieldType, kValueFieldType,
+ default_enum_value>::ContainsMapKey(
+ const MapKey& map_key) const {
+ const Map<Key, T>& map = GetMap();
+ const Key& key = UnwrapMapKey<Key>(map_key);
+ typename Map<Key, T>::const_iterator iter = map.find(key);
+ return iter != map.end();
+}
+
+template <typename Key, typename T,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType,
+ int default_enum_value>
+bool MapField<Key, T, kKeyFieldType, kValueFieldType,
+ default_enum_value>::InsertMapValue(const MapKey& map_key,
+ MapValueRef* val) {
+ Map<Key, T>* map = MutableMap();
+ bool result = false;
+ const Key& key = UnwrapMapKey<Key>(map_key);
+ if (map->end() == map->find(key)) {
+ result = true;
+ }
+ val->SetValue(&((*map)[key]));
+ return result;
+}
+
+template <typename Key, typename T,
+ WireFormatLite::FieldType kKeyFieldType,
+ WireFormatLite::FieldType kValueFieldType,
+ int default_enum_value>
+bool MapField<Key, T, kKeyFieldType, kValueFieldType,
+ default_enum_value>::DeleteMapValue(
+ const MapKey& map_key) {
+ const Key& key = UnwrapMapKey<Key>(map_key);
+ return MutableMap()->erase(key);
}
template <typename Key, typename T,
@@ -117,7 +291,7 @@ template <typename Key, typename T,
const Map<Key, T>&
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::GetMap() const {
- SyncMapWithRepeatedField();
+ MapFieldBase::SyncMapWithRepeatedField();
return MapFieldLiteType::GetInternalMap();
}
@@ -128,9 +302,9 @@ template <typename Key, typename T,
Map<Key, T>*
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::MutableMap() {
- SyncMapWithRepeatedField();
+ MapFieldBase::SyncMapWithRepeatedField();
Map<Key, T>* result = MapFieldLiteType::MutableInternalMap();
- SetMapDirty();
+ MapFieldBase::SetMapDirty();
return result;
}
@@ -143,10 +317,10 @@ MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::MergeFrom(
const MapFieldLiteType& other) {
const MapField& down_other = down_cast<const MapField&>(other);
- SyncMapWithRepeatedField();
+ MapFieldBase::SyncMapWithRepeatedField();
down_other.SyncMapWithRepeatedField();
MapFieldLiteType::MergeFrom(other);
- SetMapDirty();
+ MapFieldBase::SetMapDirty();
}
template <typename Key, typename T,
@@ -158,9 +332,9 @@ MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::Swap(
MapFieldLiteType* other) {
MapField* down_other = down_cast<MapField*>(other);
- std::swap(repeated_field_, down_other->repeated_field_);
+ std::swap(MapFieldBase::repeated_field_, down_other->repeated_field_);
MapFieldLiteType::Swap(other);
- std::swap(state_, down_other->state_);
+ std::swap(MapFieldBase::state_, down_other->state_);
}
template <typename Key, typename T,
@@ -171,7 +345,7 @@ void
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::SetEntryDescriptor(
const Descriptor** descriptor) {
- entry_descriptor_ = descriptor;
+ MapFieldBase::entry_descriptor_ = descriptor;
}
template <typename Key, typename T,
@@ -181,7 +355,7 @@ template <typename Key, typename T,
void
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::SetAssignDescriptorCallback(void (*callback)()) {
- assign_descriptor_callback_ = callback;
+ MapFieldBase::assign_descriptor_callback_ = callback;
}
template <typename Key, typename T,
@@ -211,17 +385,19 @@ template <typename Key, typename T,
void
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::SyncRepeatedFieldWithMapNoLock() const {
- if (repeated_field_ == NULL) {
+ if (MapFieldBase::repeated_field_ == NULL) {
if (MapFieldBase::arena_ == NULL) {
- repeated_field_ = new RepeatedPtrField<Message>();
+ MapFieldBase::repeated_field_ = new RepeatedPtrField<Message>();
} else {
- repeated_field_ = Arena::CreateMessage<RepeatedPtrField<Message> >(
- MapFieldBase::arena_);
+ MapFieldBase::repeated_field_ =
+ Arena::CreateMessage<RepeatedPtrField<Message> >(
+ MapFieldBase::arena_);
}
}
const Map<Key, T>& map = GetInternalMap();
RepeatedPtrField<EntryType>* repeated_field =
- reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
+ reinterpret_cast<RepeatedPtrField<EntryType>*>(
+ MapFieldBase::repeated_field_);
repeated_field->Clear();
@@ -246,7 +422,9 @@ MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::SyncMapWithRepeatedFieldNoLock() const {
Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
RepeatedPtrField<EntryType>* repeated_field =
- reinterpret_cast<RepeatedPtrField<EntryType>*>(repeated_field_);
+ reinterpret_cast<RepeatedPtrField<EntryType>*>(
+ MapFieldBase::repeated_field_);
+ GOOGLE_CHECK(MapFieldBase::repeated_field_ != NULL);
map->clear();
for (typename RepeatedPtrField<EntryType>::iterator it =
repeated_field->begin(); it != repeated_field->end(); ++it) {
@@ -267,15 +445,15 @@ int
MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::SpaceUsedExcludingSelfNoLock() const {
int size = 0;
- if (repeated_field_ != NULL) {
- size += repeated_field_->SpaceUsedExcludingSelf();
+ if (MapFieldBase::repeated_field_ != NULL) {
+ size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf();
}
Map<Key, T>* map = const_cast<MapField*>(this)->MutableInternalMap();
size += sizeof(*map);
for (typename Map<Key, T>::iterator it = map->begin();
it != map->end(); ++it) {
- size += KeyHandler::SpaceUsedInMap(it->first);
- size += ValHandler::SpaceUsedInMap(it->second);
+ size += KeyTypeHandler::SpaceUsedInMap(it->first);
+ size += ValueTypeHandler::SpaceUsedInMap(it->second);
}
return size;
}
@@ -289,10 +467,11 @@ MapField<Key, T, kKeyFieldType, kValueFieldType,
default_enum_value>::InitDefaultEntryOnce()
const {
if (default_entry_ == NULL) {
- InitMetadataOnce();
- GOOGLE_CHECK(*entry_descriptor_ != NULL);
+ MapFieldBase::InitMetadataOnce();
+ GOOGLE_CHECK(*MapFieldBase::entry_descriptor_ != NULL);
default_entry_ = down_cast<const EntryType*>(
- MessageFactory::generated_factory()->GetPrototype(*entry_descriptor_));
+ MessageFactory::generated_factory()->GetPrototype(
+ *MapFieldBase::entry_descriptor_));
}
}
diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc
index e3a64079..2ff1d6bb 100644
--- a/src/google/protobuf/map_field_test.cc
+++ b/src/google/protobuf/map_field_test.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/map.h>
@@ -74,6 +75,28 @@ class MapFieldBaseStub : public MapFieldBase {
bool IsRepeatedClean() { return state_ != 1; }
void SetMapDirty() { state_ = 0; }
void SetRepeatedDirty() { state_ = 1; }
+ bool ContainsMapKey(const MapKey& map_key) const {
+ return false;
+ }
+ bool InsertMapValue(const MapKey& map_key, MapValueRef* val) {
+ return false;
+ }
+ bool DeleteMapValue(const MapKey& map_key) {
+ return false;
+ }
+ bool EqualIterator(const MapIterator& a, const MapIterator& b) const {
+ return false;
+ }
+ int size() const { return 0; }
+ void MapBegin(MapIterator* map_iter) const {}
+ void MapEnd(MapIterator* map_iter) const {}
+ void InitializeIterator(MapIterator* map_iter) const {}
+ void DeleteIterator(MapIterator* map_iter) const {}
+ void CopyIterator(MapIterator* this_iterator,
+ const MapIterator& other_iterator) const {}
+ void IncreaseIterator(MapIterator* map_iter) const {}
+ void SetDefaultMessageEntry(const Message* message) const {}
+ const Message* GetDefaultMessageEntry() const { return NULL; }
};
class MapFieldBasePrimitiveTest : public ::testing::Test {
diff --git a/src/google/protobuf/map_lite_unittest.proto b/src/google/protobuf/map_lite_unittest.proto
index c69e8d94..0592dd7a 100644
--- a/src/google/protobuf/map_lite_unittest.proto
+++ b/src/google/protobuf/map_lite_unittest.proto
@@ -34,6 +34,7 @@ option cc_enable_arenas = true;
option optimize_for = LITE_RUNTIME;
import "google/protobuf/unittest_lite.proto";
+import "google/protobuf/unittest_no_arena_lite.proto";
package protobuf_unittest;
@@ -72,8 +73,12 @@ message TestArenaMapLite {
map<int32 , float > map_int32_float = 11;
map<int32 , double > map_int32_double = 12;
map<bool , bool > map_bool_bool = 13;
- map<int32 , MapEnumLite> map_int32_enum = 14;
- map<int32 , ForeignMessageArenaLite> map_int32_foreign_message = 15;
+ map<string , string > map_string_string = 14;
+ map<int32 , bytes > map_int32_bytes = 15;
+ map<int32 , MapEnumLite> map_int32_enum = 16;
+ map<int32 , ForeignMessageArenaLite> map_int32_foreign_message = 17;
+ map<int32, .protobuf_unittest_no_arena.ForeignMessageLite>
+ map_int32_foreign_message_no_arena = 18;
}
// Test embeded message with required fields
@@ -81,10 +86,6 @@ message TestRequiredMessageMapLite {
map<int32, TestRequiredLite> map_field = 1;
}
-message TestEnumStartWithNonZeroMapLite {
- map<int32, Proto2MapEnumStartWithNonZeroLite> map_field = 101;
-}
-
message TestEnumMapLite {
map<int32, Proto2MapEnumLite> known_map_field = 101;
map<int32, Proto2MapEnumLite> unknown_map_field = 102;
@@ -112,10 +113,6 @@ enum Proto2MapEnumPlusExtraLite {
E_PROTO2_MAP_ENUM_EXTRA_LITE = 3;
}
-enum Proto2MapEnumStartWithNonZeroLite {
- PROTO2_NON_ZERO_MAP_ENUM_FOO_LITE = 1;
-}
-
enum MapEnumLite {
MAP_ENUM_FOO_LITE = 0;
MAP_ENUM_BAR_LITE = 1;
diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto
index 3d4af28e..6f9d6165 100644
--- a/src/google/protobuf/map_proto2_unittest.proto
+++ b/src/google/protobuf/map_proto2_unittest.proto
@@ -49,10 +49,6 @@ enum Proto2MapEnumPlusExtra {
E_PROTO2_MAP_ENUM_EXTRA = 3;
}
-enum Proto2MapEnumStartWithNonZero {
- PROTO2_NON_ZERO_MAP_ENUM_FOO = 1;
-}
-
message TestEnumMap {
map<int32, Proto2MapEnum> known_map_field = 101;
map<int32, Proto2MapEnum> unknown_map_field = 102;
@@ -62,7 +58,3 @@ message TestEnumMapPlusExtra {
map<int32, Proto2MapEnumPlusExtra> known_map_field = 101;
map<int32, Proto2MapEnumPlusExtra> unknown_map_field = 102;
}
-
-message TestEnumStartWithNonZeroMap {
- map<int32, Proto2MapEnumStartWithNonZero> map_field = 101;
-}
diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc
index d62ec85f..16a24c25 100644
--- a/src/google/protobuf/map_test.cc
+++ b/src/google/protobuf/map_test.cc
@@ -36,7 +36,9 @@
#include <sstream>
#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/scoped_ptr.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/arena_test_util.h>
@@ -70,6 +72,7 @@ namespace google {
using google::protobuf::unittest::ForeignMessage;
using google::protobuf::unittest::TestAllTypes;
using google::protobuf::unittest::TestMap;
+using google::protobuf::unittest::TestRecursiveMapMessage;
namespace protobuf {
namespace internal {
@@ -200,6 +203,21 @@ TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) {
EXPECT_DEATH(const_map_.at(0), "");
}
+TEST_F(MapImplTest, UsageErrors) {
+ MapKey key;
+ key.SetInt64Value(1);
+ EXPECT_DEATH(key.GetUInt64Value(),
+ "Protocol Buffer map usage error:\n"
+ "MapKey::GetUInt64Value type does not match\n"
+ " Expected : uint64\n"
+ " Actual : int64");
+
+ MapValueRef value;
+ EXPECT_DEATH(value.SetFloatValue(0.1),
+ "Protocol Buffer map usage error:\n"
+ "MapValueRef::type MapValueRef is not initialized.");
+}
+
#endif // PROTOBUF_HAS_DEATH_TEST
TEST_F(MapImplTest, CountNonExist) {
@@ -475,6 +493,23 @@ TEST_F(MapImplTest, CopyConstructor) {
EXPECT_EQ(value2, other.at(key2));
}
+TEST_F(MapImplTest, IterConstructor) {
+ int32 key1 = 0;
+ int32 key2 = 1;
+ int32 value1 = 100;
+ int32 value2 = 101;
+
+ std::map<int32, int32> map;
+ map[key1] = value1;
+ map[key2] = value2;
+
+ Map<int32, int32> new_map(map.begin(), map.end());
+
+ EXPECT_EQ(2, new_map.size());
+ EXPECT_EQ(value1, new_map.at(key1));
+ EXPECT_EQ(value2, new_map.at(key2));
+}
+
TEST_F(MapImplTest, Assigner) {
int32 key1 = 0;
int32 key2 = 1;
@@ -1140,6 +1175,19 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
mmf_int32_foreign_message.Add(*entry_int32_foreign_message);
EXPECT_EQ(1234, message.map_int32_foreign_message().at(4321).c());
+ // Test Reflection::AddAllocatedMessage
+ Message* free_entry_string_string = MessageFactory::generated_factory()
+ ->GetPrototype(fd_map_string_string->message_type())
+ ->New();
+ entry_string_string->GetReflection()->SetString(
+ free_entry_string_string,
+ fd_map_string_string->message_type()->field(0), "4321");
+ entry_string_string->GetReflection()->SetString(
+ free_entry_string_string, fd_map_string_string->message_type()->field(1),
+ "1234");
+ refl->AddAllocatedMessage(&message, fd_map_string_string,
+ free_entry_string_string);
+
// Test MutableRepeatedFieldRef::RemoveLast()
mmf_int32_int32.RemoveLast();
mmf_int32_double.RemoveLast();
@@ -1147,7 +1195,7 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefForRegularFields) {
mmf_int32_foreign_message.RemoveLast();
EXPECT_EQ(10, message.map_int32_int32().size());
EXPECT_EQ(10, message.map_int32_double().size());
- EXPECT_EQ(10, message.map_string_string().size());
+ EXPECT_EQ(11, message.map_string_string().size());
EXPECT_EQ(10, message.map_int32_foreign_message().size());
// Test MutableRepeatedFieldRef::SwapElements()
@@ -1398,9 +1446,9 @@ TEST(GeneratedMapFieldTest, SetMapFieldsInitialized) {
}
TEST(GeneratedMapFieldTest, Proto2SetMapFieldsInitialized) {
- unittest::TestEnumStartWithNonZeroMap message;
- EXPECT_EQ(unittest::PROTO2_NON_ZERO_MAP_ENUM_FOO,
- (*message.mutable_map_field())[0]);
+ unittest::TestEnumMap message;
+ EXPECT_EQ(unittest::PROTO2_MAP_ENUM_FOO,
+ (*message.mutable_known_map_field())[0]);
}
TEST(GeneratedMapFieldTest, Clear) {
@@ -1526,12 +1574,28 @@ TEST(GeneratedMapFieldTest, CopyFromDynamicMessage) {
google::protobuf::scoped_ptr<Message> message1;
message1.reset(
factory.GetPrototype(unittest::TestMap::descriptor())->New());
-
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.SetMapFieldsViaReflection(message1.get());
reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+ message2.CopyFrom(*message1);
+ MapTestUtil::ExpectMapFieldsSet(message2);
+}
+
+TEST(GeneratedMapFieldTest, CopyFromDynamicMessageMapReflection) {
+ unittest::TestMap message2;
+ // Construct a new version of the dynamic message via the factory.
+ DynamicMessageFactory factory;
+ google::protobuf::scoped_ptr<Message> message1;
+ message1.reset(
+ factory.GetPrototype(unittest::TestMap::descriptor())->New());
+ MapReflectionTester reflection_tester(
+ unittest::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(message1.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
message2.CopyFrom(*message1);
MapTestUtil::ExpectMapFieldsSet(message2);
}
@@ -1547,12 +1611,43 @@ TEST(GeneratedMapFieldTest, DynamicMessageCopyFrom) {
message1.reset(
factory.GetPrototype(unittest::TestMap::descriptor())->New());
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
+ unittest::TestMap::descriptor());
+ message1->MergeFrom(message2);
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
+}
+
+TEST(GeneratedMapFieldTest, DynamicMessageCopyFromMapReflection) {
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
+ unittest::TestMap message2;
+ reflection_tester.SetMapFieldsViaMapReflection(&message2);
+
+ // Construct a dynamic message via the factory.
+ DynamicMessageFactory factory;
+ google::protobuf::scoped_ptr<Message> message1;
+ message1.reset(
+ factory.GetPrototype(unittest::TestMap::descriptor())->New());
+
message1->MergeFrom(message2);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message1.get());
reflection_tester.ExpectMapFieldsSetViaReflection(*message1);
}
+TEST(GeneratedMapFieldTest, SyncDynamicMapWithRepeatedField) {
+ // Construct a dynamic message via the factory.
+ MapReflectionTester reflection_tester(
+ unittest::TestMap::descriptor());
+ DynamicMessageFactory factory;
+ google::protobuf::scoped_ptr<Message> message;
+ message.reset(
+ factory.GetPrototype(unittest::TestMap::descriptor())->New());
+ reflection_tester.SetMapFieldsViaReflection(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(message.get());
+ reflection_tester.ExpectMapFieldsSetViaReflection(*message);
+}
+
#endif // !PROTOBUF_TEST_NO_DESCRIPTORS
TEST(GeneratedMapFieldTest, NonEmptyMergeFrom) {
@@ -1779,7 +1874,7 @@ TEST(GeneratedMapFieldTest, IsInitialized) {
TEST(GeneratedMapFieldReflectionTest, SpaceUsed) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.SetMapFieldsViaReflection(&message);
@@ -1790,11 +1885,12 @@ TEST(GeneratedMapFieldReflectionTest, Accessors) {
// Set every field to a unique value then go back and check all those
// values.
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.SetMapFieldsViaReflection(&message);
MapTestUtil::ExpectMapFieldsSet(message);
reflection_tester.ExpectMapFieldsSetViaReflection(message);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message);
reflection_tester.ModifyMapFieldsViaReflection(&message);
MapTestUtil::ExpectMapFieldsModified(message);
@@ -1848,15 +1944,16 @@ TEST(GeneratedMapFieldReflectionTest, ClearField) {
MapTestUtil::SetMapFields(&message);
MapTestUtil::ExpectMapFieldsSet(message);
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.ClearMapFieldsViaReflection(&message);
- MapTestUtil::ExpectClear(message);
+ reflection_tester.ExpectClearViaReflection(message);
+ reflection_tester.ExpectClearViaReflectionIterator(&message);
}
TEST(GeneratedMapFieldReflectionTest, RemoveLast) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
MapTestUtil::SetMapFields(&message);
@@ -1875,7 +1972,7 @@ TEST(GeneratedMapFieldReflectionTest, RemoveLast) {
TEST(GeneratedMapFieldReflectionTest, ReleaseLast) {
unittest::TestMap message;
const Descriptor* descriptor = message.GetDescriptor();
- MapTestUtil::MapReflectionTester reflection_tester(descriptor);
+ MapReflectionTester reflection_tester(descriptor);
MapTestUtil::SetMapFields(&message);
@@ -1904,7 +2001,7 @@ TEST(GeneratedMapFieldReflectionTest, ReleaseLast) {
TEST(GeneratedMapFieldReflectionTest, SwapElements) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
MapTestUtil::SetMapFields(&message);
@@ -1944,7 +2041,7 @@ TEST(GeneratedMapFieldReflectionTest, SwapElements) {
TEST(GeneratedMapFieldReflectionTest, MutableUnknownFields) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message);
}
@@ -2000,24 +2097,35 @@ TEST(GeneratedMapFieldReflectionTest, MergeFromClearMapEntry) {
TEST(GeneratedMapFieldReflectionTest, MapEntryClear) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester reflection_tester(
+ MapReflectionTester reflection_tester(
unittest::TestMap::descriptor());
reflection_tester.MutableUnknownFieldsOfMapFieldsViaReflection(&message);
}
TEST(GeneratedMapFieldReflectionTest, Proto2MapEntryClear) {
- unittest::TestEnumStartWithNonZeroMap message;
+ unittest::TestEnumMap message;
const Descriptor* descriptor = message.GetDescriptor();
const FieldDescriptor* field_descriptor =
- descriptor->FindFieldByName("map_field");
+ descriptor->FindFieldByName("known_map_field");
const FieldDescriptor* value_descriptor =
field_descriptor->message_type()->FindFieldByName("value");
Message* sub_message =
message.GetReflection()->AddMessage(&message, field_descriptor);
- EXPECT_EQ(1, sub_message->GetReflection()->GetEnumValue(*sub_message,
+ EXPECT_EQ(0, sub_message->GetReflection()->GetEnumValue(*sub_message,
value_descriptor));
}
+// Map Reflection API Test =========================================
+
+TEST(GeneratedMapFieldReflectionTest, SetViaMapReflection) {
+ unittest::TestMap message;
+ MapReflectionTester reflection_tester(
+ unittest::TestMap::descriptor());
+ reflection_tester.SetMapFieldsViaMapReflection(&message);
+ reflection_tester.ExpectMapFieldsSetViaReflection(message);
+ reflection_tester.ExpectMapFieldsSetViaReflectionIterator(&message);
+}
+
// Dynamic Message Test =============================================
class MapFieldInDynamicMessageTest : public testing::Test {
@@ -2025,6 +2133,7 @@ class MapFieldInDynamicMessageTest : public testing::Test {
const DescriptorPool* pool_;
DynamicMessageFactory factory_;
const Descriptor* map_descriptor_;
+ const Descriptor* recursive_map_descriptor_;
const Message* map_prototype_;
MapFieldInDynamicMessageTest()
@@ -2033,7 +2142,10 @@ class MapFieldInDynamicMessageTest : public testing::Test {
virtual void SetUp() {
map_descriptor_ =
pool_->FindMessageTypeByName("protobuf_unittest.TestMap");
+ recursive_map_descriptor_ =
+ pool_->FindMessageTypeByName("protobuf_unittest.TestRecursiveMapMessage");
ASSERT_TRUE(map_descriptor_ != NULL);
+ ASSERT_TRUE(recursive_map_descriptor_ != NULL);
map_prototype_ = factory_.GetPrototype(map_descriptor_);
}
};
@@ -2043,19 +2155,19 @@ TEST_F(MapFieldInDynamicMessageTest, MapIndependentOffsets) {
// one to a unique value then checking that they all still have those
// unique values (i.e. they don't stomp each other).
scoped_ptr<Message> message(map_prototype_->New());
- MapTestUtil::MapReflectionTester reflection_tester(map_descriptor_);
+ MapReflectionTester reflection_tester(map_descriptor_);
reflection_tester.SetMapFieldsViaReflection(message.get());
reflection_tester.ExpectMapFieldsSetViaReflection(*message);
}
-TEST_F(MapFieldInDynamicMessageTest, Map) {
+TEST_F(MapFieldInDynamicMessageTest, DynamicMapReflection) {
// Check that map fields work properly.
scoped_ptr<Message> message(map_prototype_->New());
// Check set functions.
- MapTestUtil::MapReflectionTester reflection_tester(map_descriptor_);
- reflection_tester.SetMapFieldsViaReflection(message.get());
+ MapReflectionTester reflection_tester(map_descriptor_);
+ reflection_tester.SetMapFieldsViaMapReflection(message.get());
reflection_tester.ExpectMapFieldsSetViaReflection(*message);
}
@@ -2066,7 +2178,7 @@ TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) {
// to test very much here. Just make sure it appears to be working.
scoped_ptr<Message> message(map_prototype_->New());
- MapTestUtil::MapReflectionTester reflection_tester(map_descriptor_);
+ MapReflectionTester reflection_tester(map_descriptor_);
int initial_space_used = message->SpaceUsed();
@@ -2074,6 +2186,15 @@ TEST_F(MapFieldInDynamicMessageTest, MapSpaceUsed) {
EXPECT_LT(initial_space_used, message->SpaceUsed());
}
+TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) {
+ TestRecursiveMapMessage from;
+ (*from.mutable_a())[""];
+ string data = from.SerializeAsString();
+ google::protobuf::scoped_ptr<Message> to(
+ factory_.GetPrototype(recursive_map_descriptor_)->New());
+ ASSERT_TRUE(to->ParseFromString(data));
+}
+
// ReflectionOps Test ===============================================
TEST(ReflectionOpsForMapFieldTest, MapSanityCheck) {
@@ -2260,7 +2381,7 @@ TEST(TextFormatMapTest, SerializeAndParse) {
TEST(TextFormatMapTest, Sorted) {
unittest::TestMap message;
- MapTestUtil::MapReflectionTester tester(message.GetDescriptor());
+ MapReflectionTester tester(message.GetDescriptor());
tester.SetMapFieldsViaReflection(&message);
string expected_text;
@@ -2292,7 +2413,8 @@ TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) {
data.reserve(128 * 1024);
{
- NoHeapChecker no_heap;
+ // TODO(teboring): Enable no heap check when ArenaStringPtr is used in map.
+ // NoHeapChecker no_heap;
unittest::TestArenaMap* from =
Arena::CreateMessage<unittest::TestArenaMap>(&arena);
@@ -2326,6 +2448,22 @@ TEST(ArenaTest, RelfectionInTextFormat) {
MapTestUtil::ExpectArenaMapFieldsSet(*to);
}
+// Make sure the memory allocated for string in map is deallocated.
+TEST(ArenaTest, StringMapNoLeak) {
+ Arena arena;
+ unittest::TestArenaMap* message =
+ Arena::CreateMessage<unittest::TestArenaMap>(&arena);
+ string data;
+ // String with length less than 16 will not be allocated from heap.
+ int original_capacity = data.capacity();
+ while (data.capacity() <= original_capacity) {
+ data.append("a");
+ }
+ (*message->mutable_map_string_string())[data] = data;
+ // We rely on heap checkers to detect memory leak for us.
+ ASSERT_FALSE(message == NULL);
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc
index 1713e373..ae094647 100644
--- a/src/google/protobuf/map_test_util.cc
+++ b/src/google/protobuf/map_test_util.cc
@@ -209,7 +209,7 @@ std::vector<const Message*> MapTestUtil::GetMapEntriesFromRelease(
return result;
}
-MapTestUtil::MapReflectionTester::MapReflectionTester(
+MapReflectionTester::MapReflectionTester(
const Descriptor* base_descriptor)
: base_descriptor_(base_descriptor) {
const DescriptorPool* pool = base_descriptor->file()->pool();
@@ -329,14 +329,14 @@ MapTestUtil::MapReflectionTester::MapReflectionTester(
}
// Shorthand to get a FieldDescriptor for a field of unittest::TestMap.
-const FieldDescriptor* MapTestUtil::MapReflectionTester::F(const string& name) {
+const FieldDescriptor* MapReflectionTester::F(const string& name) {
const FieldDescriptor* result = NULL;
result = base_descriptor_->FindFieldByName(name);
GOOGLE_CHECK(result != NULL);
return result;
}
-void MapTestUtil::MapReflectionTester::SetMapFieldsViaReflection(
+void MapReflectionTester::SetMapFieldsViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
Message* sub_message = NULL;
@@ -555,7 +555,196 @@ void MapTestUtil::MapReflectionTester::SetMapFieldsViaReflection(
SetInt32(sub_foreign_message, foreign_c_, 1);
}
-void MapTestUtil::MapReflectionTester::ClearMapFieldsViaReflection(
+void MapReflectionTester::SetMapFieldsViaMapReflection(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+
+ Message* sub_foreign_message = NULL;
+ MapValueRef map_val;
+
+ // Add first element.
+ MapKey map_key;
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_int32"), map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int64_int64"), map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetUInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint32_uint32"), map_key, &map_val));
+ map_val.SetUInt32Value(0);
+
+ map_key.SetUInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint64_uint64"), map_key, &map_val));
+ map_val.SetUInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sint32_sint32"), map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sint64_sint64"), map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetUInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_fixed32_fixed32"), map_key, &map_val));
+ map_val.SetUInt32Value(0);
+
+ map_key.SetUInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_fixed64_fixed64"), map_key, &map_val));
+ map_val.SetUInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed32_sfixed32"), map_key, &map_val));
+ map_val.SetInt32Value(0);
+
+ map_key.SetInt64Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed64_sfixed64"), map_key, &map_val));
+ map_val.SetInt64Value(0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_float"), map_key, &map_val));
+ map_val.SetFloatValue(0.0);
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_double"), map_key, &map_val));
+ map_val.SetDoubleValue(0.0);
+
+ map_key.SetBoolValue(false);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_bool_bool"), map_key, &map_val));
+ map_val.SetBoolValue(false);
+
+ map_key.SetStringValue("0");
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_string_string"), map_key, &map_val));
+ map_val.SetStringValue("0");
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_bytes"), map_key, &map_val));
+ map_val.SetStringValue("0");
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_enum"), map_key, &map_val));
+ map_val.SetEnumValue(map_enum_bar_->number());
+
+ map_key.SetInt32Value(0);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(
+ sub_foreign_message, foreign_c_, 0);
+
+ // Add second element
+ map_key.SetInt32Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_int32"), map_key, &map_val));
+ map_val.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_int32"), map_key, &map_val));
+
+ map_key.SetInt64Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int64_int64"), map_key, &map_val));
+ map_val.SetInt64Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int64_int64"), map_key, &map_val));
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_uint32_uint32"), map_key, &map_val);
+ map_val.SetUInt32Value(1);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_uint64_uint64"), map_key, &map_val);
+ map_val.SetUInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sint32_sint32"), map_key, &map_val);
+ map_val.SetInt32Value(1);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sint64_sint64"), map_key, &map_val);
+ map_val.SetInt64Value(1);
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_fixed32_fixed32"), map_key, &map_val);
+ map_val.SetUInt32Value(1);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_fixed64_fixed64"), map_key, &map_val);
+ map_val.SetUInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed32_sfixed32"), map_key, &map_val);
+ map_val.SetInt32Value(1);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed64_sfixed64"), map_key, &map_val);
+ map_val.SetInt64Value(1);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_float"), map_key, &map_val);
+ map_val.SetFloatValue(1.0);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_double"), map_key, &map_val);
+ map_val.SetDoubleValue(1.0);
+
+ map_key.SetBoolValue(true);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_bool_bool"), map_key, &map_val);
+ map_val.SetBoolValue(true);
+
+ map_key.SetStringValue("1");
+ reflection->InsertOrLookupMapValue(
+ message, F("map_string_string"), map_key, &map_val);
+ map_val.SetStringValue("1");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_bytes"), map_key, &map_val);
+ map_val.SetStringValue("1");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_enum"), map_key, &map_val);
+ map_val.SetEnumValue(map_enum_baz_->number());
+
+ map_key.SetInt32Value(1);
+ EXPECT_TRUE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(
+ sub_foreign_message, foreign_c_, 1);
+}
+
+void MapReflectionTester::ClearMapFieldsViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
@@ -578,97 +767,103 @@ void MapTestUtil::MapReflectionTester::ClearMapFieldsViaReflection(
reflection->ClearField(message, F("map_int32_foreign_message"));
}
-void MapTestUtil::MapReflectionTester::ModifyMapFieldsViaReflection(
+void MapReflectionTester::ModifyMapFieldsViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
- Message* sub_message;
+ MapValueRef map_val;
Message* sub_foreign_message;
- // Find out which one's key is 0.
- int size = reflection->FieldSize(*message, F("map_int32_int32"));
- int target = 0;
- for (int i = 0; i < size; i++) {
- const Message& temp_message = reflection
- ->GetRepeatedMessage(*message, F("map_int32_int32"), i);
- if (temp_message.GetReflection()
- ->GetInt32(temp_message, map_int32_int32_key_) == 1) {
- target = i;
- }
- }
-
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_int32"), target);
- sub_message->GetReflection()
- ->SetInt32(sub_message, map_int32_int32_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int64_int64"), target);
- sub_message->GetReflection()
- ->SetInt64(sub_message, map_int64_int64_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_uint32_uint32"), target);
- sub_message->GetReflection()
- ->SetUInt32(sub_message, map_uint32_uint32_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_uint64_uint64"), target);
- sub_message->GetReflection()
- ->SetUInt64(sub_message, map_uint64_uint64_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_sint32_sint32"), target);
- sub_message->GetReflection()
- ->SetInt32(sub_message, map_sint32_sint32_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_sint64_sint64"), target);
- sub_message->GetReflection()
- ->SetInt64(sub_message, map_sint64_sint64_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_fixed32_fixed32"), target);
- sub_message->GetReflection()
- ->SetUInt32(sub_message, map_fixed32_fixed32_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_fixed64_fixed64"), target);
- sub_message->GetReflection()
- ->SetUInt64(sub_message, map_fixed64_fixed64_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_sfixed32_sfixed32"), target);
- sub_message->GetReflection()
- ->SetInt32(sub_message, map_sfixed32_sfixed32_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_sfixed64_sfixed64"), target);
- sub_message->GetReflection()
- ->SetInt64(sub_message, map_sfixed64_sfixed64_val_, 2);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_float"), target);
- sub_message->GetReflection()
- ->SetFloat(sub_message, map_int32_float_val_, 2.0);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_double"), target);
- sub_message->GetReflection()
- ->SetDouble(sub_message, map_int32_double_val_, 2.0);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_bool_bool"), target);
- sub_message->GetReflection()
- ->SetBool(sub_message, map_bool_bool_val_, false);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_string_string"), target);
- sub_message->GetReflection()
- ->SetString(sub_message, map_string_string_val_, "2");
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_bytes"), target);
- sub_message->GetReflection()
- ->SetString(sub_message, map_int32_bytes_val_, "2");
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_enum"), target);
- sub_message->GetReflection()
- ->SetEnum(sub_message, map_int32_enum_val_, map_enum_foo_);
- sub_message = reflection
- ->MutableRepeatedMessage(message, F("map_int32_foreign_message"), target);
- sub_foreign_message = sub_message->GetReflection()->
- MutableMessage(sub_message, map_int32_foreign_message_val_, NULL);
- sub_foreign_message->GetReflection()->
- SetInt32(sub_foreign_message, foreign_c_, 2);
+ // Modify the second element
+ MapKey map_key;
+ map_key.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_int32"), map_key, &map_val));
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int64_int64"), map_key, &map_val));
+ map_val.SetInt64Value(2);
+
+ map_key.SetUInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_uint32_uint32"), map_key, &map_val));
+ map_val.SetUInt32Value(2);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_uint64_uint64"), map_key, &map_val);
+ map_val.SetUInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sint32_sint32"), map_key, &map_val);
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sint64_sint64"), map_key, &map_val);
+ map_val.SetInt64Value(2);
+
+ map_key.SetUInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_fixed32_fixed32"), map_key, &map_val);
+ map_val.SetUInt32Value(2);
+
+ map_key.SetUInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_fixed64_fixed64"), map_key, &map_val);
+ map_val.SetUInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed32_sfixed32"), map_key, &map_val);
+ map_val.SetInt32Value(2);
+
+ map_key.SetInt64Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_sfixed64_sfixed64"), map_key, &map_val);
+ map_val.SetInt64Value(2);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_float"), map_key, &map_val);
+ map_val.SetFloatValue(2.0);
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_double"), map_key, &map_val);
+ map_val.SetDoubleValue(2.0);
+
+ map_key.SetBoolValue(true);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_bool_bool"), map_key, &map_val);
+ map_val.SetBoolValue(false);
+
+ map_key.SetStringValue("1");
+ reflection->InsertOrLookupMapValue(
+ message, F("map_string_string"), map_key, &map_val);
+ map_val.SetStringValue("2");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_bytes"), map_key, &map_val);
+ map_val.SetStringValue("2");
+
+ map_key.SetInt32Value(1);
+ reflection->InsertOrLookupMapValue(
+ message, F("map_int32_enum"), map_key, &map_val);
+ map_val.SetEnumValue(map_enum_foo_->number());
+
+ map_key.SetInt32Value(1);
+ EXPECT_FALSE(reflection->InsertOrLookupMapValue(
+ message, F("map_int32_foreign_message"), map_key, &map_val));
+ sub_foreign_message = map_val.MutableMessageValue();
+ sub_foreign_message->GetReflection()->SetInt32(
+ sub_foreign_message, foreign_c_, 2);
}
-void MapTestUtil::MapReflectionTester::RemoveLastMapsViaReflection(
+void MapReflectionTester::RemoveLastMapsViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
@@ -681,7 +876,7 @@ void MapTestUtil::MapReflectionTester::RemoveLastMapsViaReflection(
}
}
-void MapTestUtil::MapReflectionTester::ReleaseLastMapsViaReflection(
+void MapReflectionTester::ReleaseLastMapsViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
@@ -699,7 +894,7 @@ void MapTestUtil::MapReflectionTester::ReleaseLastMapsViaReflection(
}
}
-void MapTestUtil::MapReflectionTester::SwapMapsViaReflection(Message* message) {
+void MapReflectionTester::SwapMapsViaReflection(Message* message) {
const Reflection* reflection = message->GetReflection();
vector<const FieldDescriptor*> output;
reflection->ListFields(*message, &output);
@@ -710,7 +905,7 @@ void MapTestUtil::MapReflectionTester::SwapMapsViaReflection(Message* message) {
}
}
-void MapTestUtil::MapReflectionTester::
+void MapReflectionTester::
MutableUnknownFieldsOfMapFieldsViaReflection(Message* message) {
const Reflection* reflection = message->GetReflection();
Message* sub_message = NULL;
@@ -768,11 +963,12 @@ void MapTestUtil::MapReflectionTester::
NULL);
}
-void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
+void MapReflectionTester::ExpectMapFieldsSetViaReflection(
const Message& message) {
string scratch;
const Reflection* reflection = message.GetReflection();
const Message* sub_message;
+ MapKey map_key;
// -----------------------------------------------------------------
@@ -799,6 +995,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
map[0] = 0;
map[1] = 1;
for (int i = 0; i < 2; i++) {
+ // Check with RepeatedField Reflection
sub_message =
&reflection->GetRepeatedMessage(message, F("map_int32_int32"), i);
int32 key = sub_message->GetReflection()->GetInt32(
@@ -806,6 +1003,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int32 val = sub_message->GetReflection()->GetInt32(
*sub_message, map_int32_int32_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_TRUE(reflection->ContainsMapKey(
+ message, F("map_int32_int32"), map_key));
}
}
{
@@ -813,6 +1014,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
map[0] = 0;
map[1] = 1;
for (int i = 0; i < 2; i++) {
+ // Check with RepeatedField Reflection
sub_message =
&reflection->GetRepeatedMessage(message, F("map_int64_int64"), i);
int64 key = sub_message->GetReflection()->GetInt64(
@@ -820,6 +1022,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int64 val = sub_message->GetReflection()->GetInt64(
*sub_message, map_int64_int64_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt64Value(key);
+ EXPECT_TRUE(reflection->ContainsMapKey(
+ message, F("map_int64_int64"), map_key));
}
}
{
@@ -827,6 +1033,7 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
map[0] = 0;
map[1] = 1;
for (int i = 0; i < 2; i++) {
+ // Check with RepeatedField Reflection
sub_message =
&reflection->GetRepeatedMessage(message, F("map_uint32_uint32"), i);
uint32 key = sub_message->GetReflection()->GetUInt32(
@@ -834,6 +1041,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
uint32 val = sub_message->GetReflection()->GetUInt32(
*sub_message, map_uint32_uint32_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetUInt32Value(key);
+ EXPECT_TRUE(reflection->ContainsMapKey(
+ message, F("map_uint32_uint32"), map_key));
}
}
{
@@ -848,6 +1059,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
uint64 val = sub_message->GetReflection()->GetUInt64(
*sub_message, map_uint64_uint64_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetUInt64Value(key);
+ EXPECT_TRUE(reflection->ContainsMapKey(
+ message, F("map_uint64_uint64"), map_key));
}
}
{
@@ -862,6 +1077,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int32 val = sub_message->GetReflection()->GetInt32(
*sub_message, map_sint32_sint32_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sint32_sint32"), map_key));
}
}
{
@@ -876,6 +1095,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int64 val = sub_message->GetReflection()->GetInt64(
*sub_message, map_sint64_sint64_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt64Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sint64_sint64"), map_key));
}
}
{
@@ -890,6 +1113,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
uint32 val = sub_message->GetReflection()->GetUInt32(
*sub_message, map_fixed32_fixed32_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetUInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_fixed32_fixed32"), map_key));
}
}
{
@@ -904,6 +1131,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
uint64 val = sub_message->GetReflection()->GetUInt64(
*sub_message, map_fixed64_fixed64_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetUInt64Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_fixed64_fixed64"), map_key));
}
}
{
@@ -918,6 +1149,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int32 val = sub_message->GetReflection()->GetInt32(
*sub_message, map_sfixed32_sfixed32_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sfixed32_sfixed32"), map_key));
}
}
{
@@ -932,6 +1167,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int64 val = sub_message->GetReflection()->GetInt64(
*sub_message, map_sfixed64_sfixed64_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt64Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_sfixed64_sfixed64"), map_key));
}
}
{
@@ -946,6 +1185,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
float val = sub_message->GetReflection()->GetFloat(
*sub_message, map_int32_float_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_float"), map_key));
}
}
{
@@ -960,6 +1203,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
double val = sub_message->GetReflection()->GetDouble(
*sub_message, map_int32_double_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_double"), map_key));
}
}
{
@@ -974,6 +1221,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
bool val = sub_message->GetReflection()->GetBool(
*sub_message, map_bool_bool_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetBoolValue(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_bool_bool"), map_key));
}
}
{
@@ -988,6 +1239,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
string val = sub_message->GetReflection()->GetString(
*sub_message, map_string_string_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetStringValue(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_string_string"), map_key));
}
}
{
@@ -1002,6 +1257,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
string val = sub_message->GetReflection()->GetString(
*sub_message, map_int32_bytes_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_bytes"), map_key));
}
}
{
@@ -1016,6 +1275,10 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
const EnumValueDescriptor* val = sub_message->GetReflection()->GetEnum(
*sub_message, map_int32_enum_val_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_enum"), map_key));
}
}
{
@@ -1032,11 +1295,245 @@ void MapTestUtil::MapReflectionTester::ExpectMapFieldsSetViaReflection(
int32 val = foreign_message.GetReflection()->GetInt32(
foreign_message, foreign_c_);
EXPECT_EQ(map[key], val);
+ // Check with Map Reflection
+ map_key.SetInt32Value(key);
+ EXPECT_EQ(true, reflection->ContainsMapKey(
+ message, F("map_int32_foreign_message"), map_key));
}
}
}
-void MapTestUtil::MapReflectionTester::ExpectClearViaReflection(
+void MapReflectionTester::ExpectMapFieldsSetViaReflectionIterator(
+ Message* message) {
+ string scratch;
+ string serialized;
+ const Reflection* reflection = message->GetReflection();
+
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_int32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int64_int64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint32_uint32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_uint64_uint64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint32_sint32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sint64_sint64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed32_fixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_fixed64_fixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed32_sfixed32")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_sfixed64_sfixed64")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_float")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_double")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_bool_bool")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_string_string")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_bytes")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_enum")));
+ ASSERT_EQ(2, reflection->FieldSize(*message, F("map_int32_foreign_message")));
+
+ {
+ std::map<int32, int32> map;
+ map[0] = 0;
+ map[1] = 1;
+ int size = 0;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_int32"));
+ iter != reflection->MapEnd(message, F("map_int32_int32"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsed();
+ message->ByteSize();
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ EXPECT_EQ(size, 2);
+ }
+ {
+ std::map<int64, int64> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int64_int64"));
+ iter != reflection->MapEnd(message, F("map_int64_int64")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt64Value()],
+ iter.GetValueRef().GetInt64Value());
+ }
+ }
+ {
+ std::map<uint32, uint32> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_uint32_uint32"));
+ iter != reflection->MapEnd(message, F("map_uint32_uint32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt32Value()],
+ iter.GetValueRef().GetUInt32Value());
+ }
+ }
+ {
+ std::map<uint64, uint64> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_uint64_uint64"));
+ iter != reflection->MapEnd(message, F("map_uint64_uint64"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt64Value()],
+ iter.GetValueRef().GetUInt64Value());
+ }
+ }
+ {
+ std::map<int32, int32> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_sint32_sint32"));
+ iter != reflection->MapEnd(message, F("map_sint32_sint32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ }
+ {
+ std::map<int64, int64> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_sint64_sint64"));
+ iter != reflection->MapEnd(message, F("map_sint64_sint64")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt64Value()],
+ iter.GetValueRef().GetInt64Value());
+ }
+ }
+ {
+ std::map<uint32, uint32> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_fixed32_fixed32"));
+ iter != reflection->MapEnd(message, F("map_fixed32_fixed32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt32Value()],
+ iter.GetValueRef().GetUInt32Value());
+ }
+ }
+ {
+ std::map<uint64, uint64> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_fixed64_fixed64"));
+ iter != reflection->MapEnd(message, F("map_fixed64_fixed64"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetUInt64Value()],
+ iter.GetValueRef().GetUInt64Value());
+ }
+ }
+ {
+ std::map<int32, int32> map;
+ map[0] = 0;
+ map[1] = 1;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_sfixed32_sfixed32"));
+ iter != reflection->MapEnd(message, F("map_sfixed32_sfixed32"));
+ ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetInt32Value());
+ }
+ }
+ {
+ std::map<int32, float> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_float"));
+ iter != reflection->MapEnd(message, F("map_int32_float")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetFloatValue());
+ }
+ }
+ {
+ std::map<int32, double> map;
+ map[0] = 0.0;
+ map[1] = 1.0;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_int32_double"));
+ iter != reflection->MapEnd(message, F("map_int32_double")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetDoubleValue());
+ }
+ }
+ {
+ std::map<bool, bool> map;
+ map[false] = false;
+ map[true] = true;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_bool_bool"));
+ iter != reflection->MapEnd(message, F("map_bool_bool")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetBoolValue()],
+ iter.GetValueRef().GetBoolValue());
+ }
+ }
+ {
+ std::map<string, string> map;
+ map["0"] = "0";
+ map["1"] = "1";
+ int size = 0;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_string_string"));
+ iter != reflection->MapEnd(message, F("map_string_string"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsed();
+ message->ByteSize();
+ EXPECT_EQ(map[iter.GetKey().GetStringValue()],
+ iter.GetValueRef().GetStringValue());
+ }
+ EXPECT_EQ(size, 2);
+ }
+ {
+ std::map<int32, string> map;
+ map[0] = "0";
+ map[1] = "1";
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_bytes"));
+ iter != reflection->MapEnd(message, F("map_int32_bytes")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ iter.GetValueRef().GetStringValue());
+ }
+ }
+ {
+ std::map<int32, const EnumValueDescriptor*> map;
+ map[0] = map_enum_bar_;
+ map[1] = map_enum_baz_;
+ for (MapIterator iter = reflection->MapBegin(message, F("map_int32_enum"));
+ iter != reflection->MapEnd(message, F("map_int32_enum")); ++iter) {
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()]->number(),
+ iter.GetValueRef().GetEnumValue());
+ }
+ }
+ {
+ std::map<int32, int32> map;
+ map[0] = 0;
+ map[1] = 1;
+ int size = 0;
+ for (MapIterator iter = reflection->MapBegin(
+ message, F("map_int32_foreign_message"));
+ iter != reflection->MapEnd(message, F("map_int32_foreign_message"));
+ ++iter, ++size) {
+ // Check const methods do not invalidate map.
+ message->DebugString();
+ message->ShortDebugString();
+ message->SerializeToString(&serialized);
+ message->SpaceUsed();
+ message->ByteSize();
+ const Message& sub_message = iter.GetValueRef().GetMessageValue();
+ EXPECT_EQ(map[iter.GetKey().GetInt32Value()],
+ sub_message.GetReflection()->GetInt32(sub_message, foreign_c_));
+ }
+ EXPECT_EQ(size, 2);
+ }
+}
+
+void MapReflectionTester::ExpectClearViaReflection(
const Message& message) {
const Reflection* reflection = message.GetReflection();
// Map fields are empty.
@@ -1059,7 +1556,46 @@ void MapTestUtil::MapReflectionTester::ExpectClearViaReflection(
EXPECT_EQ(0, reflection->FieldSize(message, F("map_int32_foreign_message")));
}
-void MapTestUtil::MapReflectionTester::ExpectMapEntryClearViaReflection(
+void MapReflectionTester::ExpectClearViaReflectionIterator(
+ Message* message) {
+ const Reflection* reflection = message->GetReflection();
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_int32")) ==
+ reflection->MapEnd(message, F("map_int32_int32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int64_int64")) ==
+ reflection->MapEnd(message, F("map_int64_int64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_uint32_uint32")) ==
+ reflection->MapEnd(message, F("map_uint32_uint32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_uint64_uint64")) ==
+ reflection->MapEnd(message, F("map_uint64_uint64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sint32_sint32")) ==
+ reflection->MapEnd(message, F("map_sint32_sint32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sint64_sint64")) ==
+ reflection->MapEnd(message, F("map_sint64_sint64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed32_fixed32")) ==
+ reflection->MapEnd(message, F("map_fixed32_fixed32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_fixed64_fixed64")) ==
+ reflection->MapEnd(message, F("map_fixed64_fixed64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed32_sfixed32")) ==
+ reflection->MapEnd(message, F("map_sfixed32_sfixed32")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_sfixed64_sfixed64")) ==
+ reflection->MapEnd(message, F("map_sfixed64_sfixed64")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_float")) ==
+ reflection->MapEnd(message, F("map_int32_float")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_double")) ==
+ reflection->MapEnd(message, F("map_int32_double")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_bool_bool")) ==
+ reflection->MapEnd(message, F("map_bool_bool")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_string_string")) ==
+ reflection->MapEnd(message, F("map_string_string")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_bytes")) ==
+ reflection->MapEnd(message, F("map_int32_bytes")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_enum")) ==
+ reflection->MapEnd(message, F("map_int32_enum")));
+ EXPECT_TRUE(reflection->MapBegin(message, F("map_int32_foreign_message")) ==
+ reflection->MapEnd(message, F("map_int32_foreign_message")));
+}
+
+void MapReflectionTester::ExpectMapEntryClearViaReflection(
Message* message) {
const Reflection* reflection = message->GetReflection();
const Message* sub_message;
diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h
index f437e33e..107a639d 100644
--- a/src/google/protobuf/map_test_util.h
+++ b/src/google/protobuf/map_test_util.h
@@ -83,71 +83,74 @@ class MapTestUtil {
// Get pointers of map entries from release.
static std::vector<const Message*> GetMapEntriesFromRelease(
unittest::TestMap* message);
+};
- // Like above, but use the reflection interface.
- class MapReflectionTester {
- public:
- // base_descriptor must be a descriptor for TestMap, which is used for
- // MapReflectionTester to fetch the FieldDescriptors needed to use the
- // reflection interface.
- explicit MapReflectionTester(const Descriptor* base_descriptor);
-
- void SetMapFieldsViaReflection(Message* message);
- void ClearMapFieldsViaReflection(Message* message);
- void ModifyMapFieldsViaReflection(Message* message);
- void RemoveLastMapsViaReflection(Message* message);
- void ReleaseLastMapsViaReflection(Message* message);
- void SwapMapsViaReflection(Message* message);
- void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message);
- void ExpectMapFieldsSetViaReflection(const Message& message);
- void ExpectClearViaReflection(const Message& message);
- void ExpectMapEntryClearViaReflection(Message* message);
-
- private:
- const FieldDescriptor* F(const string& name);
-
- const Descriptor* base_descriptor_;
-
- const EnumValueDescriptor* map_enum_bar_;
- const EnumValueDescriptor* map_enum_baz_;
- const EnumValueDescriptor* map_enum_foo_;
-
- const FieldDescriptor* foreign_c_;
- const FieldDescriptor* map_int32_int32_key_;
- const FieldDescriptor* map_int32_int32_val_;
- const FieldDescriptor* map_int64_int64_key_;
- const FieldDescriptor* map_int64_int64_val_;
- const FieldDescriptor* map_uint32_uint32_key_;
- const FieldDescriptor* map_uint32_uint32_val_;
- const FieldDescriptor* map_uint64_uint64_key_;
- const FieldDescriptor* map_uint64_uint64_val_;
- const FieldDescriptor* map_sint32_sint32_key_;
- const FieldDescriptor* map_sint32_sint32_val_;
- const FieldDescriptor* map_sint64_sint64_key_;
- const FieldDescriptor* map_sint64_sint64_val_;
- const FieldDescriptor* map_fixed32_fixed32_key_;
- const FieldDescriptor* map_fixed32_fixed32_val_;
- const FieldDescriptor* map_fixed64_fixed64_key_;
- const FieldDescriptor* map_fixed64_fixed64_val_;
- const FieldDescriptor* map_sfixed32_sfixed32_key_;
- const FieldDescriptor* map_sfixed32_sfixed32_val_;
- const FieldDescriptor* map_sfixed64_sfixed64_key_;
- const FieldDescriptor* map_sfixed64_sfixed64_val_;
- const FieldDescriptor* map_int32_float_key_;
- const FieldDescriptor* map_int32_float_val_;
- const FieldDescriptor* map_int32_double_key_;
- const FieldDescriptor* map_int32_double_val_;
- const FieldDescriptor* map_bool_bool_key_;
- const FieldDescriptor* map_bool_bool_val_;
- const FieldDescriptor* map_string_string_key_;
- const FieldDescriptor* map_string_string_val_;
- const FieldDescriptor* map_int32_bytes_key_;
- const FieldDescriptor* map_int32_bytes_val_;
- const FieldDescriptor* map_int32_enum_key_;
- const FieldDescriptor* map_int32_enum_val_;
- const FieldDescriptor* map_int32_foreign_message_key_;
- const FieldDescriptor* map_int32_foreign_message_val_;
- };
+// Like above, but use the reflection interface.
+class MapReflectionTester {
+ public:
+ // base_descriptor must be a descriptor for TestMap, which is used for
+ // MapReflectionTester to fetch the FieldDescriptors needed to use the
+ // reflection interface.
+ explicit MapReflectionTester(const Descriptor* base_descriptor);
+
+ void SetMapFieldsViaReflection(Message* message);
+ void SetMapFieldsViaMapReflection(Message* message);
+ void ClearMapFieldsViaReflection(Message* message);
+ void ModifyMapFieldsViaReflection(Message* message);
+ void RemoveLastMapsViaReflection(Message* message);
+ void ReleaseLastMapsViaReflection(Message* message);
+ void SwapMapsViaReflection(Message* message);
+ void MutableUnknownFieldsOfMapFieldsViaReflection(Message* message);
+ void ExpectMapFieldsSetViaReflection(const Message& message);
+ void ExpectMapFieldsSetViaReflectionIterator(Message* message);
+ void ExpectClearViaReflection(const Message& message);
+ void ExpectClearViaReflectionIterator(Message* message);
+ void ExpectMapEntryClearViaReflection(Message* message);
+
+ private:
+ const FieldDescriptor* F(const string& name);
+
+ const Descriptor* base_descriptor_;
+
+ const EnumValueDescriptor* map_enum_bar_;
+ const EnumValueDescriptor* map_enum_baz_;
+ const EnumValueDescriptor* map_enum_foo_;
+
+ const FieldDescriptor* foreign_c_;
+ const FieldDescriptor* map_int32_int32_key_;
+ const FieldDescriptor* map_int32_int32_val_;
+ const FieldDescriptor* map_int64_int64_key_;
+ const FieldDescriptor* map_int64_int64_val_;
+ const FieldDescriptor* map_uint32_uint32_key_;
+ const FieldDescriptor* map_uint32_uint32_val_;
+ const FieldDescriptor* map_uint64_uint64_key_;
+ const FieldDescriptor* map_uint64_uint64_val_;
+ const FieldDescriptor* map_sint32_sint32_key_;
+ const FieldDescriptor* map_sint32_sint32_val_;
+ const FieldDescriptor* map_sint64_sint64_key_;
+ const FieldDescriptor* map_sint64_sint64_val_;
+ const FieldDescriptor* map_fixed32_fixed32_key_;
+ const FieldDescriptor* map_fixed32_fixed32_val_;
+ const FieldDescriptor* map_fixed64_fixed64_key_;
+ const FieldDescriptor* map_fixed64_fixed64_val_;
+ const FieldDescriptor* map_sfixed32_sfixed32_key_;
+ const FieldDescriptor* map_sfixed32_sfixed32_val_;
+ const FieldDescriptor* map_sfixed64_sfixed64_key_;
+ const FieldDescriptor* map_sfixed64_sfixed64_val_;
+ const FieldDescriptor* map_int32_float_key_;
+ const FieldDescriptor* map_int32_float_val_;
+ const FieldDescriptor* map_int32_double_key_;
+ const FieldDescriptor* map_int32_double_val_;
+ const FieldDescriptor* map_bool_bool_key_;
+ const FieldDescriptor* map_bool_bool_val_;
+ const FieldDescriptor* map_string_string_key_;
+ const FieldDescriptor* map_string_string_val_;
+ const FieldDescriptor* map_int32_bytes_key_;
+ const FieldDescriptor* map_int32_bytes_val_;
+ const FieldDescriptor* map_int32_enum_key_;
+ const FieldDescriptor* map_int32_enum_val_;
+ const FieldDescriptor* map_int32_foreign_message_key_;
+ const FieldDescriptor* map_int32_foreign_message_val_;
};
} // namespace protobuf
diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h
index 5e7882a1..7e8757ed 100644
--- a/src/google/protobuf/map_test_util_impl.h
+++ b/src/google/protobuf/map_test_util_impl.h
@@ -31,6 +31,7 @@
#ifndef GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
#define GOOGLE_PROTOBUF_MAP_TEST_UTIL_IMPL_H__
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
@@ -167,8 +168,11 @@ void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) {
(*message->mutable_map_int32_float())[0] = 0.0;
(*message->mutable_map_int32_double())[0] = 0.0;
(*message->mutable_map_bool_bool())[0] = false;
+ (*message->mutable_map_string_string())["0"] = "0";
+ (*message->mutable_map_int32_bytes())[0] = "0";
(*message->mutable_map_int32_enum())[0] = enum_value0;
(*message->mutable_map_int32_foreign_message())[0].set_c(0);
+ (*message->mutable_map_int32_foreign_message_no_arena())[0].set_c(0);
// Add second element
(*message->mutable_map_int32_int32())[1] = 1;
@@ -184,8 +188,11 @@ void MapTestUtilImpl::SetArenaMapFields(MapMessage* message) {
(*message->mutable_map_int32_float())[1] = 1.0;
(*message->mutable_map_int32_double())[1] = 1.0;
(*message->mutable_map_bool_bool())[1] = true;
+ (*message->mutable_map_string_string())["1"] = "1";
+ (*message->mutable_map_int32_bytes())[1] = "1";
(*message->mutable_map_int32_enum())[1] = enum_value1;
(*message->mutable_map_int32_foreign_message())[1].set_c(1);
+ (*message->mutable_map_int32_foreign_message_no_arena())[1].set_c(1);
}
template <typename MapMessage>
@@ -329,8 +336,11 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) {
EXPECT_EQ(2, message.map_int32_float().size());
EXPECT_EQ(2, message.map_int32_double().size());
EXPECT_EQ(2, message.map_bool_bool().size());
+ EXPECT_EQ(2, message.map_string_string().size());
+ EXPECT_EQ(2, message.map_int32_bytes().size());
EXPECT_EQ(2, message.map_int32_enum().size());
EXPECT_EQ(2, message.map_int32_foreign_message().size());
+ EXPECT_EQ(2, message.map_int32_foreign_message_no_arena().size());
EXPECT_EQ(0, message.map_int32_int32().at(0));
EXPECT_EQ(0, message.map_int64_int64().at(0));
@@ -345,8 +355,11 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) {
EXPECT_EQ(0, message.map_int32_float().at(0));
EXPECT_EQ(0, message.map_int32_double().at(0));
EXPECT_EQ(false, message.map_bool_bool().at(0));
+ EXPECT_EQ("0", message.map_string_string().at("0"));
+ EXPECT_EQ("0", message.map_int32_bytes().at(0));
EXPECT_EQ(enum_value0, message.map_int32_enum().at(0));
EXPECT_EQ(0, message.map_int32_foreign_message().at(0).c());
+ EXPECT_EQ(0, message.map_int32_foreign_message_no_arena().at(0).c());
EXPECT_EQ(1, message.map_int32_int32().at(1));
EXPECT_EQ(1, message.map_int64_int64().at(1));
@@ -361,8 +374,11 @@ void MapTestUtilImpl::ExpectArenaMapFieldsSet(const MapMessage& message) {
EXPECT_EQ(1, message.map_int32_float().at(1));
EXPECT_EQ(1, message.map_int32_double().at(1));
EXPECT_EQ(true, message.map_bool_bool().at(1));
+ EXPECT_EQ("1", message.map_string_string().at("1"));
+ EXPECT_EQ("1", message.map_int32_bytes().at(1));
EXPECT_EQ(enum_value1, message.map_int32_enum().at(1));
EXPECT_EQ(1, message.map_int32_foreign_message().at(1).c());
+ EXPECT_EQ(1, message.map_int32_foreign_message_no_arena().at(1).c());
}
template <typename EnumType, EnumType enum_value, typename MapMessage>
diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h
index ffdb6dfb..5040e605 100644
--- a/src/google/protobuf/map_type_handler.h
+++ b/src/google/protobuf/map_type_handler.h
@@ -54,22 +54,6 @@ struct MapIf<false, TrueType, FalseType> {
typedef FalseType type;
};
-// In MapField, string and message are stored as pointer while others are stored
-// as object. However, google::protobuf::Map has unified api. Functions in this class
-// convert key/value to type wanted in api regardless how it's stored
-// internally.
-template <typename Type>
-class MapCommonTypeHandler {
- public:
- static inline Type& Reference(Type* x) { return *x; }
- static inline Type& Reference(Type& x) { return x; }
- static inline const Type& Reference(const Type& x) { return x; }
- static inline Type* Pointer(Type* x) { return x; }
- static inline Type* Pointer(Type& x) { return &x; }
- static inline const Type* Pointer(const Type* x) { return x; }
- static inline const Type* Pointer(const Type& x) { return &x; }
-};
-
// In proto2 Map, enum needs to be initialized to given default value, while
// other types' default value can be inferred from the type.
template <bool IsEnum, typename Type>
@@ -110,174 +94,29 @@ template <typename Type>
class MapArenaMessageCreator<Type, false> {
public:
static inline Type* CreateMessage(Arena* arena) {
- return new Type;
- }
-};
-
-// Handlers for key/value stored type in MapField. ==================
-
-// Handler for message
-template <typename Type>
-class MapCppTypeHandler : public MapCommonTypeHandler<Type> {
- public:
- static const bool kIsStringOrMessage = true;
- // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
- // those already calculate in sizeof(MapField).
- static int SpaceUsedInMapEntry(const Type* value) {
- return value->SpaceUsed();
- }
- // Return bytes used by value in Map.
- static int SpaceUsedInMap(const Type& value) { return value.SpaceUsed(); }
- static inline void Clear(Type** value) {
- if (*value != NULL) (*value)->Clear();
- }
- static inline void ClearMaybeByDefaultEnum(Type** value,
- int default_enum_value) {
- if (*value != NULL) (*value)->Clear();
- }
- static inline void Merge(const Type& from, Type** to) {
- (*to)->MergeFrom(from);
- }
-
- static void Delete(const Type* ptr) { delete ptr; }
-
- // Assign default value to given instance.
- static inline void AssignDefaultValue(Type** value) {
- *value = const_cast<Type*>(&Type::default_instance());
- }
- // Initialize value when constructing MapEntry
- static inline void Initialize(Type** x, Arena* arena) { *x = NULL; }
- // Same as above, but use default_enum_value to initialize enum type value.
- static inline void InitializeMaybeByDefaultEnum(
- Type** x, int default_enum_value, Arena* arena) {
- *x = NULL;
- }
- // Initialize value for the first time mutable accessor is called.
- static inline void EnsureMutable(Type** value, Arena* arena) {
- if (*value == NULL) {
- *value =
- MapArenaMessageCreator<Type, Arena::is_arena_constructable<Type>::
- type::value>::CreateMessage(arena);
- }
- }
- // Return default instance if value is not initialized when calling const
- // reference accessor.
- static inline const Type& DefaultIfNotInitialized(const Type* value,
- const Type* default_value) {
- return value != NULL ? *value : *default_value;
- }
- // Check if all required fields have values set.
- static inline bool IsInitialized(Type* value) {
- return value->IsInitialized();
- }
-};
-
-// Handler for string.
-template <>
-class MapCppTypeHandler<string> : public MapCommonTypeHandler<string> {
- public:
- static const bool kIsStringOrMessage = true;
- static inline void Merge(const string& from, string** to) { **to = from; }
- static inline void Clear(string** value) { (*value)->clear(); }
- static inline void ClearMaybeByDefaultEnum(string** value, int default_enum) {
- (*value)->clear();
- }
- static inline int SpaceUsedInMapEntry(const string* value) {
- return sizeof(*value) + StringSpaceUsedExcludingSelf(*value);
- }
- static inline int SpaceUsedInMap(const string& value) {
- return sizeof(value) + StringSpaceUsedExcludingSelf(value);
- }
- static void Delete(const string* ptr) {
- if (ptr != &::google::protobuf::internal::GetEmptyString()) delete ptr;
- }
- static inline void AssignDefaultValue(string** value) {}
- static inline void Initialize(string** value, Arena* arena) {
- *value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
- if (arena != NULL) arena->Own(*value);
- }
- static inline void InitializeMaybeByDefaultEnum(
- string** value, int default_enum_value, Arena* arena) {
- *value = const_cast< ::std::string*>(&::google::protobuf::internal::GetEmptyString());
- if (arena != NULL) arena->Own(*value);
+ return Arena::Create<Type>(arena);
}
- static inline void EnsureMutable(string** value, Arena* arena) {
- if (*value == &::google::protobuf::internal::GetEmptyString()) {
- *value = Arena::Create<string>(arena);
- }
- }
- static inline const string& DefaultIfNotInitialized(
- const string* value,
- const string* default_value) {
- return value != default_value ? *value : *default_value;
- }
- static inline bool IsInitialized(string* value) { return true; }
};
-// Base class for primitive type handlers.
-template <typename Type>
-class MapPrimitiveTypeHandler : public MapCommonTypeHandler<Type> {
- public:
- static const bool kIsStringOrMessage = false;
- static inline void Delete(const Type& x) {}
- static inline void Merge(const Type& from, Type* to) { *to = from; }
- static inline int SpaceUsedInMapEntry(const Type& value) { return 0; }
- static inline int SpaceUsedInMap(const Type& value) { return sizeof(Type); }
- static inline void AssignDefaultValue(Type* value) {}
- static inline const Type& DefaultIfNotInitialized(
- const Type& value, const Type& default_value) {
- return value;
- }
- static inline bool IsInitialized(const Type& value) { return true; }
-};
-
-// Handlers for primitive types.
-#define PRIMITIVE_HANDLER(CType) \
- template <> \
- class MapCppTypeHandler<CType> : public MapPrimitiveTypeHandler<CType> { \
- public: \
- static inline void Clear(CType* value) { *value = 0; } \
- static inline void ClearMaybeByDefaultEnum(CType* value, \
- int default_enum_value) { \
- *value = static_cast<CType>(default_enum_value); \
- } \
- static inline void Initialize(CType* value, Arena* arena) { *value = 0; } \
- static inline void InitializeMaybeByDefaultEnum(CType* value, \
- int default_enum_value, \
- Arena* arena) { \
- *value = static_cast<CType>(default_enum_value); \
- } \
- static inline void EnsureMutable(CType* value, Arena* arena) {} \
- };
-
-PRIMITIVE_HANDLER(int32 )
-PRIMITIVE_HANDLER(int64 )
-PRIMITIVE_HANDLER(uint32)
-PRIMITIVE_HANDLER(uint64)
-PRIMITIVE_HANDLER(double)
-PRIMITIVE_HANDLER(float )
-PRIMITIVE_HANDLER(bool )
-
-#undef PRIMITIVE_HANDLER
-
// Define constants for given wire field type
-template <WireFormatLite::FieldType field_type>
+template <WireFormatLite::FieldType field_type, typename Type>
class MapWireFieldTypeTraits {};
-#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \
- template <> \
- class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType> { \
- public: \
- typedef CType CppType; \
- static const bool kIsMessage = IsMessage; \
- static const bool kIsEnum = IsEnum; \
- static const WireFormatLite::WireType kWireType = \
- WireFormatLite::WIRETYPE_##WireFormatType; \
+#define TYPE_TRAITS(FieldType, CType, WireFormatType, IsMessage, IsEnum) \
+ template <typename Type> \
+ class MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, Type> { \
+ public: \
+ static const bool kIsMessage = IsMessage; \
+ static const bool kIsEnum = IsEnum; \
+ typedef typename MapIf<kIsMessage, Type*, CType>::type TypeOnMemory; \
+ typedef typename MapIf<kIsEnum, int, Type>::type MapEntryAccessorType; \
+ static const WireFormatLite::WireType kWireType = \
+ WireFormatLite::WIRETYPE_##WireFormatType; \
};
-TYPE_TRAITS(MESSAGE , MessageLite, LENGTH_DELIMITED, true, false)
-TYPE_TRAITS(STRING , string , LENGTH_DELIMITED, false, false)
-TYPE_TRAITS(BYTES , string , LENGTH_DELIMITED, false, false)
+TYPE_TRAITS(MESSAGE , Type, LENGTH_DELIMITED, true, false)
+TYPE_TRAITS(STRING , ArenaStringPtr, LENGTH_DELIMITED, false, false)
+TYPE_TRAITS(BYTES , ArenaStringPtr , LENGTH_DELIMITED, false, false)
TYPE_TRAITS(INT64 , int64 , VARINT , false, false)
TYPE_TRAITS(UINT64 , uint64 , VARINT , false, false)
TYPE_TRAITS(INT32 , int32 , VARINT , false, false)
@@ -295,46 +134,149 @@ TYPE_TRAITS(BOOL , bool , VARINT , false, false)
#undef TYPE_TRAITS
-template <WireFormatLite::FieldType field_type>
-class MapWireFieldTypeHandler {
+template <WireFormatLite::FieldType field_type, typename Type>
+class MapTypeHandler {};
+
+template <typename Type>
+class MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type> {
public:
+ // Enum type cannot be used for MapTypeHandler::Read. Define a type which will
+ // replace Enum with int.
+ typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE,
+ Type>::MapEntryAccessorType MapEntryAccessorType;
// Internal stored type in MapEntryLite for given wire field type.
- typedef typename MapWireFieldTypeTraits<field_type>::CppType CppType;
+ typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE,
+ Type>::TypeOnMemory TypeOnMemory;
// Corresponding wire type for field type.
static const WireFormatLite::WireType kWireType =
- MapWireFieldTypeTraits<field_type>::kWireType;
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kWireType;
// Whether wire type is for message.
- static const bool kIsMessage = MapWireFieldTypeTraits<field_type>::kIsMessage;
+ static const bool kIsMessage =
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsMessage;
// Whether wire type is for enum.
- static const bool kIsEnum = MapWireFieldTypeTraits<field_type>::kIsEnum;
+ static const bool kIsEnum =
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_MESSAGE, Type>::kIsEnum;
// Functions used in parsing and serialization. ===================
- template <typename ValueType>
- static inline int ByteSize(const ValueType& value);
- template <typename ValueType>
- static inline int GetCachedSize(const ValueType& value);
- template <typename ValueType>
- static inline bool Read(io::CodedInputStream* input, ValueType* value);
- static inline void Write(int field, const CppType& value,
+ static inline int ByteSize(const MapEntryAccessorType& value);
+ static inline int GetCachedSize(const MapEntryAccessorType& value);
+ static inline bool Read(io::CodedInputStream* input,
+ MapEntryAccessorType* value);
+ static inline void Write(int field, const MapEntryAccessorType& value,
io::CodedOutputStream* output);
- static inline uint8* WriteToArray(int field, const CppType& value,
+ static inline uint8* WriteToArray(int field,
+ const MapEntryAccessorType& value,
uint8* output);
+
+ // Functions to manipulate data on memory. ========================
+ static inline const Type& GetExternalReference(const Type* value);
+ static inline void DeleteNoArena(const Type* x);
+ static inline void Merge(const Type& from, Type** to, Arena* arena);
+ static inline void Clear(Type** value, Arena* arena);
+ static inline void ClearMaybeByDefaultEnum(Type** value, Arena* arena,
+ int default_enum_value);
+ static inline void Initialize(Type** x, Arena* arena);
+
+ static inline void InitializeMaybeByDefaultEnum(Type** x,
+ int default_enum_value,
+ Arena* arena);
+ static inline Type* EnsureMutable(Type** value, Arena* arena);
+ // SpaceUsedInMapEntry: Return bytes used by value in MapEntry, excluding
+ // those already calculate in sizeof(MapField).
+ static inline int SpaceUsedInMapEntry(const Type* value);
+ // Return bytes used by value in Map.
+ static inline int SpaceUsedInMap(const Type& value);
+ // Assign default value to given instance.
+ static inline void AssignDefaultValue(Type** value);
+ // Return default instance if value is not initialized when calling const
+ // reference accessor.
+ static inline const Type& DefaultIfNotInitialized(
+ const Type* value, const Type* default_value);
+ // Check if all required fields have values set.
+ static inline bool IsInitialized(Type* value);
};
-template <>
-template <typename ValueType>
-inline int MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::ByteSize(
- const ValueType& value) {
+#define MAP_HANDLER(FieldType) \
+ template <typename Type> \
+ class MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type> { \
+ public: \
+ typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType \
+ MapEntryAccessorType; \
+ typedef typename MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
+ Type>::TypeOnMemory TypeOnMemory; \
+ static const WireFormatLite::WireType kWireType = \
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
+ Type>::kWireType; \
+ static const bool kIsMessage = \
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
+ Type>::kIsMessage; \
+ static const bool kIsEnum = \
+ MapWireFieldTypeTraits<WireFormatLite::TYPE_##FieldType, \
+ Type>::kIsEnum; \
+ static inline int ByteSize(const MapEntryAccessorType& value); \
+ static inline int GetCachedSize(const MapEntryAccessorType& value); \
+ static inline bool Read(io::CodedInputStream* input, \
+ MapEntryAccessorType* value); \
+ static inline void Write(int field, const MapEntryAccessorType& value, \
+ io::CodedOutputStream* output); \
+ static inline uint8* WriteToArray(int field, \
+ const MapEntryAccessorType& value, \
+ uint8* output); \
+ static inline const MapEntryAccessorType& GetExternalReference( \
+ const TypeOnMemory& value); \
+ static inline void DeleteNoArena(const TypeOnMemory& x); \
+ static inline void Merge(const MapEntryAccessorType& from, \
+ TypeOnMemory* to, Arena* arena); \
+ static inline void Clear(TypeOnMemory* value, Arena* arena); \
+ static inline void ClearMaybeByDefaultEnum(TypeOnMemory* value, \
+ Arena* arena, \
+ int default_enum); \
+ static inline int SpaceUsedInMapEntry(const TypeOnMemory& value); \
+ static inline int SpaceUsedInMap(const TypeOnMemory& value); \
+ static inline int SpaceUsedInMap(const string& value); \
+ static inline void AssignDefaultValue(TypeOnMemory* value); \
+ static inline const MapEntryAccessorType& DefaultIfNotInitialized( \
+ const TypeOnMemory& value, const TypeOnMemory& default_value); \
+ static inline bool IsInitialized(const TypeOnMemory& value); \
+ static void DeleteNoArena(TypeOnMemory& value); \
+ static inline void Initialize(TypeOnMemory* value, Arena* arena); \
+ static inline void InitializeMaybeByDefaultEnum(TypeOnMemory* value, \
+ int default_enum_value, \
+ Arena* arena); \
+ static inline MapEntryAccessorType* EnsureMutable(TypeOnMemory* value, \
+ Arena* arena); \
+ };
+MAP_HANDLER(STRING)
+MAP_HANDLER(BYTES)
+MAP_HANDLER(INT64)
+MAP_HANDLER(UINT64)
+MAP_HANDLER(INT32)
+MAP_HANDLER(UINT32)
+MAP_HANDLER(SINT64)
+MAP_HANDLER(SINT32)
+MAP_HANDLER(ENUM)
+MAP_HANDLER(DOUBLE)
+MAP_HANDLER(FLOAT)
+MAP_HANDLER(FIXED64)
+MAP_HANDLER(FIXED32)
+MAP_HANDLER(SFIXED64)
+MAP_HANDLER(SFIXED32)
+MAP_HANDLER(BOOL)
+#undef MAP_HANDLER
+
+template <typename Type>
+inline int
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::ByteSize(
+ const MapEntryAccessorType& value) {
return WireFormatLite::MessageSizeNoVirtual(value);
}
-#define BYTE_SIZE(FieldType, DeclaredType) \
- template <> \
- template <typename ValueType> \
- inline int \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::ByteSize( \
- const ValueType& value) { \
- return WireFormatLite::DeclaredType##Size(value); \
+#define BYTE_SIZE(FieldType, DeclaredType) \
+ template <typename Type> \
+ inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
+ const MapEntryAccessorType& value) { \
+ return WireFormatLite::DeclaredType##Size(value); \
}
BYTE_SIZE(STRING, String)
@@ -349,13 +291,11 @@ BYTE_SIZE(ENUM , Enum)
#undef BYTE_SIZE
-#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \
- template <> \
- template <typename ValueType> \
- inline int \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::ByteSize( \
- const ValueType& value) { \
- return WireFormatLite::k##DeclaredType##Size; \
+#define FIXED_BYTE_SIZE(FieldType, DeclaredType) \
+ template <typename Type> \
+ inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::ByteSize( \
+ const MapEntryAccessorType& value) { \
+ return WireFormatLite::k##DeclaredType##Size; \
}
FIXED_BYTE_SIZE(DOUBLE , Double)
@@ -368,20 +308,19 @@ FIXED_BYTE_SIZE(BOOL , Bool)
#undef FIXED_BYTE_SIZE
-template <>
-template <typename ValueType>
-inline int MapWireFieldTypeHandler<
- WireFormatLite::TYPE_MESSAGE>::GetCachedSize(const ValueType& value) {
+template <typename Type>
+inline int
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::GetCachedSize(
+ const MapEntryAccessorType& value) {
return WireFormatLite::LengthDelimitedSize(value.GetCachedSize());
}
-#define GET_CACHED_SIZE(FieldType, DeclaredType) \
- template <> \
- template <typename ValueType> \
- inline int \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::GetCachedSize( \
- const ValueType& value) { \
- return WireFormatLite::DeclaredType##Size(value); \
+#define GET_CACHED_SIZE(FieldType, DeclaredType) \
+ template <typename Type> \
+ inline int \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \
+ const MapEntryAccessorType& value) { \
+ return WireFormatLite::DeclaredType##Size(value); \
}
GET_CACHED_SIZE(STRING, String)
@@ -396,13 +335,12 @@ GET_CACHED_SIZE(ENUM , Enum)
#undef GET_CACHED_SIZE
-#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \
- template <> \
- template <typename ValueType> \
- inline int \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::GetCachedSize( \
- const ValueType& value) { \
- return WireFormatLite::k##DeclaredType##Size; \
+#define GET_FIXED_CACHED_SIZE(FieldType, DeclaredType) \
+ template <typename Type> \
+ inline int \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::GetCachedSize( \
+ const MapEntryAccessorType& value) { \
+ return WireFormatLite::k##DeclaredType##Size; \
}
GET_FIXED_CACHED_SIZE(DOUBLE , Double)
@@ -415,30 +353,31 @@ GET_FIXED_CACHED_SIZE(BOOL , Bool)
#undef GET_FIXED_CACHED_SIZE
-template <>
-inline void MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::Write(
- int field, const MessageLite& value, io::CodedOutputStream* output) {
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Write(
+ int field, const MapEntryAccessorType& value,
+ io::CodedOutputStream* output) {
WireFormatLite::WriteMessageMaybeToArray(field, value, output);
}
-template <>
+template <typename Type>
inline uint8*
-MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::WriteToArray(
- int field, const MessageLite& value, uint8* output) {
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::WriteToArray(
+ int field, const MapEntryAccessorType& value, uint8* output) {
return WireFormatLite::WriteMessageToArray(field, value, output);
}
#define WRITE_METHOD(FieldType, DeclaredType) \
- template <> \
- inline void \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::Write( \
- int field, const CppType& value, io::CodedOutputStream* output) { \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Write( \
+ int field, const MapEntryAccessorType& value, \
+ io::CodedOutputStream* output) { \
return WireFormatLite::Write##DeclaredType(field, value, output); \
} \
- template <> \
+ template <typename Type> \
inline uint8* \
- MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::WriteToArray( \
- int field, const CppType& value, uint8* output) { \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::WriteToArray( \
+ int field, const MapEntryAccessorType& value, uint8* output) { \
return WireFormatLite::Write##DeclaredType##ToArray(field, value, output); \
}
@@ -461,35 +400,31 @@ WRITE_METHOD(BOOL , Bool)
#undef WRITE_METHOD
-template <>
-template <typename ValueType>
-inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_MESSAGE>::Read(
- io::CodedInputStream* input, ValueType* value) {
+template <typename Type>
+inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Read(
+ io::CodedInputStream* input, MapEntryAccessorType* value) {
return WireFormatLite::ReadMessageNoVirtual(input, value);
}
-template <>
-template <typename ValueType>
-inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_STRING>::Read(
- io::CodedInputStream* input, ValueType* value) {
+template <typename Type>
+inline bool MapTypeHandler<WireFormatLite::TYPE_STRING, Type>::Read(
+ io::CodedInputStream* input, MapEntryAccessorType* value) {
return WireFormatLite::ReadString(input, value);
}
-template <>
-template <typename ValueType>
-inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_BYTES>::Read(
- io::CodedInputStream* input, ValueType* value) {
+template <typename Type>
+inline bool MapTypeHandler<WireFormatLite::TYPE_BYTES, Type>::Read(
+ io::CodedInputStream* input, MapEntryAccessorType* value) {
return WireFormatLite::ReadBytes(input, value);
}
-#define READ_METHOD(FieldType) \
- template <> \
- template <typename ValueType> \
- inline bool MapWireFieldTypeHandler<WireFormatLite::TYPE_##FieldType>::Read( \
- io::CodedInputStream* input, ValueType* value) { \
- return WireFormatLite::ReadPrimitive<CppType, \
- WireFormatLite::TYPE_##FieldType>( \
- input, value); \
+#define READ_METHOD(FieldType) \
+ template <typename Type> \
+ inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Read( \
+ io::CodedInputStream* input, MapEntryAccessorType* value) { \
+ return WireFormatLite::ReadPrimitive<TypeOnMemory, \
+ WireFormatLite::TYPE_##FieldType>( \
+ input, value); \
}
READ_METHOD(INT64)
@@ -509,6 +444,282 @@ READ_METHOD(BOOL)
#undef READ_METHOD
+// Definition for message handler
+
+template <typename Type>
+inline const Type&
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::GetExternalReference(const Type* value) {
+ return *value;
+}
+
+template <typename Type>
+inline int
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::SpaceUsedInMapEntry(const Type* value) {
+ return value->SpaceUsed();
+}
+
+template <typename Type>
+int MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::SpaceUsedInMap(
+ const Type& value) {
+ return value.SpaceUsed();
+}
+
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Clear(
+ Type** value, Arena* arena) {
+ if (*value != NULL) (*value)->Clear();
+}
+template <typename Type>
+inline void
+MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::ClearMaybeByDefaultEnum(Type** value,
+ Arena* arena,
+ int default_enum_value) {
+ if (*value != NULL) (*value)->Clear();
+}
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::Merge(
+ const Type& from, Type** to, Arena* arena) {
+ (*to)->MergeFrom(from);
+}
+
+template <typename Type>
+void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::DeleteNoArena(
+ const Type* ptr) {
+ delete ptr;
+}
+
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::AssignDefaultValue(Type** value) {
+ *value = const_cast<Type*>(&Type::default_instance());
+}
+
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::Initialize(Type** x,
+ Arena* arena) {
+ *x = NULL;
+}
+
+template <typename Type>
+inline void MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::
+ InitializeMaybeByDefaultEnum(Type** x, int default_enum_value,
+ Arena* arena) {
+ *x = NULL;
+}
+
+template <typename Type>
+inline Type* MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::EnsureMutable(Type** value,
+ Arena* arena) {
+ if (*value == NULL) {
+ *value =
+ MapArenaMessageCreator<Type, Arena::is_arena_constructable<Type>::
+ type::value>::CreateMessage(arena);
+ }
+ return *value;
+}
+
+template <typename Type>
+inline const Type& MapTypeHandler<WireFormatLite::TYPE_MESSAGE, Type>::
+ DefaultIfNotInitialized(const Type* value, const Type* default_value) {
+ return value != NULL ? *value : *default_value;
+}
+
+template <typename Type>
+inline bool MapTypeHandler<WireFormatLite::TYPE_MESSAGE,
+ Type>::IsInitialized(Type* value) {
+ return value->IsInitialized();
+}
+
+// Definition for string/bytes handler
+
+#define STRING_OR_BYTES_HANDLER_FUNCTIONS(FieldType) \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::GetExternalReference(const TypeOnMemory& value) { \
+ return value.Get(&::google::protobuf::internal::GetEmptyString()); \
+ } \
+ template <typename Type> \
+ inline int \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \
+ const TypeOnMemory& value) { \
+ return sizeof(value); \
+ } \
+ template <typename Type> \
+ inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::SpaceUsedInMap(const TypeOnMemory& value) { \
+ return sizeof(value); \
+ } \
+ template <typename Type> \
+ inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::SpaceUsedInMap(const string& value) { \
+ return sizeof(value); \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
+ TypeOnMemory* value, Arena* arena) { \
+ value->ClearToEmpty(&::google::protobuf::internal::GetEmptyString(), arena); \
+ } \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::ClearMaybeByDefaultEnum(TypeOnMemory* value, \
+ Arena* arena, \
+ int default_enum) { \
+ Clear(value, arena); \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
+ const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \
+ to->Set(&::google::protobuf::internal::GetEmptyString(), from, arena); \
+ } \
+ template <typename Type> \
+ void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::DeleteNoArena( \
+ TypeOnMemory& value) { \
+ value.DestroyNoArena(&::google::protobuf::internal::GetEmptyString()); \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::AssignDefaultValue(TypeOnMemory* value) {} \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
+ TypeOnMemory* value, Arena* arena) { \
+ value->UnsafeSetDefault(&::google::protobuf::internal::GetEmptyString()); \
+ } \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \
+ int default_enum_value, \
+ Arena* arena) { \
+ Initialize(value, arena); \
+ } \
+ template <typename Type> \
+ inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType* \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
+ TypeOnMemory* value, Arena* arena) { \
+ return value->Mutable(&::google::protobuf::internal::GetEmptyString(), arena); \
+ } \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DefaultIfNotInitialized(const TypeOnMemory& value, \
+ const TypeOnMemory& \
+ default_value) { \
+ return value.Get(&::google::protobuf::internal::GetEmptyString()); \
+ } \
+ template <typename Type> \
+ inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::IsInitialized(const TypeOnMemory& value) { \
+ return true; \
+ }
+STRING_OR_BYTES_HANDLER_FUNCTIONS(STRING)
+STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES)
+#undef STRING_OR_BYTES_HANDLER_FUNCTIONS
+
+#define PRIMITIVE_HANDLER_FUNCTIONS(FieldType) \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::GetExternalReference(const TypeOnMemory& value) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline int \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::SpaceUsedInMapEntry( \
+ const TypeOnMemory& value) { \
+ return 0; \
+ } \
+ template <typename Type> \
+ inline int MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::SpaceUsedInMap(const TypeOnMemory& value) { \
+ return sizeof(Type); \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Clear( \
+ TypeOnMemory* value, Arena* arena) { \
+ *value = 0; \
+ } \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::ClearMaybeByDefaultEnum(TypeOnMemory* value, \
+ Arena* arena, \
+ int default_enum_value) { \
+ *value = static_cast<TypeOnMemory>(default_enum_value); \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Merge( \
+ const MapEntryAccessorType& from, TypeOnMemory* to, Arena* arena) { \
+ *to = from; \
+ } \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DeleteNoArena(TypeOnMemory& x) {} \
+ template <typename Type> \
+ inline void MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::AssignDefaultValue(TypeOnMemory* value) {} \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::Initialize( \
+ TypeOnMemory* value, Arena* arena) { \
+ *value = 0; \
+ } \
+ template <typename Type> \
+ inline void \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \
+ int default_enum_value, \
+ Arena* arena) { \
+ *value = static_cast<TypeOnMemory>(default_enum_value); \
+ } \
+ template <typename Type> \
+ inline typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType* \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, Type>::EnsureMutable( \
+ TypeOnMemory* value, Arena* arena) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline const typename MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::MapEntryAccessorType& \
+ MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::DefaultIfNotInitialized(const TypeOnMemory& value, \
+ const TypeOnMemory& \
+ default_value) { \
+ return value; \
+ } \
+ template <typename Type> \
+ inline bool MapTypeHandler<WireFormatLite::TYPE_##FieldType, \
+ Type>::IsInitialized(const TypeOnMemory& value) { \
+ return true; \
+ }
+PRIMITIVE_HANDLER_FUNCTIONS(INT64)
+PRIMITIVE_HANDLER_FUNCTIONS(UINT64)
+PRIMITIVE_HANDLER_FUNCTIONS(INT32)
+PRIMITIVE_HANDLER_FUNCTIONS(UINT32)
+PRIMITIVE_HANDLER_FUNCTIONS(SINT64)
+PRIMITIVE_HANDLER_FUNCTIONS(SINT32)
+PRIMITIVE_HANDLER_FUNCTIONS(ENUM)
+PRIMITIVE_HANDLER_FUNCTIONS(DOUBLE)
+PRIMITIVE_HANDLER_FUNCTIONS(FLOAT)
+PRIMITIVE_HANDLER_FUNCTIONS(FIXED64)
+PRIMITIVE_HANDLER_FUNCTIONS(FIXED32)
+PRIMITIVE_HANDLER_FUNCTIONS(SFIXED64)
+PRIMITIVE_HANDLER_FUNCTIONS(SFIXED32)
+PRIMITIVE_HANDLER_FUNCTIONS(BOOL)
+#undef PRIMITIVE_HANDLER_FUNCTIONS
+
} // namespace internal
} // namespace protobuf
diff --git a/src/google/protobuf/map_unittest.proto b/src/google/protobuf/map_unittest.proto
index b308c7ff..aea1e8ce 100644
--- a/src/google/protobuf/map_unittest.proto
+++ b/src/google/protobuf/map_unittest.proto
@@ -33,6 +33,7 @@ syntax = "proto3";
option cc_enable_arenas = true;
import "google/protobuf/unittest.proto";
+import "google/protobuf/unittest_no_arena.proto";
// We don't put this in a package within proto2 because we need to make sure
// that the generated code doesn't depend on being in the proto2 namespace.
@@ -58,6 +59,7 @@ message TestMap {
map<int32 , bytes > map_int32_bytes = 15;
map<int32 , MapEnum > map_int32_enum = 16;
map<int32 , ForeignMessage> map_int32_foreign_message = 17;
+ map<string , ForeignMessage> map_string_foreign_message = 18;
}
message TestMapSubmessage {
@@ -100,8 +102,12 @@ message TestArenaMap {
map<int32 , float > map_int32_float = 11;
map<int32 , double > map_int32_double = 12;
map<bool , bool > map_bool_bool = 13;
- map<int32 , MapEnum > map_int32_enum = 14;
- map<int32 , ForeignMessage> map_int32_foreign_message = 15;
+ map<string , string > map_string_string = 14;
+ map<int32 , bytes > map_int32_bytes = 15;
+ map<int32 , MapEnum > map_int32_enum = 16;
+ map<int32 , ForeignMessage> map_int32_foreign_message = 17;
+ map<int32, .protobuf_unittest_no_arena.ForeignMessage>
+ map_int32_foreign_message_no_arena = 18;
}
// Previously, message containing enum called Type cannot be used as value of
@@ -110,10 +116,14 @@ message MessageContainingEnumCalledType {
enum Type {
TYPE_FOO = 0;
}
- map<int32, MessageContainingEnumCalledType> type = 1;
+ map<string, MessageContainingEnumCalledType> type = 1;
}
// Previously, message cannot contain map field called "entry".
message MessageContainingMapCalledEntry {
map<int32, int32> entry = 1;
}
+
+message TestRecursiveMapMessage {
+ map<string, TestRecursiveMapMessage> a = 1;
+}
diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc
index 123bd789..2f6416d0 100644
--- a/src/google/protobuf/message.cc
+++ b/src/google/protobuf/message.cc
@@ -38,12 +38,15 @@
#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/reflection_internal.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/map_field.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/reflection_ops.h>
@@ -257,6 +260,22 @@ void Reflection::AddEnumValue(Message* message,
GOOGLE_LOG(FATAL) << "Unimplemented EnumValue API.";
}
+MapIterator Reflection::MapBegin(
+ Message* message,
+ const FieldDescriptor* field) const {
+ GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
+ MapIterator iter(message, field);
+ return iter;
+}
+
+MapIterator Reflection::MapEnd(
+ Message* message,
+ const FieldDescriptor* field) const {
+ GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
+ MapIterator iter(message, field);
+ return iter;
+}
+
// =============================================================================
// MessageFactory
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index 18c092d0..348e7c7f 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -134,12 +134,23 @@ class Reflection;
class MessageFactory;
// Defined in other files.
+class MapKey;
+class MapValueRef;
+class MapIterator;
+class MapReflectionTester;
+
+namespace internal {
+class MapFieldBase;
+}
class UnknownFieldSet; // unknown_field_set.h
namespace io {
- class ZeroCopyInputStream; // zero_copy_stream.h
- class ZeroCopyOutputStream; // zero_copy_stream.h
- class CodedInputStream; // coded_stream.h
- class CodedOutputStream; // coded_stream.h
+class ZeroCopyInputStream; // zero_copy_stream.h
+class ZeroCopyOutputStream; // zero_copy_stream.h
+class CodedInputStream; // coded_stream.h
+class CodedOutputStream; // coded_stream.h
+}
+namespace python {
+class MapReflectionFriend; // scalar_map_container.h
}
@@ -724,6 +735,14 @@ class LIBPROTOBUF_EXPORT Reflection {
const FieldDescriptor* field,
MessageFactory* factory = NULL) const = 0;
+ // Appends an already-allocated object 'new_entry' to the repeated field
+ // specifyed by 'field' passing ownership to the message.
+ // TODO(tmarek): Make virtual after all subclasses have been
+ // updated.
+ virtual void AddAllocatedMessage(Message* message,
+ const FieldDescriptor* field,
+ Message* new_entry) const {}
+
// Get a RepeatedFieldRef object that can be used to read the underlying
// repeated field. The type parameter T must be set according to the
@@ -868,11 +887,20 @@ class LIBPROTOBUF_EXPORT Reflection {
// on field->cpp_type(),
// on field->field_option().ctype() (if ctype >= 0)
// of field->message_type() (if message_type != NULL).
- // We use 1 routine rather than 4 (const vs mutable) x (scalar vs pointer).
+ // We use 2 routine rather than 4 (const vs mutable) x (scalar vs pointer).
virtual void* MutableRawRepeatedField(
Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
int ctype, const Descriptor* message_type) const = 0;
+ // TODO(jieluo) - make it pure virtual after updating all the subclasses.
+ virtual const void* GetRawRepeatedField(
+ const Message& message, const FieldDescriptor* field,
+ FieldDescriptor::CppType cpptype, int ctype,
+ const Descriptor* message_type) const {
+ return MutableRawRepeatedField(
+ const_cast<Message*>(&message), field, cpptype, ctype, message_type);
+ }
+
// The following methods are used to implement (Mutable)RepeatedFieldRef.
// A Ref object will store a raw pointer to the repeated field data (obtained
// from RepeatedFieldData()) and a pointer to a Accessor (obtained from
@@ -887,6 +915,8 @@ class LIBPROTOBUF_EXPORT Reflection {
// "message_type" should be set to its descriptor. Otherwise "message_type"
// should be set to NULL. Implementations of this method should check whether
// "cpp_type"/"message_type" is consistent with the actual type of the field.
+ // We use 1 routine rather than 2 (const vs mutable) because it is protected
+ // and it doesn't change the message.
virtual void* RepeatedFieldData(
Message* message, const FieldDescriptor* field,
FieldDescriptor::CppType cpp_type,
@@ -902,14 +932,73 @@ class LIBPROTOBUF_EXPORT Reflection {
friend class RepeatedFieldRef;
template<typename T, typename Enable>
friend class MutableRepeatedFieldRef;
+ friend class ::google::protobuf::python::MapReflectionFriend;
// Special version for specialized implementations of string. We can't call
// MutableRawRepeatedField directly here because we don't have access to
// FieldOptions::* which are defined in descriptor.pb.h. Including that
// file here is not possible because it would cause a circular include cycle.
+ // We use 1 routine rather than 2 (const vs mutable) because it is private
+ // and mutable a repeated string field doesn't change the message.
void* MutableRawRepeatedString(
Message* message, const FieldDescriptor* field, bool is_string) const;
+ friend class MapReflectionTester;
+ // TODO(jieluo) - make the map APIs pure virtual after updating
+ // all the subclasses.
+ // Returns true if key is in map. Returns false if key is not in map field.
+ virtual bool ContainsMapKey(const Message& message,
+ const FieldDescriptor* field,
+ const MapKey& key) const {
+ return false;
+ }
+
+ // If key is in map field: Saves the value pointer to val and returns
+ // false. If key in not in map field: Insert the key into map, saves
+ // value pointer to val and retuns true.
+ virtual bool InsertOrLookupMapValue(Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key,
+ MapValueRef* val) const {
+ return false;
+ }
+
+ // Delete and returns true if key is in the map field. Returns false
+ // otherwise.
+ virtual bool DeleteMapValue(Message* message,
+ const FieldDescriptor* field,
+ const MapKey& key) const {
+ return false;
+ }
+
+ // Returns a MaIterator referring to the first element in the map field.
+ // If the map field is empty, this function returns the same as
+ // reflection::MapEnd. Mutation to the field may invalidate the iterator.
+ virtual MapIterator MapBegin(
+ Message* message,
+ const FieldDescriptor* field) const;
+
+ // Returns a MapIterator referring to the theoretical element that would
+ // follow the last element in the map field. It does not point to any
+ // real element. Mutation to the field may invalidate the iterator.
+ virtual MapIterator MapEnd(
+ Message* message,
+ const FieldDescriptor* field) const;
+
+ // Get the number of <key, value> pair of a map field. The result may be
+ // different from FieldSize which can have duplicate keys.
+ virtual int MapSize(const Message& message,
+ const FieldDescriptor* field) const {
+ return 0;
+ }
+
+ // Help method for MapIterator.
+ friend class MapIterator;
+ virtual internal::MapFieldBase* MapData(
+ Message* message, const FieldDescriptor* field) const {
+ return NULL;
+ }
+
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
};
@@ -1025,10 +1114,9 @@ inline RepeatedPtrField<string>* Reflection::MutableRepeatedPtrField<string>(
template<>
inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
const Message& message, const FieldDescriptor* field) const {
- return *static_cast<RepeatedPtrField<Message>* >(
- MutableRawRepeatedField(const_cast<Message*>(&message), field,
- FieldDescriptor::CPPTYPE_MESSAGE, -1,
- NULL));
+ return *static_cast<const RepeatedPtrField<Message>* >(
+ GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE,
+ -1, NULL));
}
template<>
@@ -1043,10 +1131,9 @@ inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
template<typename PB>
inline const RepeatedPtrField<PB>& Reflection::GetRepeatedPtrField(
const Message& message, const FieldDescriptor* field) const {
- return *static_cast<RepeatedPtrField<PB>* >(
- MutableRawRepeatedField(const_cast<Message*>(&message), field,
- FieldDescriptor::CPPTYPE_MESSAGE, -1,
- PB::default_instance().GetDescriptor()));
+ return *static_cast<const RepeatedPtrField<PB>* >(
+ GetRawRepeatedField(message, field, FieldDescriptor::CPPTYPE_MESSAGE,
+ -1, PB::default_instance().GetDescriptor()));
}
template<typename PB>
diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc
index 4f63ad2b..5bd8bcfb 100644
--- a/src/google/protobuf/message_lite.cc
+++ b/src/google/protobuf/message_lite.cc
@@ -35,7 +35,9 @@
#include <google/protobuf/message_lite.h>
#include <google/protobuf/arena.h>
+#include <google/protobuf/repeated_field.h>
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
@@ -98,27 +100,19 @@ string InitializationErrorMessage(const char* action,
// call MergePartialFromCodedStream(). However, when parsing very small
// messages, every function call introduces significant overhead. To avoid
// this without reproducing code, we use these forced-inline helpers.
-//
-// Note: GCC only allows GOOGLE_ATTRIBUTE_ALWAYS_INLINE on declarations, not
-// definitions.
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InlineMergeFromCodedStream(
+ io::CodedInputStream* input, MessageLite* message);
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromCodedStream(
+ io::CodedInputStream* input, MessageLite* message);
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromCodedStream(
+ io::CodedInputStream* input, MessageLite* message);
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InlineParseFromArray(
+ const void* data, int size, MessageLite* message);
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool InlineParsePartialFromArray(
+ const void* data, int size, MessageLite* message);
+
inline bool InlineMergeFromCodedStream(io::CodedInputStream* input,
- MessageLite* message)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
- MessageLite* message)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
- MessageLite* message)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-inline bool InlineParseFromArray(const void* data, int size,
- MessageLite* message)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-inline bool InlineParsePartialFromArray(const void* data, int size,
- MessageLite* message)
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-
-bool InlineMergeFromCodedStream(io::CodedInputStream* input,
- MessageLite* message) {
+ MessageLite* message) {
if (!message->MergePartialFromCodedStream(input)) return false;
if (!message->IsInitialized()) {
GOOGLE_LOG(ERROR) << InitializationErrorMessage("parse", *message);
@@ -127,26 +121,27 @@ bool InlineMergeFromCodedStream(io::CodedInputStream* input,
return true;
}
-bool InlineParseFromCodedStream(io::CodedInputStream* input,
- MessageLite* message) {
+inline bool InlineParseFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message) {
message->Clear();
return InlineMergeFromCodedStream(input, message);
}
-bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
- MessageLite* message) {
+inline bool InlineParsePartialFromCodedStream(io::CodedInputStream* input,
+ MessageLite* message) {
message->Clear();
return message->MergePartialFromCodedStream(input);
}
-bool InlineParseFromArray(const void* data, int size, MessageLite* message) {
+inline bool InlineParseFromArray(
+ const void* data, int size, MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParseFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
}
-bool InlineParsePartialFromArray(const void* data, int size,
- MessageLite* message) {
+inline bool InlineParsePartialFromArray(
+ const void* data, int size, MessageLite* message) {
io::CodedInputStream input(reinterpret_cast<const uint8*>(data), size);
return InlineParsePartialFromCodedStream(&input, message) &&
input.ConsumedEntireMessage();
@@ -353,5 +348,18 @@ string MessageLite::SerializePartialAsString() const {
return output;
}
+namespace internal {
+template<>
+MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, google::protobuf::Arena* arena) {
+ return prototype->New(arena);
+}
+template <>
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to) {
+ to->CheckTypeAndMergeFrom(from);
+}
+} // namespace internal
+
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc
index 75d60b8b..2d4780fe 100644
--- a/src/google/protobuf/message_unittest.cc
+++ b/src/google/protobuf/message_unittest.cc
@@ -53,6 +53,7 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h
index c5bab0a8..fdee150b 100644
--- a/src/google/protobuf/metadata.h
+++ b/src/google/protobuf/metadata.h
@@ -69,8 +69,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
ptr_ = NULL;
}
- inline const UnknownFieldSet& unknown_fields() const
- GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE const UnknownFieldSet& unknown_fields() const {
if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
return PtrValue<Container>()->unknown_fields_;
} else {
@@ -78,7 +77,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
}
}
- inline UnknownFieldSet* mutable_unknown_fields() GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE UnknownFieldSet* mutable_unknown_fields() {
if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) {
return &PtrValue<Container>()->unknown_fields_;
} else {
@@ -86,7 +85,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
}
}
- inline Arena* arena() const GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const {
if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) {
return PtrValue<Container>()->arena_;
} else {
@@ -94,11 +93,11 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
}
}
- inline bool have_unknown_fields() const GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const {
return PtrTag() == kTagContainer;
}
- inline void Swap(InternalMetadataWithArena* other) GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(InternalMetadataWithArena* other) {
// Semantics here are that we swap only the unknown fields, not the arena
// pointer. We cannot simply swap ptr_ with other->ptr_ because we need to
// maintain our own arena ptr. Also, our ptr_ and other's ptr_ may be in
@@ -110,7 +109,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
}
}
- inline void* raw_arena_ptr() const GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const {
return ptr_;
}
@@ -128,7 +127,7 @@ class LIBPROTOBUF_EXPORT InternalMetadataWithArena {
static const intptr_t kPtrValueMask = ~kPtrTagMask;
// Accessors for pointer tag and pointer value.
- inline int PtrTag() const GOOGLE_ATTRIBUTE_ALWAYS_INLINE {
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const {
return reinterpret_cast<intptr_t>(ptr_) & kPtrTagMask;
}
diff --git a/src/google/protobuf/no_field_presence_test.cc b/src/google/protobuf/no_field_presence_test.cc
index 4b7b31d9..bc41beec 100644
--- a/src/google/protobuf/no_field_presence_test.cc
+++ b/src/google/protobuf/no_field_presence_test.cc
@@ -341,6 +341,46 @@ TEST(NoFieldPresenceTest, ReflectionHasFieldTest) {
EXPECT_EQ(false, r->HasField(message, field_string));
}
+TEST(NoFieldPresenceTest, ReflectionClearFieldTest) {
+ proto2_nofieldpresence_unittest::TestAllTypes message;
+
+ const google::protobuf::Reflection* r = message.GetReflection();
+ const google::protobuf::Descriptor* desc = message.GetDescriptor();
+
+ const google::protobuf::FieldDescriptor* field_int32 = desc->FindFieldByName(
+ "optional_int32");
+ const google::protobuf::FieldDescriptor* field_double = desc->FindFieldByName(
+ "optional_double");
+ const google::protobuf::FieldDescriptor* field_string = desc->FindFieldByName(
+ "optional_string");
+ const google::protobuf::FieldDescriptor* field_message = desc->FindFieldByName(
+ "optional_nested_message");
+ const google::protobuf::FieldDescriptor* field_lazy = desc->FindFieldByName(
+ "optional_lazy_message");
+
+ message.set_optional_int32(42);
+ r->ClearField(&message, field_int32);
+ EXPECT_EQ(0, message.optional_int32());
+
+ message.set_optional_double(42.0);
+ r->ClearField(&message, field_double);
+ EXPECT_EQ(0.0, message.optional_double());
+
+ message.set_optional_string("test");
+ r->ClearField(&message, field_string);
+ EXPECT_EQ("", message.optional_string());
+
+ message.mutable_optional_nested_message()->set_bb(1234);
+ r->ClearField(&message, field_message);
+ EXPECT_FALSE(message.has_optional_nested_message());
+ EXPECT_EQ(0, message.optional_nested_message().bb());
+
+ message.mutable_optional_lazy_message()->set_bb(42);
+ r->ClearField(&message, field_lazy);
+ EXPECT_FALSE(message.has_optional_lazy_message());
+ EXPECT_EQ(0, message.optional_lazy_message().bb());
+}
+
TEST(NoFieldPresenceTest, HasFieldOneofsTest) {
// check that HasField behaves properly for oneofs.
proto2_nofieldpresence_unittest::TestAllTypes message;
diff --git a/src/google/protobuf/proto3_arena_unittest.cc b/src/google/protobuf/proto3_arena_unittest.cc
index da4be673..2838e0fc 100644
--- a/src/google/protobuf/proto3_arena_unittest.cc
+++ b/src/google/protobuf/proto3_arena_unittest.cc
@@ -119,7 +119,7 @@ void ExpectAllFieldsSet(const TestAllTypes& m) {
// proto3 and expect the arena support to be fully tested in proto2 unittests
// because proto3 shares most code with proto2.
-TEST(ArenaTest, Parsing) {
+TEST(Proto3ArenaTest, Parsing) {
TestAllTypes original;
SetAllFields(&original);
@@ -129,7 +129,7 @@ TEST(ArenaTest, Parsing) {
ExpectAllFieldsSet(*arena_message);
}
-TEST(ArenaTest, UnknownFields) {
+TEST(Proto3ArenaTest, UnknownFields) {
TestAllTypes original;
SetAllFields(&original);
@@ -150,7 +150,7 @@ TEST(ArenaTest, UnknownFields) {
arena_message->GetReflection()->GetUnknownFields(*arena_message).empty());
}
-TEST(ArenaTest, Swap) {
+TEST(Proto3ArenaTest, Swap) {
Arena arena1;
Arena arena2;
@@ -162,7 +162,7 @@ TEST(ArenaTest, Swap) {
EXPECT_EQ(&arena2, arena2_message->GetArena());
}
-TEST(ArenaTest, SetAllocatedMessage) {
+TEST(Proto3ArenaTest, SetAllocatedMessage) {
Arena arena;
TestAllTypes *arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
@@ -171,7 +171,7 @@ TEST(ArenaTest, SetAllocatedMessage) {
EXPECT_EQ(118, arena_message->optional_nested_message().bb());
}
-TEST(ArenaTest, ReleaseMessage) {
+TEST(Proto3ArenaTest, ReleaseMessage) {
Arena arena;
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
arena_message->mutable_optional_nested_message()->set_bb(118);
@@ -180,7 +180,7 @@ TEST(ArenaTest, ReleaseMessage) {
EXPECT_EQ(118, nested->bb());
}
-TEST(ArenaTest, MessageFieldClear) {
+TEST(Proto3ArenaTest, MessageFieldClear) {
// GitHub issue #310: https://github.com/google/protobuf/issues/310
Arena arena;
TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
@@ -190,6 +190,20 @@ TEST(ArenaTest, MessageFieldClear) {
arena_message->Clear();
}
+TEST(Proto3ArenaTest, MessageFieldClearViaReflection) {
+ Arena arena;
+ TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
+ const Reflection* r = message->GetReflection();
+ const Descriptor* d = message->GetDescriptor();
+ const FieldDescriptor* msg_field = d->FindFieldByName(
+ "optional_nested_message");
+
+ message->mutable_optional_nested_message()->set_bb(1);
+ r->ClearField(message, msg_field);
+ EXPECT_FALSE(message->has_optional_nested_message());
+ EXPECT_EQ(0, message->optional_nested_message().bb());
+}
+
} // namespace
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/proto_cast.h b/src/google/protobuf/proto_cast.h
index e25c219f..dc0e9aca 100644
--- a/src/google/protobuf/proto_cast.h
+++ b/src/google/protobuf/proto_cast.h
@@ -33,6 +33,7 @@
#include <string>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
// proto_cast<> is used to simulate over-the-wire conversion of one
diff --git a/src/google/protobuf/proto_cast_test.cc b/src/google/protobuf/proto_cast_test.cc
index eb101eb6..a8f43ae4 100644
--- a/src/google/protobuf/proto_cast_test.cc
+++ b/src/google/protobuf/proto_cast_test.cc
@@ -32,7 +32,7 @@
#include <google/protobuf/util/unknown_enum_test.pb.h>
#include <gtest/gtest.h>
-#include <google/protobuf/testing/gmock.h>
+#include <gmock/gmock.h>
namespace google {
using google::protobuf::util::UpRevision;
diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h
index 4ff0f6b4..671aafdc 100755
--- a/src/google/protobuf/reflection.h
+++ b/src/google/protobuf/reflection.h
@@ -553,7 +553,7 @@ struct RefTypeTraits<
template<typename T>
struct RefTypeTraits<
- T, typename internal::enable_if<internal::is_same<string, T>::value>::type> {
+ T, typename internal::enable_if< ::google::protobuf::internal::is_same<string, T>::value>::type> {
typedef RepeatedFieldRefIterator<T> iterator;
typedef RepeatedFieldAccessor AccessorType;
typedef string AccessorValueType;
diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc
index 32740ea4..88d6bfb6 100644
--- a/src/google/protobuf/reflection_ops_unittest.cc
+++ b/src/google/protobuf/reflection_ops_unittest.cc
@@ -37,6 +37,7 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc
index e5aedadc..949e0a23 100644
--- a/src/google/protobuf/repeated_field.cc
+++ b/src/google/protobuf/repeated_field.cc
@@ -35,6 +35,7 @@
#include <algorithm>
#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
@@ -53,13 +54,17 @@ void** RepeatedPtrFieldBase::InternalExtend(int extend_amount) {
Arena* arena = GetArenaNoVirtual();
new_size = max(kMinRepeatedFieldAllocationSize,
max(total_size_ * 2, new_size));
+ GOOGLE_CHECK_LE(new_size,
+ (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
+ sizeof(old_rep->elements[0]))
+ << "Requested size is too large to fit into size_t.";
if (arena == NULL) {
rep_ = reinterpret_cast<Rep*>(
- new char[kRepHeaderSize + sizeof(old_rep->elements[0])*new_size]);
+ new char[kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size]);
} else {
rep_ = reinterpret_cast<Rep*>(
::google::protobuf::Arena::CreateArray<char>(arena,
- kRepHeaderSize + sizeof(old_rep->elements[0])*new_size));
+ kRepHeaderSize + sizeof(old_rep->elements[0]) * new_size));
}
total_size_ = new_size;
if (old_rep && old_rep->allocated_size > 0) {
diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h
index 2ba5dfd5..b10e7a95 100644
--- a/src/google/protobuf/repeated_field.h
+++ b/src/google/protobuf/repeated_field.h
@@ -54,6 +54,7 @@
#include <string>
#include <iterator>
#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/type_traits.h>
#include <google/protobuf/arena.h>
@@ -361,7 +362,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
// To parse directly into a proto2 generated class, the upb class GMR_Handlers
// needs to be able to modify a RepeatedPtrFieldBase directly.
- friend class LIBPROTOBUF_EXPORT upb::google_opensource::GMR_Handlers;
+ friend class upb::google_opensource::GMR_Handlers;
RepeatedPtrFieldBase();
explicit RepeatedPtrFieldBase(::google::protobuf::Arena* arena);
@@ -408,7 +409,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
const typename TypeHandler::Type* const* data() const;
template <typename TypeHandler>
- inline void Swap(RepeatedPtrFieldBase* other) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(RepeatedPtrFieldBase* other);
void SwapElements(int index1, int index2);
@@ -461,8 +462,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
void AddAllocatedSlowWithCopy(typename TypeHandler::Type* value,
Arena* value_arena,
- Arena* my_arena)
-;
+ Arena* my_arena);
template <typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
void AddAllocatedSlowWithoutCopy(typename TypeHandler::Type* value);
@@ -472,7 +472,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase {
typename TypeHandler::Type* ReleaseLastInternal(google::protobuf::internal::false_type);
template<typename TypeHandler> GOOGLE_ATTRIBUTE_NOINLINE
- inline void SwapFallback(RepeatedPtrFieldBase* other);
+ void SwapFallback(RepeatedPtrFieldBase* other);
inline Arena* GetArenaNoVirtual() const {
return arena_;
@@ -541,20 +541,10 @@ class GenericTypeHandler {
}
// We force NewFromPrototype() and Delete() to be non-inline to reduce code
// size: else, several other methods get inlined copies of message types'
- // constructors and destructors. Note that the GOOGLE_ATTRIBUTE_NOINLINE macro
- // requires the 'inline' storage class here, which is somewhat confusing, but
- // the compiler does the right thing.
- GOOGLE_ATTRIBUTE_NOINLINE
- static inline GenericType* NewFromPrototype(const GenericType* prototype,
- ::google::protobuf::Arena* arena = NULL) {
- return New(arena);
- }
- GOOGLE_ATTRIBUTE_NOINLINE
- static inline void Delete(GenericType* value, Arena* arena) {
- if (arena == NULL) {
- delete value;
- }
- }
+ // constructors and destructors.
+ GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype(
+ const GenericType* prototype, ::google::protobuf::Arena* arena = NULL);
+ GOOGLE_ATTRIBUTE_NOINLINE static void Delete(GenericType* value, Arena* arena);
static inline ::google::protobuf::Arena* GetArena(GenericType* value) {
return ::google::protobuf::Arena::GetArena<Type>(value);
}
@@ -563,11 +553,8 @@ class GenericTypeHandler {
}
static inline void Clear(GenericType* value) { value->Clear(); }
-
- GOOGLE_ATTRIBUTE_NOINLINE
- static inline void Merge(const GenericType& from, GenericType* to) {
- to->MergeFrom(from);
- }
+ GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from,
+ GenericType* to);
static inline int SpaceUsed(const GenericType& value) {
return value.SpaceUsed();
}
@@ -576,11 +563,31 @@ class GenericTypeHandler {
}
};
-template<>
-inline MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
- const MessageLite* prototype, google::protobuf::Arena* arena) {
- return prototype->New(arena);
+template <typename GenericType>
+GenericType* GenericTypeHandler<GenericType>::NewFromPrototype(
+ const GenericType* prototype, ::google::protobuf::Arena* arena) {
+ return New(arena);
}
+template <typename GenericType>
+void GenericTypeHandler<GenericType>::Delete(GenericType* value, Arena* arena) {
+ if (arena == NULL) {
+ delete value;
+ }
+}
+template <typename GenericType>
+void GenericTypeHandler<GenericType>::Merge(const GenericType& from,
+ GenericType* to) {
+ to->MergeFrom(from);
+}
+
+// NewFromPrototype() and Merge() cannot be defined here; if they're declared
+// inline the compiler will complain about not matching GOOGLE_ATTRIBUTE_NOINLINE
+// above, and if not, compilation will result in multiple definitions. These
+// are therefore declared as specializations here and defined in
+// message_lite.cc.
+template<>
+MessageLite* GenericTypeHandler<MessageLite>::NewFromPrototype(
+ const MessageLite* prototype, google::protobuf::Arena* arena);
template<>
inline google::protobuf::Arena* GenericTypeHandler<MessageLite>::GetArena(
MessageLite* value) {
@@ -591,14 +598,9 @@ inline void* GenericTypeHandler<MessageLite>::GetMaybeArenaPointer(
MessageLite* value) {
return value->GetMaybeArenaPointer();
}
-
-// Implements GenericTypeHandler specialization required by RepeatedPtrFields
-// to work with MessageLite type.
template <>
-inline void GenericTypeHandler<MessageLite>::Merge(
- const MessageLite& from, MessageLite* to) {
- to->CheckTypeAndMergeFrom(from);
-}
+void GenericTypeHandler<MessageLite>::Merge(const MessageLite& from,
+ MessageLite* to);
// Declarations of the specialization as we cannot define them here, as the
// header that defines ProtocolMessage depends on types defined in this header.
@@ -1222,13 +1224,17 @@ void RepeatedField<Element>::Reserve(int new_size) {
Arena* arena = GetArenaNoVirtual();
new_size = max(google::protobuf::internal::kMinRepeatedFieldAllocationSize,
max(total_size_ * 2, new_size));
+ GOOGLE_CHECK_LE(static_cast<size_t>(new_size),
+ (std::numeric_limits<size_t>::max() - kRepHeaderSize) /
+ sizeof(Element))
+ << "Requested size is too large to fit into size_t.";
if (arena == NULL) {
rep_ = reinterpret_cast<Rep*>(
- new char[kRepHeaderSize + sizeof(Element)*new_size]);
+ new char[kRepHeaderSize + sizeof(Element) * new_size]);
} else {
rep_ = reinterpret_cast<Rep*>(
::google::protobuf::Arena::CreateArray<char>(arena,
- kRepHeaderSize + sizeof(Element)*new_size));
+ kRepHeaderSize + sizeof(Element) * new_size));
}
rep_->arena = arena;
int old_total_size = total_size_;
@@ -1343,7 +1349,7 @@ inline void RepeatedPtrFieldBase::Swap(RepeatedPtrFieldBase* other) {
}
template <typename TypeHandler>
-inline void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
+void RepeatedPtrFieldBase::SwapFallback(RepeatedPtrFieldBase* other) {
GOOGLE_DCHECK(other->GetArenaNoVirtual() != GetArenaNoVirtual());
// Copy semantics in this case. We try to improve efficiency by placing the
diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc
index af397932..b45664b0 100644
--- a/src/google/protobuf/repeated_field_unittest.cc
+++ b/src/google/protobuf/repeated_field_unittest.cc
@@ -42,6 +42,7 @@
#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/stubs/strutil.h>
@@ -1429,7 +1430,6 @@ class RepeatedFieldInsertionIteratorsTest : public testing::Test {
std::copy(nested_ptrs.begin(), nested_ptrs.end(),
RepeatedFieldBackInserter(
protobuffer.mutable_repeated_nested_message()));
-
}
virtual void TearDown() {
diff --git a/src/google/protobuf/service.h b/src/google/protobuf/service.h
index cc0b45d4..ad6f9685 100644
--- a/src/google/protobuf/service.h
+++ b/src/google/protobuf/service.h
@@ -74,12 +74,12 @@
//
// To call a remote MyServiceImpl, first you need an RpcChannel connected to it.
// How to construct a channel depends, again, on your RPC implementation.
-// Here we use a hypothentical "MyRpcChannel" as an example:
+// Here we use a hypothetical "MyRpcChannel" as an example:
// MyRpcChannel channel("rpc:hostname:1234/myservice");
// MyRpcController controller;
// MyServiceImpl::Stub stub(&channel);
// FooRequest request;
-// FooRespnose response;
+// FooResponse response;
//
// // ... fill in request ...
//
@@ -102,6 +102,7 @@
#include <string>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/callback.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc
index 5c88363f..c8397639 100644
--- a/src/google/protobuf/source_context.pb.cc
+++ b/src/google/protobuf/source_context.pb.cc
@@ -81,9 +81,9 @@ void protobuf_AddDesc_google_2fprotobuf_2fsource_5fcontext_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n$google/protobuf/source_context.proto\022\017"
"google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
- "_name\030\001 \001(\tBR\n\023com.google.protobufB\022Sour"
- "ceContextProtoP\001\242\002\003GPB\252\002\036Google.Protobuf"
- ".WellKnownTypesb\006proto3", 183);
+ "_name\030\001 \001(\tBU\n\023com.google.protobufB\022Sour"
+ "ceContextProtoP\001\240\001\001\242\002\003GPB\252\002\036Google.Proto"
+ "buf.WellKnownTypesb\006proto3", 186);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/source_context.proto", &protobuf_RegisterTypes);
SourceContext::default_instance_ = new SourceContext();
@@ -194,10 +194,10 @@ bool SourceContext::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_file_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->file_name().data(), this->file_name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.SourceContext.file_name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.SourceContext.file_name"));
} else {
goto handle_unusual;
}
@@ -231,9 +231,9 @@ void SourceContext::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.SourceContext)
// optional string file_name = 1;
if (this->file_name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->file_name().data(), this->file_name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.SourceContext.file_name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->file_name(), output);
@@ -247,9 +247,9 @@ void SourceContext::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext)
// optional string file_name = 1;
if (this->file_name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->file_name().data(), this->file_name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.SourceContext.file_name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
diff --git a/src/google/protobuf/source_context.proto b/src/google/protobuf/source_context.proto
index 98d4920a..e9a27d65 100644
--- a/src/google/protobuf/source_context.proto
+++ b/src/google/protobuf/source_context.proto
@@ -34,10 +34,10 @@ package google.protobuf;
option java_multiple_files = true;
option java_outer_classname = "SourceContextProto";
option java_package = "com.google.protobuf";
+option java_generate_equals_and_hash = true;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// `SourceContext` represents information about the source of a
// protobuf element, like the file in which it is defined.
message SourceContext {
diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc
index a7e2eafd..d5f89122 100644
--- a/src/google/protobuf/struct.pb.cc
+++ b/src/google/protobuf/struct.pb.cc
@@ -301,6 +301,10 @@ bool Struct::MergePartialFromCodedStream(
DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
input, entry.get()));
(*mutable_fields())[entry->key()].Swap(entry->mutable_value());
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ entry->key().data(), entry->key().length(),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Struct.FieldsEntry.key"));
} else {
goto handle_unusual;
}
@@ -343,6 +347,10 @@ void Struct::SerializeWithCachedSizes(
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");
}
}
@@ -362,6 +370,10 @@ void Struct::SerializeWithCachedSizes(
target = ::google::protobuf::internal::WireFormatLite::
WriteMessageNoVirtualToArray(
1, *entry, target);
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ it->first.data(), it->first.length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Struct.FieldsEntry.key");
}
}
@@ -631,10 +643,10 @@ bool Value::MergePartialFromCodedStream(
parse_string_value:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_string_value()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->string_value().data(), this->string_value().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Value.string_value");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Value.string_value"));
} else {
goto handle_unusual;
}
@@ -721,9 +733,9 @@ void Value::SerializeWithCachedSizes(
// optional string string_value = 3;
if (has_string_value()) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->string_value().data(), this->string_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Value.string_value");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
3, this->string_value(), output);
@@ -765,9 +777,9 @@ void Value::SerializeWithCachedSizes(
// optional string string_value = 3;
if (has_string_value()) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->string_value().data(), this->string_value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Value.string_value");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1114,10 +1126,11 @@ void Value::clear_struct_value() {
}
const ::google::protobuf::Struct& Value::struct_value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
- return has_struct_value() ? *kind_.struct_value_
- : ::google::protobuf::Struct::default_instance();
+ return has_struct_value()
+ ? *kind_.struct_value_
+ : ::google::protobuf::Struct::default_instance();
}
- ::google::protobuf::Struct* Value::mutable_struct_value() {
+::google::protobuf::Struct* Value::mutable_struct_value() {
if (!has_struct_value()) {
clear_kind();
set_has_struct_value();
@@ -1126,7 +1139,7 @@ void Value::clear_struct_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Value.struct_value)
return kind_.struct_value_;
}
- ::google::protobuf::Struct* Value::release_struct_value() {
+::google::protobuf::Struct* Value::release_struct_value() {
if (has_struct_value()) {
clear_has_kind();
::google::protobuf::Struct* temp = kind_.struct_value_;
@@ -1136,7 +1149,7 @@ void Value::clear_struct_value() {
return NULL;
}
}
- void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) {
+void Value::set_allocated_struct_value(::google::protobuf::Struct* struct_value) {
clear_kind();
if (struct_value) {
set_has_struct_value();
@@ -1160,10 +1173,11 @@ void Value::clear_list_value() {
}
const ::google::protobuf::ListValue& Value::list_value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
- return has_list_value() ? *kind_.list_value_
- : ::google::protobuf::ListValue::default_instance();
+ return has_list_value()
+ ? *kind_.list_value_
+ : ::google::protobuf::ListValue::default_instance();
}
- ::google::protobuf::ListValue* Value::mutable_list_value() {
+::google::protobuf::ListValue* Value::mutable_list_value() {
if (!has_list_value()) {
clear_kind();
set_has_list_value();
@@ -1172,7 +1186,7 @@ void Value::clear_list_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Value.list_value)
return kind_.list_value_;
}
- ::google::protobuf::ListValue* Value::release_list_value() {
+::google::protobuf::ListValue* Value::release_list_value() {
if (has_list_value()) {
clear_has_kind();
::google::protobuf::ListValue* temp = kind_.list_value_;
@@ -1182,7 +1196,7 @@ void Value::clear_list_value() {
return NULL;
}
}
- void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) {
+void Value::set_allocated_list_value(::google::protobuf::ListValue* list_value) {
clear_kind();
if (list_value) {
set_has_list_value();
@@ -1422,28 +1436,28 @@ int ListValue::values_size() const {
void ListValue::clear_values() {
values_.Clear();
}
- const ::google::protobuf::Value& ListValue::values(int index) const {
+const ::google::protobuf::Value& ListValue::values(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.ListValue.values)
return values_.Get(index);
}
- ::google::protobuf::Value* ListValue::mutable_values(int index) {
+::google::protobuf::Value* ListValue::mutable_values(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.ListValue.values)
return values_.Mutable(index);
}
- ::google::protobuf::Value* ListValue::add_values() {
+::google::protobuf::Value* ListValue::add_values() {
// @@protoc_insertion_point(field_add:google.protobuf.ListValue.values)
return values_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
-ListValue::values() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
- return values_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >*
ListValue::mutable_values() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values)
return &values_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
+ListValue::values() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
+ return values_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h
index 2889c8fe..0527c812 100644
--- a/src/google/protobuf/struct.pb.h
+++ b/src/google/protobuf/struct.pb.h
@@ -40,9 +40,9 @@ void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fstruct_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2fstruct_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2fstruct_2eproto();
+class ListValue;
class Struct;
class Value;
-class ListValue;
enum NullValue {
NULL_VALUE = 0,
@@ -383,10 +383,10 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message {
const ::google::protobuf::Value& values(int index) const;
::google::protobuf::Value* mutable_values(int index);
::google::protobuf::Value* add_values();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
- values() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >*
mutable_values();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
+ values() const;
// @@protoc_insertion_point(class_scope:google.protobuf.ListValue)
private:
@@ -612,10 +612,11 @@ inline void Value::clear_struct_value() {
clear_has_kind();
}
}
-inline const ::google::protobuf::Struct& Value::struct_value() const {
+inline const ::google::protobuf::Struct& Value::struct_value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Value.struct_value)
- return has_struct_value() ? *kind_.struct_value_
- : ::google::protobuf::Struct::default_instance();
+ return has_struct_value()
+ ? *kind_.struct_value_
+ : ::google::protobuf::Struct::default_instance();
}
inline ::google::protobuf::Struct* Value::mutable_struct_value() {
if (!has_struct_value()) {
@@ -658,10 +659,11 @@ inline void Value::clear_list_value() {
clear_has_kind();
}
}
-inline const ::google::protobuf::ListValue& Value::list_value() const {
+inline const ::google::protobuf::ListValue& Value::list_value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Value.list_value)
- return has_list_value() ? *kind_.list_value_
- : ::google::protobuf::ListValue::default_instance();
+ return has_list_value()
+ ? *kind_.list_value_
+ : ::google::protobuf::ListValue::default_instance();
}
inline ::google::protobuf::ListValue* Value::mutable_list_value() {
if (!has_list_value()) {
@@ -723,16 +725,16 @@ inline ::google::protobuf::Value* ListValue::add_values() {
// @@protoc_insertion_point(field_add:google.protobuf.ListValue.values)
return values_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
-ListValue::values() const {
- // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
- return values_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >*
ListValue::mutable_values() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.ListValue.values)
return &values_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value >&
+ListValue::values() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.ListValue.values)
+ return values_;
+}
#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------
diff --git a/src/google/protobuf/struct.proto b/src/google/protobuf/struct.proto
index 4ff10cd0..b3e9e699 100644
--- a/src/google/protobuf/struct.proto
+++ b/src/google/protobuf/struct.proto
@@ -45,6 +45,8 @@ option objc_class_prefix = "GPB";
// scripting languages like JS a struct is represented as an
// object. The details of that representation are described together
// with the proto support for the language.
+//
+// The JSON representation for `Struct` is JSON object.
message Struct {
// Map of dynamically typed values.
map<string, Value> fields = 1;
@@ -54,37 +56,39 @@ message Struct {
// null, a number, a string, a boolean, a recursive struct value, or a
// list of values. A producer of value is expected to set one of that
// variants, absence of any variant indicates an error.
+//
+// The JSON representation for `Value` is JSON value.
message Value {
+ // The kind of value.
oneof kind {
// Represents a null value.
NullValue null_value = 1;
-
// Represents a double value.
double number_value = 2;
-
// Represents a string value.
string string_value = 3;
-
// Represents a boolean value.
bool bool_value = 4;
-
// Represents a structured value.
Struct struct_value = 5;
-
// Represents a repeated `Value`.
ListValue list_value = 6;
}
}
+// `NullValue` is a singleton enumeration to represent the null value for the
+// `Value` type union.
+//
+// The JSON representation for `NullValue` is JSON `null`.
+enum NullValue {
+ // Null value.
+ NULL_VALUE = 0;
+}
+
// `ListValue` is a wrapper around a repeated field of values.
+//
+// The JSON representation for `ListValue` is JSON array.
message ListValue {
// Repeated field of dynamically typed values.
repeated Value values = 1;
}
-
-// `NullValue` is a singleton enumeration to represent the null
-// value for the `Value` type union.
-enum NullValue {
- // Null value.
- NULL_VALUE = 0;
-}
diff --git a/src/google/protobuf/stubs/common.cc b/src/google/protobuf/stubs/common.cc
index d470fc72..54dbafab 100644
--- a/src/google/protobuf/stubs/common.cc
+++ b/src/google/protobuf/stubs/common.cc
@@ -35,8 +35,10 @@
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/stubs/stringpiece.h>
#include <google/protobuf/stubs/strutil.h>
-#include <stdio.h>
+#include <google/protobuf/stubs/int128.h>
#include <errno.h>
+#include <sstream>
+#include <stdio.h>
#include <vector>
#ifdef _WIN32
@@ -48,6 +50,9 @@
#else
#error "No suitable threading library available."
#endif
+#if defined(__ANDROID__)
+#include <android/log.h>
+#endif
namespace google {
namespace protobuf {
@@ -104,7 +109,43 @@ string VersionString(int version) {
// emulates google3/base/logging.cc
namespace internal {
+#if defined(__ANDROID__)
+inline void DefaultLogHandler(LogLevel level, const char* filename, int line,
+ const string& message) {
+#ifdef GOOGLE_PROTOBUF_MIN_LOG_LEVEL
+ if (level < GOOGLE_PROTOBUF_MIN_LOG_LEVEL) {
+ return;
+ }
+ static const char* level_names[] = {"INFO", "WARNING", "ERROR", "FATAL"};
+
+ static const int android_log_levels[] = {
+ ANDROID_LOG_INFO, // LOG(INFO),
+ ANDROID_LOG_WARN, // LOG(WARNING)
+ ANDROID_LOG_ERROR, // LOG(ERROR)
+ ANDROID_LOG_FATAL, // LOG(FATAL)
+ };
+ // Bound the logging level.
+ const int android_log_level = android_log_levels[level];
+ ::std::ostringstream ostr;
+ ostr << "[libprotobuf " << level_names[level] << " " << filename << ":"
+ << line << "] " << message.c_str();
+
+ // Output the log string the Android log at the appropriate level.
+ __android_log_write(android_log_level, "libprotobuf-native",
+ ostr.str().c_str());
+ // Also output to std::cerr.
+ fprintf(stderr, "%s", ostr.str().c_str());
+ fflush(stderr);
+
+ // Indicate termination if needed.
+ if (android_log_level == ANDROID_LOG_FATAL) {
+ __android_log_write(ANDROID_LOG_FATAL, "libprotobuf-native",
+ "terminating.\n");
+ }
+#endif
+}
+#else
void DefaultLogHandler(LogLevel level, const char* filename, int line,
const string& message) {
static const char* level_names[] = { "INFO", "WARNING", "ERROR", "FATAL" };
@@ -115,6 +156,7 @@ void DefaultLogHandler(LogLevel level, const char* filename, int line,
level_names[level], filename, line, message.c_str());
fflush(stderr); // Needed on MSVC.
}
+#endif
void NullLogHandler(LogLevel /* level */, const char* /* filename */,
int /* line */, const string& /* message */) {
@@ -154,22 +196,19 @@ LogMessage& LogMessage::operator<<(const StringPiece& value) {
return *this;
}
-LogMessage& LogMessage::operator<<(long long value) {
- message_ += SimpleItoa(value);
- return *this;
-}
-
-LogMessage& LogMessage::operator<<(unsigned long long value) {
- message_ += SimpleItoa(value);
- return *this;
-}
-
LogMessage& LogMessage::operator<<(
const ::google::protobuf::util::Status& status) {
message_ += status.ToString();
return *this;
}
+LogMessage& LogMessage::operator<<(const uint128& value) {
+ std::ostringstream str;
+ str << value;
+ message_ += str.str();
+ return *this;
+}
+
// Since this is just for logging, we don't care if the current locale changes
// the results -- in fact, we probably prefer that. So we use snprintf()
// instead of Simple*toa().
@@ -194,6 +233,8 @@ DECLARE_STREAM_OPERATOR(long , "%ld")
DECLARE_STREAM_OPERATOR(unsigned long, "%lu")
DECLARE_STREAM_OPERATOR(double , "%g" )
DECLARE_STREAM_OPERATOR(void* , "%p" )
+DECLARE_STREAM_OPERATOR(long long , "%" GOOGLE_LL_FORMAT "d")
+DECLARE_STREAM_OPERATOR(unsigned long long, "%" GOOGLE_LL_FORMAT "u")
#undef DECLARE_STREAM_OPERATOR
LogMessage::LogMessage(LogLevel level, const char* filename, int line)
diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h
index de866e14..88e7084f 100644
--- a/src/google/protobuf/stubs/common.h
+++ b/src/google/protobuf/stubs/common.h
@@ -35,6 +35,7 @@
#ifndef GOOGLE_PROTOBUF_COMMON_H__
#define GOOGLE_PROTOBUF_COMMON_H__
+#include <string>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/macros.h>
@@ -137,12 +138,35 @@ std::string LIBPROTOBUF_EXPORT VersionString(int version);
// ===================================================================
// from google3/util/utf8/public/unilib.h
+class StringPiece;
namespace internal {
// Checks if the buffer contains structurally-valid UTF-8. Implemented in
// structurally_valid.cc.
LIBPROTOBUF_EXPORT bool IsStructurallyValidUTF8(const char* buf, int len);
+inline bool IsStructurallyValidUTF8(const std::string& str) {
+ return IsStructurallyValidUTF8(str.data(), str.length());
+}
+
+// Returns initial number of bytes of structually valid UTF-8.
+LIBPROTOBUF_EXPORT int UTF8SpnStructurallyValid(const StringPiece& str);
+
+// Coerce UTF-8 byte string in src_str to be
+// a structurally-valid equal-length string by selectively
+// overwriting illegal bytes with replace_char (typically ' ' or '?').
+// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
+// src_str is read-only.
+//
+// Returns pointer to output buffer, src_str.data() if no changes were made,
+// or idst if some bytes were changed. idst is allocated by the caller
+// and must be at least as big as src_str
+//
+// Optimized for: all structurally valid and no byte copying is done.
+//
+LIBPROTOBUF_EXPORT char* UTF8CoerceToStructurallyValid(
+ const StringPiece& str, char* dst, char replace_char);
+
} // namespace internal
diff --git a/src/google/protobuf/stubs/hash.h b/src/google/protobuf/stubs/hash.h
index 9a6b217a..c6f210f0 100755
--- a/src/google/protobuf/stubs/hash.h
+++ b/src/google/protobuf/stubs/hash.h
@@ -103,8 +103,8 @@
# define GOOGLE_PROTOBUF_HAS_CXX11_HASH
# define GOOGLE_PROTOBUF_HASH_COMPARE std::hash_compare
# elif _MSC_VER >= 1500 // Since Visual Studio 2008
-# define GOOGLE_PROTOBUF_HAS_TR1
-# define GOOGLE_PROTOBUF_HASH_COMPARE stdext::hash_compare
+# undef GOOGLE_PROTOBUF_HAVE_HASH_MAP
+# undef GOOGLE_PROTOBUF_HAVE_HASH_SET
# elif _MSC_VER >= 1310
# define GOOGLE_PROTOBUF_HASH_NAMESPACE stdext
# include <hash_map>
@@ -143,6 +143,11 @@
# define GOOGLE_PROTOBUF_HASH_SET_CLASS unordered_set
#endif
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START \
+ namespace google { \
+ namespace protobuf {
+# define GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END }}
+
#undef GOOGLE_PROTOBUF_HAS_CXX11_HASH
#undef GOOGLE_PROTOBUF_HAS_TR1
diff --git a/src/google/protobuf/stubs/int128.cc b/src/google/protobuf/stubs/int128.cc
new file mode 100644
index 00000000..9f4fb824
--- /dev/null
+++ b/src/google/protobuf/stubs/int128.cc
@@ -0,0 +1,200 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/stubs/int128.h>
+
+#include <iomanip>
+#include <iostream> // NOLINT(readability/streams)
+#include <sstream>
+
+namespace google {
+namespace protobuf {
+
+const uint128_pod kuint128max = {
+ static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF)),
+ static_cast<uint64>(GOOGLE_LONGLONG(0xFFFFFFFFFFFFFFFF))
+};
+
+// Returns the 0-based position of the last set bit (i.e., most significant bit)
+// in the given uint64. The argument may not be 0.
+//
+// For example:
+// Given: 5 (decimal) == 101 (binary)
+// Returns: 2
+#define STEP(T, n, pos, sh) \
+ do { \
+ if ((n) >= (static_cast<T>(1) << (sh))) { \
+ (n) = (n) >> (sh); \
+ (pos) |= (sh); \
+ } \
+ } while (0)
+static inline int Fls64(uint64 n) {
+ GOOGLE_DCHECK_NE(0, n);
+ int pos = 0;
+ STEP(uint64, n, pos, 0x20);
+ uint32 n32 = n;
+ STEP(uint32, n32, pos, 0x10);
+ STEP(uint32, n32, pos, 0x08);
+ STEP(uint32, n32, pos, 0x04);
+ return pos + ((GOOGLE_ULONGLONG(0x3333333322221100) >> (n32 << 2)) & 0x3);
+}
+#undef STEP
+
+// Like Fls64() above, but returns the 0-based position of the last set bit
+// (i.e., most significant bit) in the given uint128. The argument may not be 0.
+static inline int Fls128(uint128 n) {
+ if (uint64 hi = Uint128High64(n)) {
+ return Fls64(hi) + 64;
+ }
+ return Fls64(Uint128Low64(n));
+}
+
+// Long division/modulo for uint128 implemented using the shift-subtract
+// division algorithm adapted from:
+// http://stackoverflow.com/questions/5386377/division-without-using
+void uint128::DivModImpl(uint128 dividend, uint128 divisor,
+ uint128* quotient_ret, uint128* remainder_ret) {
+ if (divisor == 0) {
+ GOOGLE_LOG(FATAL) << "Division or mod by zero: dividend.hi=" << dividend.hi_
+ << ", lo=" << dividend.lo_;
+ }
+
+ if (divisor > dividend) {
+ *quotient_ret = 0;
+ *remainder_ret = dividend;
+ return;
+ }
+
+ if (divisor == dividend) {
+ *quotient_ret = 1;
+ *remainder_ret = 0;
+ return;
+ }
+
+ uint128 denominator = divisor;
+ uint128 position = 1;
+ uint128 quotient = 0;
+
+ // Left aligns the MSB of the denominator and the dividend.
+ int shift = Fls128(dividend) - Fls128(denominator);
+ denominator <<= shift;
+ position <<= shift;
+
+ // Uses shift-subtract algorithm to divide dividend by denominator. The
+ // remainder will be left in dividend.
+ while (position > 0) {
+ if (dividend >= denominator) {
+ dividend -= denominator;
+ quotient |= position;
+ }
+ position >>= 1;
+ denominator >>= 1;
+ }
+
+ *quotient_ret = quotient;
+ *remainder_ret = dividend;
+}
+
+uint128& uint128::operator/=(const uint128& divisor) {
+ uint128 quotient = 0;
+ uint128 remainder = 0;
+ DivModImpl(*this, divisor, &quotient, &remainder);
+ *this = quotient;
+ return *this;
+}
+uint128& uint128::operator%=(const uint128& divisor) {
+ uint128 quotient = 0;
+ uint128 remainder = 0;
+ DivModImpl(*this, divisor, &quotient, &remainder);
+ *this = remainder;
+ return *this;
+}
+
+std::ostream& operator<<(std::ostream& o, const uint128& b) {
+ std::ios_base::fmtflags flags = o.flags();
+
+ // Select a divisor which is the largest power of the base < 2^64.
+ uint128 div;
+ std::streamsize div_base_log;
+ switch (flags & std::ios::basefield) {
+ case std::ios::hex:
+ div = GOOGLE_ULONGLONG(0x1000000000000000); // 16^15
+ div_base_log = 15;
+ break;
+ case std::ios::oct:
+ div = GOOGLE_ULONGLONG(01000000000000000000000); // 8^21
+ div_base_log = 21;
+ break;
+ default: // std::ios::dec
+ div = GOOGLE_ULONGLONG(10000000000000000000); // 10^19
+ div_base_log = 19;
+ break;
+ }
+
+ // Now piece together the uint128 representation from three chunks of
+ // the original value, each less than "div" and therefore representable
+ // as a uint64.
+ std::ostringstream os;
+ std::ios_base::fmtflags copy_mask =
+ std::ios::basefield | std::ios::showbase | std::ios::uppercase;
+ os.setf(flags & copy_mask, copy_mask);
+ uint128 high = b;
+ uint128 low;
+ uint128::DivModImpl(high, div, &high, &low);
+ uint128 mid;
+ uint128::DivModImpl(high, div, &high, &mid);
+ if (high.lo_ != 0) {
+ os << high.lo_;
+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
+ os << mid.lo_;
+ os << std::setw(div_base_log);
+ } else if (mid.lo_ != 0) {
+ os << mid.lo_;
+ os << std::noshowbase << std::setfill('0') << std::setw(div_base_log);
+ }
+ os << low.lo_;
+ std::string rep = os.str();
+
+ // Add the requisite padding.
+ std::streamsize width = o.width(0);
+ if (width > rep.size()) {
+ if ((flags & std::ios::adjustfield) == std::ios::left) {
+ rep.append(width - rep.size(), o.fill());
+ } else {
+ rep.insert(0, width - rep.size(), o.fill());
+ }
+ }
+
+ // Stream the final representation in a single "<<" call.
+ return o << rep;
+}
+
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/stubs/int128.h b/src/google/protobuf/stubs/int128.h
new file mode 100644
index 00000000..1499bb76
--- /dev/null
+++ b/src/google/protobuf/stubs/int128.h
@@ -0,0 +1,383 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#ifndef GOOGLE_PROTOBUF_STUBS_INT128_H_
+#define GOOGLE_PROTOBUF_STUBS_INT128_H_
+
+#include <google/protobuf/stubs/common.h>
+
+#include <iosfwd>
+
+namespace google {
+namespace protobuf {
+
+struct uint128_pod;
+
+// TODO(xiaofeng): Define GOOGLE_PROTOBUF_HAS_CONSTEXPR when constexpr is
+// available.
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+# define UINT128_CONSTEXPR constexpr
+#else
+# define UINT128_CONSTEXPR
+#endif
+
+// An unsigned 128-bit integer type. Thread-compatible.
+class LIBPROTOBUF_EXPORT uint128 {
+ public:
+ UINT128_CONSTEXPR uint128(); // Sets to 0, but don't trust on this behavior.
+ UINT128_CONSTEXPR uint128(uint64 top, uint64 bottom);
+#ifndef SWIG
+ UINT128_CONSTEXPR uint128(int bottom);
+ UINT128_CONSTEXPR uint128(uint32 bottom); // Top 96 bits = 0
+#endif
+ UINT128_CONSTEXPR uint128(uint64 bottom); // hi_ = 0
+ UINT128_CONSTEXPR uint128(const uint128_pod &val);
+
+ // Trivial copy constructor, assignment operator and destructor.
+
+ void Initialize(uint64 top, uint64 bottom);
+
+ // Arithmetic operators.
+ uint128& operator+=(const uint128& b);
+ uint128& operator-=(const uint128& b);
+ uint128& operator*=(const uint128& b);
+ // Long division/modulo for uint128.
+ uint128& operator/=(const uint128& b);
+ uint128& operator%=(const uint128& b);
+ uint128 operator++(int);
+ uint128 operator--(int);
+ uint128& operator<<=(int);
+ uint128& operator>>=(int);
+ uint128& operator&=(const uint128& b);
+ uint128& operator|=(const uint128& b);
+ uint128& operator^=(const uint128& b);
+ uint128& operator++();
+ uint128& operator--();
+
+ friend uint64 Uint128Low64(const uint128& v);
+ friend uint64 Uint128High64(const uint128& v);
+
+ // We add "std::" to avoid including all of port.h.
+ LIBPROTOBUF_EXPORT friend std::ostream& operator<<(std::ostream& o,
+ const uint128& b);
+
+ private:
+ static void DivModImpl(uint128 dividend, uint128 divisor,
+ uint128* quotient_ret, uint128* remainder_ret);
+
+ // Little-endian memory order optimizations can benefit from
+ // having lo_ first, hi_ last.
+ // See util/endian/endian.h and Load128/Store128 for storing a uint128.
+ uint64 lo_;
+ uint64 hi_;
+
+ // Not implemented, just declared for catching automatic type conversions.
+ uint128(uint8);
+ uint128(uint16);
+ uint128(float v);
+ uint128(double v);
+};
+
+// This is a POD form of uint128 which can be used for static variables which
+// need to be operated on as uint128.
+struct uint128_pod {
+ // Note: The ordering of fields is different than 'class uint128' but the
+ // same as its 2-arg constructor. This enables more obvious initialization
+ // of static instances, which is the primary reason for this struct in the
+ // first place. This does not seem to defeat any optimizations wrt
+ // operations involving this struct.
+ uint64 hi;
+ uint64 lo;
+};
+
+LIBPROTOBUF_EXPORT extern const uint128_pod kuint128max;
+
+// allow uint128 to be logged
+LIBPROTOBUF_EXPORT extern std::ostream& operator<<(std::ostream& o,
+ const uint128& b);
+
+// Methods to access low and high pieces of 128-bit value.
+// Defined externally from uint128 to facilitate conversion
+// to native 128-bit types when compilers support them.
+inline uint64 Uint128Low64(const uint128& v) { return v.lo_; }
+inline uint64 Uint128High64(const uint128& v) { return v.hi_; }
+
+// TODO: perhaps it would be nice to have int128, a signed 128-bit type?
+
+// --------------------------------------------------------------------------
+// Implementation details follow
+// --------------------------------------------------------------------------
+inline bool operator==(const uint128& lhs, const uint128& rhs) {
+ return (Uint128Low64(lhs) == Uint128Low64(rhs) &&
+ Uint128High64(lhs) == Uint128High64(rhs));
+}
+inline bool operator!=(const uint128& lhs, const uint128& rhs) {
+ return !(lhs == rhs);
+}
+
+inline UINT128_CONSTEXPR uint128::uint128() : lo_(0), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 top, uint64 bottom)
+ : lo_(bottom), hi_(top) {}
+inline UINT128_CONSTEXPR uint128::uint128(const uint128_pod& v)
+ : lo_(v.lo), hi_(v.hi) {}
+inline UINT128_CONSTEXPR uint128::uint128(uint64 bottom)
+ : lo_(bottom), hi_(0) {}
+#ifndef SWIG
+inline UINT128_CONSTEXPR uint128::uint128(uint32 bottom)
+ : lo_(bottom), hi_(0) {}
+inline UINT128_CONSTEXPR uint128::uint128(int bottom)
+ : lo_(bottom), hi_(static_cast<int64>((bottom < 0) ? -1 : 0)) {}
+#endif
+
+#undef UINT128_CONSTEXPR
+
+inline void uint128::Initialize(uint64 top, uint64 bottom) {
+ hi_ = top;
+ lo_ = bottom;
+}
+
+// Comparison operators.
+
+#define CMP128(op) \
+inline bool operator op(const uint128& lhs, const uint128& rhs) { \
+ return (Uint128High64(lhs) == Uint128High64(rhs)) ? \
+ (Uint128Low64(lhs) op Uint128Low64(rhs)) : \
+ (Uint128High64(lhs) op Uint128High64(rhs)); \
+}
+
+CMP128(<)
+CMP128(>)
+CMP128(>=)
+CMP128(<=)
+
+#undef CMP128
+
+// Unary operators
+
+inline uint128 operator-(const uint128& val) {
+ const uint64 hi_flip = ~Uint128High64(val);
+ const uint64 lo_flip = ~Uint128Low64(val);
+ const uint64 lo_add = lo_flip + 1;
+ if (lo_add < lo_flip) {
+ return uint128(hi_flip + 1, lo_add);
+ }
+ return uint128(hi_flip, lo_add);
+}
+
+inline bool operator!(const uint128& val) {
+ return !Uint128High64(val) && !Uint128Low64(val);
+}
+
+// Logical operators.
+
+inline uint128 operator~(const uint128& val) {
+ return uint128(~Uint128High64(val), ~Uint128Low64(val));
+}
+
+#define LOGIC128(op) \
+inline uint128 operator op(const uint128& lhs, const uint128& rhs) { \
+ return uint128(Uint128High64(lhs) op Uint128High64(rhs), \
+ Uint128Low64(lhs) op Uint128Low64(rhs)); \
+}
+
+LOGIC128(|)
+LOGIC128(&)
+LOGIC128(^)
+
+#undef LOGIC128
+
+#define LOGICASSIGN128(op) \
+inline uint128& uint128::operator op(const uint128& other) { \
+ hi_ op other.hi_; \
+ lo_ op other.lo_; \
+ return *this; \
+}
+
+LOGICASSIGN128(|=)
+LOGICASSIGN128(&=)
+LOGICASSIGN128(^=)
+
+#undef LOGICASSIGN128
+
+// Shift operators.
+
+inline uint128 operator<<(const uint128& val, int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return val;
+ }
+ uint64 new_hi = (Uint128High64(val) << amount) |
+ (Uint128Low64(val) >> (64 - amount));
+ uint64 new_lo = Uint128Low64(val) << amount;
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(Uint128Low64(val) << (amount - 64), 0);
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128 operator>>(const uint128& val, int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount == 0) {
+ return val;
+ }
+ uint64 new_hi = Uint128High64(val) >> amount;
+ uint64 new_lo = (Uint128Low64(val) >> amount) |
+ (Uint128High64(val) << (64 - amount));
+ return uint128(new_hi, new_lo);
+ } else if (amount < 128) {
+ return uint128(0, Uint128High64(val) >> (amount - 64));
+ } else {
+ return uint128(0, 0);
+ }
+}
+
+inline uint128& uint128::operator<<=(int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount != 0) {
+ hi_ = (hi_ << amount) | (lo_ >> (64 - amount));
+ lo_ = lo_ << amount;
+ }
+ } else if (amount < 128) {
+ hi_ = lo_ << (amount - 64);
+ lo_ = 0;
+ } else {
+ hi_ = 0;
+ lo_ = 0;
+ }
+ return *this;
+}
+
+inline uint128& uint128::operator>>=(int amount) {
+ // uint64 shifts of >= 64 are undefined, so we will need some special-casing.
+ if (amount < 64) {
+ if (amount != 0) {
+ lo_ = (lo_ >> amount) | (hi_ << (64 - amount));
+ hi_ = hi_ >> amount;
+ }
+ } else if (amount < 128) {
+ lo_ = hi_ >> (amount - 64);
+ hi_ = 0;
+ } else {
+ lo_ = 0;
+ hi_ = 0;
+ }
+ return *this;
+}
+
+inline uint128 operator+(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) += rhs;
+}
+
+inline uint128 operator-(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) -= rhs;
+}
+
+inline uint128 operator*(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) *= rhs;
+}
+
+inline uint128 operator/(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) /= rhs;
+}
+
+inline uint128 operator%(const uint128& lhs, const uint128& rhs) {
+ return uint128(lhs) %= rhs;
+}
+
+inline uint128& uint128::operator+=(const uint128& b) {
+ hi_ += b.hi_;
+ uint64 lolo = lo_ + b.lo_;
+ if (lolo < lo_)
+ ++hi_;
+ lo_ = lolo;
+ return *this;
+}
+
+inline uint128& uint128::operator-=(const uint128& b) {
+ hi_ -= b.hi_;
+ if (b.lo_ > lo_)
+ --hi_;
+ lo_ -= b.lo_;
+ return *this;
+}
+
+inline uint128& uint128::operator*=(const uint128& b) {
+ uint64 a96 = hi_ >> 32;
+ uint64 a64 = hi_ & 0xffffffffu;
+ uint64 a32 = lo_ >> 32;
+ uint64 a00 = lo_ & 0xffffffffu;
+ uint64 b96 = b.hi_ >> 32;
+ uint64 b64 = b.hi_ & 0xffffffffu;
+ uint64 b32 = b.lo_ >> 32;
+ uint64 b00 = b.lo_ & 0xffffffffu;
+ // multiply [a96 .. a00] x [b96 .. b00]
+ // terms higher than c96 disappear off the high side
+ // terms c96 and c64 are safe to ignore carry bit
+ uint64 c96 = a96 * b00 + a64 * b32 + a32 * b64 + a00 * b96;
+ uint64 c64 = a64 * b00 + a32 * b32 + a00 * b64;
+ this->hi_ = (c96 << 32) + c64;
+ this->lo_ = 0;
+ // add terms after this one at a time to capture carry
+ *this += uint128(a32 * b00) << 32;
+ *this += uint128(a00 * b32) << 32;
+ *this += a00 * b00;
+ return *this;
+}
+
+inline uint128 uint128::operator++(int) {
+ uint128 tmp(*this);
+ *this += 1;
+ return tmp;
+}
+
+inline uint128 uint128::operator--(int) {
+ uint128 tmp(*this);
+ *this -= 1;
+ return tmp;
+}
+
+inline uint128& uint128::operator++() {
+ *this += 1;
+ return *this;
+}
+
+inline uint128& uint128::operator--() {
+ *this -= 1;
+ return *this;
+}
+
+} // namespace protobuf
+} // namespace google
+
+#endif // GOOGLE_PROTOBUF_STUBS_INT128_H_
diff --git a/src/google/protobuf/stubs/int128_unittest.cc b/src/google/protobuf/stubs/int128_unittest.cc
new file mode 100644
index 00000000..5d33292c
--- /dev/null
+++ b/src/google/protobuf/stubs/int128_unittest.cc
@@ -0,0 +1,513 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/stubs/int128.h>
+
+#include <algorithm>
+#include <sstream>
+#include <utility>
+
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+
+TEST(Int128, AllTests) {
+ uint128 zero(0);
+ uint128 one(1);
+ uint128 one_2arg(0, 1);
+ uint128 two(0, 2);
+ uint128 three(0, 3);
+ uint128 big(2000, 2);
+ uint128 big_minus_one(2000, 1);
+ uint128 bigger(2001, 1);
+ uint128 biggest(kuint128max);
+ uint128 high_low(1, 0);
+ uint128 low_high(0, kuint64max);
+ EXPECT_LT(one, two);
+ EXPECT_GT(two, one);
+ EXPECT_LT(one, big);
+ EXPECT_LT(one, big);
+ EXPECT_EQ(one, one_2arg);
+ EXPECT_NE(one, two);
+ EXPECT_GT(big, one);
+ EXPECT_GE(big, two);
+ EXPECT_GE(big, big_minus_one);
+ EXPECT_GT(big, big_minus_one);
+ EXPECT_LT(big_minus_one, big);
+ EXPECT_LE(big_minus_one, big);
+ EXPECT_NE(big_minus_one, big);
+ EXPECT_LT(big, biggest);
+ EXPECT_LE(big, biggest);
+ EXPECT_GT(biggest, big);
+ EXPECT_GE(biggest, big);
+ EXPECT_EQ(big, ~~big);
+ EXPECT_EQ(one, one | one);
+ EXPECT_EQ(big, big | big);
+ EXPECT_EQ(one, one | zero);
+ EXPECT_EQ(one, one & one);
+ EXPECT_EQ(big, big & big);
+ EXPECT_EQ(zero, one & zero);
+ EXPECT_EQ(zero, big & ~big);
+ EXPECT_EQ(zero, one ^ one);
+ EXPECT_EQ(zero, big ^ big);
+ EXPECT_EQ(one, one ^ zero);
+
+ // Shift operators.
+ EXPECT_EQ(big, big << 0);
+ EXPECT_EQ(big, big >> 0);
+ EXPECT_GT(big << 1, big);
+ EXPECT_LT(big >> 1, big);
+ EXPECT_EQ(big, (big << 10) >> 10);
+ EXPECT_EQ(big, (big >> 1) << 1);
+ EXPECT_EQ(one, (one << 80) >> 80);
+ EXPECT_EQ(zero, (one >> 80) << 80);
+ EXPECT_EQ(zero, big >> 128);
+ EXPECT_EQ(zero, big << 128);
+
+ // Shift assignments.
+ uint128 big_copy = big;
+ EXPECT_EQ(big << 0, big_copy <<= 0);
+ big_copy = big;
+ EXPECT_EQ(big >> 0, big_copy >>= 0);
+ big_copy = big;
+ EXPECT_EQ(big << 1, big_copy <<= 1);
+ big_copy = big;
+ EXPECT_EQ(big >> 1, big_copy >>= 1);
+ big_copy = big;
+ EXPECT_EQ(big << 10, big_copy <<= 10);
+ big_copy = big;
+ EXPECT_EQ(big >> 10, big_copy >>= 10);
+ big_copy = big;
+ EXPECT_EQ(big << 64, big_copy <<= 64);
+ big_copy = big;
+ EXPECT_EQ(big >> 64, big_copy >>= 64);
+ big_copy = big;
+ EXPECT_EQ(big << 73, big_copy <<= 73);
+ big_copy = big;
+ EXPECT_EQ(big >> 73, big_copy >>= 73);
+ big_copy = big;
+ EXPECT_EQ(big << 128, big_copy <<= 128);
+ big_copy = big;
+ EXPECT_EQ(big >> 128, big_copy >>= 128);
+
+ EXPECT_EQ(Uint128High64(biggest), kuint64max);
+ EXPECT_EQ(Uint128Low64(biggest), kuint64max);
+ EXPECT_EQ(zero + one, one);
+ EXPECT_EQ(one + one, two);
+ EXPECT_EQ(big_minus_one + one, big);
+ EXPECT_EQ(one - one, zero);
+ EXPECT_EQ(one - zero, one);
+ EXPECT_EQ(zero - one, biggest);
+ EXPECT_EQ(big - big, zero);
+ EXPECT_EQ(big - one, big_minus_one);
+ EXPECT_EQ(big + kuint64max, bigger);
+ EXPECT_EQ(biggest + 1, zero);
+ EXPECT_EQ(zero - 1, biggest);
+ EXPECT_EQ(high_low - one, low_high);
+ EXPECT_EQ(low_high + one, high_low);
+ EXPECT_EQ(Uint128High64((uint128(1) << 64) - 1), 0);
+ EXPECT_EQ(Uint128Low64((uint128(1) << 64) - 1), kuint64max);
+ EXPECT_TRUE(!!one);
+ EXPECT_TRUE(!!high_low);
+ EXPECT_FALSE(!!zero);
+ EXPECT_FALSE(!one);
+ EXPECT_FALSE(!high_low);
+ EXPECT_TRUE(!zero);
+ EXPECT_TRUE(zero == 0);
+ EXPECT_FALSE(zero != 0);
+ EXPECT_FALSE(one == 0);
+ EXPECT_TRUE(one != 0);
+
+ uint128 test = zero;
+ EXPECT_EQ(++test, one);
+ EXPECT_EQ(test, one);
+ EXPECT_EQ(test++, one);
+ EXPECT_EQ(test, two);
+ EXPECT_EQ(test -= 2, zero);
+ EXPECT_EQ(test, zero);
+ EXPECT_EQ(test += 2, two);
+ EXPECT_EQ(test, two);
+ EXPECT_EQ(--test, one);
+ EXPECT_EQ(test, one);
+ EXPECT_EQ(test--, one);
+ EXPECT_EQ(test, zero);
+ EXPECT_EQ(test |= three, three);
+ EXPECT_EQ(test &= one, one);
+ EXPECT_EQ(test ^= three, two);
+ EXPECT_EQ(test >>= 1, one);
+ EXPECT_EQ(test <<= 1, two);
+
+ EXPECT_EQ(big, -(-big));
+ EXPECT_EQ(two, -((-one) - 1));
+ EXPECT_EQ(kuint128max, -one);
+ EXPECT_EQ(zero, -zero);
+
+ GOOGLE_LOG(INFO) << one;
+ GOOGLE_LOG(INFO) << big_minus_one;
+}
+
+TEST(Int128, PodTests) {
+ uint128_pod pod = { 12345, 67890 };
+ uint128 from_pod(pod);
+ EXPECT_EQ(12345, Uint128High64(from_pod));
+ EXPECT_EQ(67890, Uint128Low64(from_pod));
+
+ uint128 zero(0);
+ uint128_pod zero_pod = {0, 0};
+ uint128 one(1);
+ uint128_pod one_pod = {0, 1};
+ uint128 two(2);
+ uint128_pod two_pod = {0, 2};
+ uint128 three(3);
+ uint128_pod three_pod = {0, 3};
+ uint128 big(1, 0);
+ uint128_pod big_pod = {1, 0};
+
+ EXPECT_EQ(zero, zero_pod);
+ EXPECT_EQ(zero_pod, zero);
+ EXPECT_EQ(zero_pod, zero_pod);
+ EXPECT_EQ(one, one_pod);
+ EXPECT_EQ(one_pod, one);
+ EXPECT_EQ(one_pod, one_pod);
+ EXPECT_EQ(two, two_pod);
+ EXPECT_EQ(two_pod, two);
+ EXPECT_EQ(two_pod, two_pod);
+
+ EXPECT_NE(one, two_pod);
+ EXPECT_NE(one_pod, two);
+ EXPECT_NE(one_pod, two_pod);
+
+ EXPECT_LT(one, two_pod);
+ EXPECT_LT(one_pod, two);
+ EXPECT_LT(one_pod, two_pod);
+ EXPECT_LE(one, one_pod);
+ EXPECT_LE(one_pod, one);
+ EXPECT_LE(one_pod, one_pod);
+ EXPECT_LE(one, two_pod);
+ EXPECT_LE(one_pod, two);
+ EXPECT_LE(one_pod, two_pod);
+
+ EXPECT_GT(two, one_pod);
+ EXPECT_GT(two_pod, one);
+ EXPECT_GT(two_pod, one_pod);
+ EXPECT_GE(two, two_pod);
+ EXPECT_GE(two_pod, two);
+ EXPECT_GE(two_pod, two_pod);
+ EXPECT_GE(two, one_pod);
+ EXPECT_GE(two_pod, one);
+ EXPECT_GE(two_pod, one_pod);
+
+ EXPECT_EQ(three, one | two_pod);
+ EXPECT_EQ(three, one_pod | two);
+ EXPECT_EQ(three, one_pod | two_pod);
+ EXPECT_EQ(one, three & one_pod);
+ EXPECT_EQ(one, three_pod & one);
+ EXPECT_EQ(one, three_pod & one_pod);
+ EXPECT_EQ(two, three ^ one_pod);
+ EXPECT_EQ(two, three_pod ^ one);
+ EXPECT_EQ(two, three_pod ^ one_pod);
+ EXPECT_EQ(two, three & (~one));
+ EXPECT_EQ(three, ~~three);
+
+ EXPECT_EQ(two, two_pod << 0);
+ EXPECT_EQ(two, one_pod << 1);
+ EXPECT_EQ(big, one_pod << 64);
+ EXPECT_EQ(zero, one_pod << 128);
+ EXPECT_EQ(two, two_pod >> 0);
+ EXPECT_EQ(one, two_pod >> 1);
+ EXPECT_EQ(one, big_pod >> 64);
+
+ EXPECT_EQ(one, zero + one_pod);
+ EXPECT_EQ(one, zero_pod + one);
+ EXPECT_EQ(one, zero_pod + one_pod);
+ EXPECT_EQ(one, two - one_pod);
+ EXPECT_EQ(one, two_pod - one);
+ EXPECT_EQ(one, two_pod - one_pod);
+}
+
+TEST(Int128, OperatorAssignReturnRef) {
+ uint128 v(1);
+ (v += 4) -= 3;
+ EXPECT_EQ(2, v);
+}
+
+TEST(Int128, Multiply) {
+ uint128 a, b, c;
+
+ // Zero test.
+ a = 0;
+ b = 0;
+ c = a * b;
+ EXPECT_EQ(0, c);
+
+ // Max carries.
+ a = uint128(0) - 1;
+ b = uint128(0) - 1;
+ c = a * b;
+ EXPECT_EQ(1, c);
+
+ // Self-operation with max carries.
+ c = uint128(0) - 1;
+ c *= c;
+ EXPECT_EQ(1, c);
+
+ // 1-bit x 1-bit.
+ for (int i = 0; i < 64; ++i) {
+ for (int j = 0; j < 64; ++j) {
+ a = uint128(1) << i;
+ b = uint128(1) << j;
+ c = a * b;
+ EXPECT_EQ(uint128(1) << (i+j), c);
+ }
+ }
+
+ // Verified with dc.
+ a = uint128(GOOGLE_ULONGLONG(0xffffeeeeddddcccc),
+ GOOGLE_ULONGLONG(0xbbbbaaaa99998888));
+ b = uint128(GOOGLE_ULONGLONG(0x7777666655554444),
+ GOOGLE_ULONGLONG(0x3333222211110000));
+ c = a * b;
+ EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x530EDA741C71D4C3),
+ GOOGLE_ULONGLONG(0xBF25975319080000)), c);
+ EXPECT_EQ(0, c - b * a);
+ EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+
+ // Verified with dc.
+ a = uint128(GOOGLE_ULONGLONG(0x0123456789abcdef),
+ GOOGLE_ULONGLONG(0xfedcba9876543210));
+ b = uint128(GOOGLE_ULONGLONG(0x02468ace13579bdf),
+ GOOGLE_ULONGLONG(0xfdb97531eca86420));
+ c = a * b;
+ EXPECT_EQ(uint128(GOOGLE_ULONGLONG(0x97a87f4f261ba3f2),
+ GOOGLE_ULONGLONG(0x342d0bbf48948200)), c);
+ EXPECT_EQ(0, c - b * a);
+ EXPECT_EQ(a*a - b*b, (a+b) * (a-b));
+}
+
+TEST(Int128, AliasTests) {
+ uint128 x1(1, 2);
+ uint128 x2(2, 4);
+ x1 += x1;
+ EXPECT_EQ(x2, x1);
+
+ uint128 x3(1, static_cast<uint64>(1) << 63);
+ uint128 x4(3, 0);
+ x3 += x3;
+ EXPECT_EQ(x4, x3);
+}
+
+#ifdef PROTOBUF_HAS_DEATH_TEST
+TEST(Int128, DivideByZeroCheckFails) {
+ uint128 a = 0;
+ uint128 b = 0;
+ EXPECT_DEATH(a / b, "Division or mod by zero:");
+ a = 123;
+ EXPECT_DEATH(a / b, "Division or mod by zero:");
+}
+
+TEST(Int128, ModByZeroCheckFails) {
+ uint128 a = 0;
+ uint128 b = 0;
+ EXPECT_DEATH(a % b, "Division or mod by zero:");
+ a = 123;
+ EXPECT_DEATH(a % b, "Division or mod by zero:");
+}
+#endif // PROTOBUF_HAS_DEATH_TEST
+
+TEST(Int128, DivideAndMod) {
+ // a := q * b + r
+ uint128 a, b, q, r;
+
+ // Zero test.
+ a = 0;
+ b = 123;
+ q = a / b;
+ r = a % b;
+ EXPECT_EQ(0, q);
+ EXPECT_EQ(0, r);
+
+ a = uint128(GOOGLE_ULONGLONG(0x530eda741c71d4c3),
+ GOOGLE_ULONGLONG(0xbf25975319080000));
+ q = uint128(GOOGLE_ULONGLONG(0x4de2cab081),
+ GOOGLE_ULONGLONG(0x14c34ab4676e4bab));
+ b = uint128(0x1110001);
+ r = uint128(0x3eb455);
+ ASSERT_EQ(a, q * b + r); // Sanity-check.
+
+ uint128 result_q, result_r;
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(q, result_q);
+ EXPECT_EQ(r, result_r);
+
+ // Try the other way around.
+ swap(q, b);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(q, result_q);
+ EXPECT_EQ(r, result_r);
+ // Restore.
+ swap(b, q);
+
+ // Dividend < divisor; result should be q:0 r:<dividend>.
+ swap(a, b);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(0, result_q);
+ EXPECT_EQ(a, result_r);
+ // Try the other way around.
+ swap(a, q);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(0, result_q);
+ EXPECT_EQ(a, result_r);
+ // Restore.
+ swap(q, a);
+ swap(b, a);
+
+ // Try a large remainder.
+ b = a / 2 + 1;
+ uint128 expected_r(GOOGLE_ULONGLONG(0x29876d3a0e38ea61),
+ GOOGLE_ULONGLONG(0xdf92cba98c83ffff));
+ // Sanity checks.
+ ASSERT_EQ(a / 2 - 1, expected_r);
+ ASSERT_EQ(a, b + expected_r);
+ result_q = a / b;
+ result_r = a % b;
+ EXPECT_EQ(1, result_q);
+ EXPECT_EQ(expected_r, result_r);
+}
+
+static uint64 RandomUint64() {
+ uint64 v1 = rand();
+ uint64 v2 = rand();
+ uint64 v3 = rand();
+ return v1 * v2 + v3;
+}
+
+TEST(Int128, DivideAndModRandomInputs) {
+ const int kNumIters = 1 << 18;
+ for (int i = 0; i < kNumIters; ++i) {
+ const uint128 a(RandomUint64(), RandomUint64());
+ const uint128 b(RandomUint64(), RandomUint64());
+ if (b == 0) {
+ continue; // Avoid a div-by-zero.
+ }
+ const uint128 q = a / b;
+ const uint128 r = a % b;
+ ASSERT_EQ(a, b * q + r);
+ }
+}
+
+#ifdef GOOGLE_PROTOBUF_HAS_CONSTEXPR
+TEST(Int128, ConstexprTest) {
+ constexpr uint128 zero;
+ constexpr uint128 one = 1;
+ constexpr uint128_pod pod = {2, 3};
+ constexpr uint128 from_pod = pod;
+ constexpr uint128 minus_two = -2;
+ EXPECT_EQ(one, uint128(1));
+ EXPECT_EQ(from_pod, uint128(2, 3));
+ EXPECT_EQ(minus_two, uint128(-1ULL, -2ULL));
+}
+
+TEST(Int128, Traits) {
+ EXPECT_TRUE(std::is_trivially_copy_constructible<uint128>::value);
+ EXPECT_TRUE(std::is_trivially_copy_assignable<uint128>::value);
+ EXPECT_TRUE(std::is_trivially_destructible<uint128>::value);
+}
+#endif // GOOGLE_PROTOBUF_HAS_CONSTEXPR
+
+TEST(Int128, OStream) {
+ struct {
+ uint128 val;
+ std::ios_base::fmtflags flags;
+ std::streamsize width;
+ char fill;
+ const char* rep;
+ } cases[] = {
+ // zero with different bases
+ {uint128(0), std::ios::dec, 0, '_', "0"},
+ {uint128(0), std::ios::oct, 0, '_', "0"},
+ {uint128(0), std::ios::hex, 0, '_', "0"},
+ // crossover between lo_ and hi_
+ {uint128(0, -1), std::ios::dec, 0, '_', "18446744073709551615"},
+ {uint128(0, -1), std::ios::oct, 0, '_', "1777777777777777777777"},
+ {uint128(0, -1), std::ios::hex, 0, '_', "ffffffffffffffff"},
+ {uint128(1, 0), std::ios::dec, 0, '_', "18446744073709551616"},
+ {uint128(1, 0), std::ios::oct, 0, '_', "2000000000000000000000"},
+ {uint128(1, 0), std::ios::hex, 0, '_', "10000000000000000"},
+ // just the top bit
+ {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::dec, 0, '_',
+ "170141183460469231731687303715884105728"},
+ {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::oct, 0, '_',
+ "2000000000000000000000000000000000000000000"},
+ {uint128(GOOGLE_ULONGLONG(0x8000000000000000), 0), std::ios::hex, 0, '_',
+ "80000000000000000000000000000000"},
+ // maximum uint128 value
+ {uint128(-1, -1), std::ios::dec, 0, '_',
+ "340282366920938463463374607431768211455"},
+ {uint128(-1, -1), std::ios::oct, 0, '_',
+ "3777777777777777777777777777777777777777777"},
+ {uint128(-1, -1), std::ios::hex, 0, '_',
+ "ffffffffffffffffffffffffffffffff"},
+ // uppercase
+ {uint128(-1, -1), std::ios::hex | std::ios::uppercase, 0, '_',
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"},
+ // showbase
+ {uint128(1), std::ios::dec | std::ios::showbase, 0, '_', "1"},
+ {uint128(1), std::ios::oct | std::ios::showbase, 0, '_', "01"},
+ {uint128(1), std::ios::hex | std::ios::showbase, 0, '_', "0x1"},
+ // showbase does nothing on zero
+ {uint128(0), std::ios::dec | std::ios::showbase, 0, '_', "0"},
+ {uint128(0), std::ios::oct | std::ios::showbase, 0, '_', "0"},
+ {uint128(0), std::ios::hex | std::ios::showbase, 0, '_', "0"},
+ // showpos does nothing on unsigned types
+ {uint128(1), std::ios::dec | std::ios::showpos, 0, '_', "1"},
+ // padding
+ {uint128(9), std::ios::dec, 6, '_', "_____9"},
+ {uint128(12345), std::ios::dec, 6, '_', "_12345"},
+ // left adjustment
+ {uint128(9), std::ios::dec | std::ios::left, 6, '_', "9_____"},
+ {uint128(12345), std::ios::dec | std::ios::left, 6, '_', "12345_"},
+ };
+ for (size_t i = 0; i < GOOGLE_ARRAYSIZE(cases); ++i) {
+ ostringstream os;
+ os.flags(cases[i].flags);
+ os.width(cases[i].width);
+ os.fill(cases[i].fill);
+ os << cases[i].val;
+ EXPECT_EQ(cases[i].rep, os.str());
+ }
+}
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/stubs/logging.h b/src/google/protobuf/stubs/logging.h
index 330d33d2..3108db8c 100644
--- a/src/google/protobuf/stubs/logging.h
+++ b/src/google/protobuf/stubs/logging.h
@@ -65,6 +65,7 @@ class StringPiece;
namespace util {
class Status;
}
+class uint128;
namespace internal {
class LogFinisher;
@@ -78,7 +79,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
LogMessage& operator<<(const char* value);
LogMessage& operator<<(char value);
LogMessage& operator<<(int value);
- LogMessage& operator<<(unsigned int value);
+ LogMessage& operator<<(uint value);
LogMessage& operator<<(long value);
LogMessage& operator<<(unsigned long value);
LogMessage& operator<<(long long value);
@@ -87,6 +88,7 @@ class LIBPROTOBUF_EXPORT LogMessage {
LogMessage& operator<<(void* value);
LogMessage& operator<<(const StringPiece& value);
LogMessage& operator<<(const ::google::protobuf::util::Status& status);
+ LogMessage& operator<<(const uint128& value);
private:
friend class LogFinisher;
diff --git a/src/google/protobuf/stubs/mathutil.h b/src/google/protobuf/stubs/mathutil.h
index 99c4d452..3a1ef8a8 100644
--- a/src/google/protobuf/stubs/mathutil.h
+++ b/src/google/protobuf/stubs/mathutil.h
@@ -45,9 +45,21 @@ bool IsNan(T value) {
return false;
}
template<>
-inline bool IsNan(float value) { return isnan(value); }
+inline bool IsNan(float value) {
+#ifdef _MSC_VER
+ return _isnan(value);
+#else
+ return isnan(value);
+#endif
+}
template<>
-inline bool IsNan(double value) { return isnan(value); }
+inline bool IsNan(double value) {
+#ifdef _MSC_VER
+ return _isnan(value);
+#else
+ return isnan(value);
+#endif
+}
template<typename T>
bool AlmostEquals(T a, T b) {
diff --git a/src/google/protobuf/stubs/port.h b/src/google/protobuf/stubs/port.h
index 74bdfffa..b35a3afe 100644
--- a/src/google/protobuf/stubs/port.h
+++ b/src/google/protobuf/stubs/port.h
@@ -45,12 +45,15 @@
#endif
#undef PROTOBUF_LITTLE_ENDIAN
-#ifdef _MSC_VER
+#ifdef _WIN32
// Assuming windows is always little-endian.
+ // TODO(xiaofeng): The PROTOBUF_LITTLE_ENDIAN is not only used for
+ // optimization but also for correctness. We should define an
+ // different macro to test the big-endian code path in coded_stream.
#if !defined(PROTOBUF_DISABLE_LITTLE_ENDIAN_OPT_FOR_TEST)
#define PROTOBUF_LITTLE_ENDIAN 1
#endif
- #if _MSC_VER >= 1300
+ #if defined(_MSC_VER) && _MSC_VER >= 1300
// If MSVC has "/RTCc" set, it will complain about truncating casts at
// runtime. This file contains some intentional truncating casts.
#pragma runtime_checks("c", off)
@@ -109,20 +112,12 @@ typedef unsigned __int64 uint64;
typedef signed char int8;
typedef short int16;
typedef int int32;
-// NOTE: This should be "long long" for consistency with upstream, but
-// something is stacked against this particular type for 64bit hashing.
-// Switching it causes an obvious missing hash function (with an unobvious
-// cause) when building the tests.
-typedef int64_t int64;
+typedef long long int64;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
-// NOTE: This should be "unsigned long long" for consistency with upstream, but
-// something is stacked against this particular type for 64bit hashing.
-// Switching it causes an obvious missing hash function (with an unobvious
-// cause) when building the tests.
-typedef uint64_t uint64;
+typedef unsigned long long uint64;
#endif
// long long macros to be used because gcc and vc++ use different suffixes,
diff --git a/src/google/protobuf/stubs/status.cc b/src/google/protobuf/stubs/status.cc
index 7314c563..dd1bd614 100644
--- a/src/google/protobuf/stubs/status.cc
+++ b/src/google/protobuf/stubs/status.cc
@@ -30,7 +30,6 @@
#include <google/protobuf/stubs/status.h>
#include <ostream>
-#include <stdint.h>
#include <stdio.h>
#include <string>
#include <utility>
diff --git a/src/google/protobuf/stubs/structurally_valid.cc b/src/google/protobuf/stubs/structurally_valid.cc
index 0f6afe6d..d79a6ee4 100644
--- a/src/google/protobuf/stubs/structurally_valid.cc
+++ b/src/google/protobuf/stubs/structurally_valid.cc
@@ -3,6 +3,8 @@
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringpiece.h>
+
namespace google {
namespace protobuf {
namespace internal {
@@ -531,6 +533,56 @@ bool IsStructurallyValidUTF8(const char* buf, int len) {
return (bytes_consumed == len);
}
+int UTF8SpnStructurallyValid(const StringPiece& str) {
+ if (!module_initialized_) return str.size();
+
+ int bytes_consumed = 0;
+ UTF8GenericScanFastAscii(&utf8acceptnonsurrogates_obj,
+ str.data(), str.size(), &bytes_consumed);
+ return bytes_consumed;
+}
+
+// Coerce UTF-8 byte string in src_str to be
+// a structurally-valid equal-length string by selectively
+// overwriting illegal bytes with replace_char (typically blank).
+// replace_char must be legal printable 7-bit Ascii 0x20..0x7e.
+// src_str is read-only. If any overwriting is needed, a modified byte string
+// is created in idst, length isrclen.
+//
+// Returns pointer to output buffer, isrc if no changes were made,
+// or idst if some bytes were changed.
+//
+// Fast case: all is structurally valid and no byte copying is done.
+//
+char* UTF8CoerceToStructurallyValid(const StringPiece& src_str,
+ char* idst,
+ const char replace_char) {
+ const char* isrc = src_str.data();
+ const int len = src_str.length();
+ int n = UTF8SpnStructurallyValid(src_str);
+ if (n == len) { // Normal case -- all is cool, return
+ return const_cast<char*>(isrc);
+ } else { // Unusual case -- copy w/o bad bytes
+ const char* src = isrc;
+ const char* srclimit = isrc + len;
+ char* dst = idst;
+ memmove(dst, src, n); // Copy initial good chunk
+ src += n;
+ dst += n;
+ while (src < srclimit) { // src points to bogus byte or is off the end
+ dst[0] = replace_char; // replace one bad byte
+ src++;
+ dst++;
+ StringPiece str2(src, srclimit - src);
+ n = UTF8SpnStructurallyValid(str2); // scan the remainder
+ memmove(dst, src, n); // copy next good chunk
+ src += n;
+ dst += n;
+ }
+ }
+ return idst;
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/test_util.cc b/src/google/protobuf/test_util.cc
index be1c90e0..07aa1d77 100644
--- a/src/google/protobuf/test_util.cc
+++ b/src/google/protobuf/test_util.cc
@@ -42,6 +42,7 @@
#include <google/protobuf/descriptor.h>
#include <google/protobuf/message.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc
index 88eca0ad..388c0cbd 100644
--- a/src/google/protobuf/test_util_lite.cc
+++ b/src/google/protobuf/test_util_lite.cc
@@ -33,6 +33,7 @@
// Sanjay Ghemawat, Jeff Dean, and others.
#include <google/protobuf/test_util_lite.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc
index 76ce9875..1aafd8e6 100644
--- a/src/google/protobuf/text_format_unittest.cc
+++ b/src/google/protobuf/text_format_unittest.cc
@@ -38,11 +38,13 @@
#include <stdlib.h>
#include <limits>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/file.h>
#include <google/protobuf/test_util.h>
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/unittest_mset_wire_format.pb.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/strutil.h>
diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto
index 11f258da..06b60e6f 100644
--- a/src/google/protobuf/timestamp.proto
+++ b/src/google/protobuf/timestamp.proto
@@ -38,7 +38,6 @@ option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
@@ -85,14 +84,16 @@ option objc_class_prefix = "GPB";
// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
// .setNanos((int) ((millis % 1000) * 1000000)).build();
//
-// Example 5: Compute Timestamp from Python `datetime.datetime`.
//
-// now = datetime.datetime.utcnow()
-// seconds = int(time.mktime(now.timetuple()))
-// nanos = now.microsecond * 1000
+// Example 5: Compute Timestamp from current time in Python.
+//
+// now = time.time()
+// seconds = int(now)
+// nanos = int((now - seconds) * 10**9)
// timestamp = Timestamp(seconds=seconds, nanos=nanos)
//
message Timestamp {
+
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.
diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc
index 029a72c6..8f993561 100644
--- a/src/google/protobuf/type.pb.cc
+++ b/src/google/protobuf/type.pb.cc
@@ -38,6 +38,7 @@ const ::google::protobuf::internal::GeneratedMessageReflection*
const ::google::protobuf::Descriptor* Option_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
Option_reflection_ = NULL;
+const ::google::protobuf::EnumDescriptor* Syntax_descriptor_ = NULL;
} // namespace
@@ -49,12 +50,13 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
"google/protobuf/type.proto");
GOOGLE_CHECK(file != NULL);
Type_descriptor_ = file->message_type(0);
- static const int Type_offsets_[5] = {
+ static const int Type_offsets_[6] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, options_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, source_context_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, syntax_),
};
Type_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -68,7 +70,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _is_default_instance_));
Field_descriptor_ = file->message_type(1);
- static const int Field_offsets_[8] = {
+ static const int Field_offsets_[9] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_),
@@ -77,6 +79,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, oneof_index_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, packed_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, options_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, json_name_),
};
Field_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -92,11 +95,12 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
Field_Kind_descriptor_ = Field_descriptor_->enum_type(0);
Field_Cardinality_descriptor_ = Field_descriptor_->enum_type(1);
Enum_descriptor_ = file->message_type(2);
- static const int Enum_offsets_[4] = {
+ static const int Enum_offsets_[5] = {
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, source_context_),
+ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, syntax_),
};
Enum_reflection_ =
::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
@@ -142,6 +146,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto() {
sizeof(Option),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_),
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _is_default_instance_));
+ Syntax_descriptor_ = file->enum_type(0);
}
namespace {
@@ -192,38 +197,43 @@ void protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto() {
::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
"\n\032google/protobuf/type.proto\022\017google.pro"
"tobuf\032\031google/protobuf/any.proto\032$google"
- "/protobuf/source_context.proto\"\256\001\n\004Type\022"
+ "/protobuf/source_context.proto\"\327\001\n\004Type\022"
"\014\n\004name\030\001 \001(\t\022&\n\006fields\030\002 \003(\0132\026.google.p"
"rotobuf.Field\022\016\n\006oneofs\030\003 \003(\t\022(\n\007options"
"\030\004 \003(\0132\027.google.protobuf.Option\0226\n\016sourc"
"e_context\030\005 \001(\0132\036.google.protobuf.Source"
- "Context\"\233\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.google"
- ".protobuf.Field.Kind\0227\n\013cardinality\030\002 \001("
- "\0162\".google.protobuf.Field.Cardinality\022\016\n"
- "\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url\030"
- "\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 \001"
- "(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.Op"
- "tion\"\270\002\n\004Kind\022\020\n\014TYPE_UNKNOWN\020\000\022\017\n\013TYPE_"
- "DOUBLE\020\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003"
- "\022\017\n\013TYPE_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYP"
- "E_FIXED64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BO"
- "OL\020\010\022\017\n\013TYPE_STRING\020\t\022\020\n\014TYPE_MESSAGE\020\013\022"
- "\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE"
- "_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXE"
- "D64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\""
- "t\n\013Cardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022"
- "\030\n\024CARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY"
- "_REQUIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\245\001"
- "\n\004Enum\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132"
- "\032.google.protobuf.EnumValue\022(\n\007options\030\003"
- " \003(\0132\027.google.protobuf.Option\0226\n\016source_"
- "context\030\004 \001(\0132\036.google.protobuf.SourceCo"
- "ntext\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006numb"
- "er\030\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.proto"
- "buf.Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005va"
- "lue\030\002 \001(\0132\024.google.protobuf.AnyBI\n\023com.g"
- "oogle.protobufB\tTypeProtoP\001\242\002\003GPB\252\002\036Goog"
- "le.Protobuf.WellKnownTypesb\006proto3", 1354);
+ "Context\022\'\n\006syntax\030\006 \001(\0162\027.google.protobu"
+ "f.Syntax\"\276\005\n\005Field\022)\n\004kind\030\001 \001(\0162\033.googl"
+ "e.protobuf.Field.Kind\0227\n\013cardinality\030\002 \001"
+ "(\0162\".google.protobuf.Field.Cardinality\022\016"
+ "\n\006number\030\003 \001(\005\022\014\n\004name\030\004 \001(\t\022\020\n\010type_url"
+ "\030\006 \001(\t\022\023\n\013oneof_index\030\007 \001(\005\022\016\n\006packed\030\010 "
+ "\001(\010\022(\n\007options\030\t \003(\0132\027.google.protobuf.O"
+ "ption\022\021\n\tjson_name\030\n \001(\t\"\310\002\n\004Kind\022\020\n\014TYP"
+ "E_UNKNOWN\020\000\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FLO"
+ "AT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016\n"
+ "\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\020\006\022\020\n\014TYPE_"
+ "FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n\013TYPE_STRING\020"
+ "\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_MESSAGE\020\013\022\016\n\nT"
+ "YPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_ENU"
+ "M\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64\020"
+ "\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"t\n\013C"
+ "ardinality\022\027\n\023CARDINALITY_UNKNOWN\020\000\022\030\n\024C"
+ "ARDINALITY_OPTIONAL\020\001\022\030\n\024CARDINALITY_REQ"
+ "UIRED\020\002\022\030\n\024CARDINALITY_REPEATED\020\003\"\316\001\n\004En"
+ "um\022\014\n\004name\030\001 \001(\t\022-\n\tenumvalue\030\002 \003(\0132\032.go"
+ "ogle.protobuf.EnumValue\022(\n\007options\030\003 \003(\013"
+ "2\027.google.protobuf.Option\0226\n\016source_cont"
+ "ext\030\004 \001(\0132\036.google.protobuf.SourceContex"
+ "t\022\'\n\006syntax\030\005 \001(\0162\027.google.protobuf.Synt"
+ "ax\"S\n\tEnumValue\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030"
+ "\002 \001(\005\022(\n\007options\030\003 \003(\0132\027.google.protobuf"
+ ".Option\";\n\006Option\022\014\n\004name\030\001 \001(\t\022#\n\005value"
+ "\030\002 \001(\0132\024.google.protobuf.Any*.\n\006Syntax\022\021"
+ "\n\rSYNTAX_PROTO2\020\000\022\021\n\rSYNTAX_PROTO3\020\001BL\n\023"
+ "com.google.protobufB\tTypeProtoP\001\240\001\001\242\002\003GP"
+ "B\252\002\036Google.Protobuf.WellKnownTypesb\006prot"
+ "o3", 1522);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/type.proto", &protobuf_RegisterTypes);
Type::default_instance_ = new Type();
@@ -245,6 +255,20 @@ struct StaticDescriptorInitializer_google_2fprotobuf_2ftype_2eproto {
protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
}
} static_descriptor_initializer_google_2fprotobuf_2ftype_2eproto_;
+const ::google::protobuf::EnumDescriptor* Syntax_descriptor() {
+ protobuf_AssignDescriptorsOnce();
+ return Syntax_descriptor_;
+}
+bool Syntax_IsValid(int value) {
+ switch(value) {
+ case 0:
+ case 1:
+ return true;
+ default:
+ return false;
+ }
+}
+
namespace {
@@ -264,6 +288,7 @@ const int Type::kFieldsFieldNumber;
const int Type::kOneofsFieldNumber;
const int Type::kOptionsFieldNumber;
const int Type::kSourceContextFieldNumber;
+const int Type::kSyntaxFieldNumber;
#endif // !_MSC_VER
Type::Type()
@@ -291,6 +316,7 @@ void Type::SharedCtor() {
_cached_size_ = 0;
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
source_context_ = NULL;
+ syntax_ = 0;
}
Type::~Type() {
@@ -334,6 +360,7 @@ void Type::Clear() {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
+ syntax_ = 0;
fields_.Clear();
oneofs_.Clear();
options_.Clear();
@@ -354,10 +381,10 @@ bool Type::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Type.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Type.name"));
} else {
goto handle_unusual;
}
@@ -388,11 +415,11 @@ bool Type::MergePartialFromCodedStream(
parse_oneofs:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->add_oneofs()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->oneofs(this->oneofs_size() - 1).data(),
this->oneofs(this->oneofs_size() - 1).length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Type.oneofs");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Type.oneofs"));
} else {
goto handle_unusual;
}
@@ -427,6 +454,22 @@ bool Type::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
+ if (input->ExpectTag(48)) goto parse_syntax;
+ break;
+ }
+
+ // optional .google.protobuf.Syntax syntax = 6;
+ case 6: {
+ if (tag == 48) {
+ parse_syntax:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -457,9 +500,9 @@ void Type::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Type)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Type.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -473,10 +516,10 @@ void Type::SerializeWithCachedSizes(
// repeated string oneofs = 3;
for (int i = 0; i < this->oneofs_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
- this->oneofs(i).data(), this->oneofs(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
- "google.protobuf.Type.oneofs");
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->oneofs(i).data(), this->oneofs(i).length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Type.oneofs");
::google::protobuf::internal::WireFormatLite::WriteString(
3, this->oneofs(i), output);
}
@@ -493,6 +536,12 @@ void Type::SerializeWithCachedSizes(
5, *this->source_context_, output);
}
+ // optional .google.protobuf.Syntax syntax = 6;
+ if (this->syntax() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 6, this->syntax(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Type)
}
@@ -501,9 +550,9 @@ void Type::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Type.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -519,9 +568,9 @@ void Type::SerializeWithCachedSizes(
// repeated string oneofs = 3;
for (int i = 0; i < this->oneofs_size(); i++) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->oneofs(i).data(), this->oneofs(i).length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Type.oneofs");
target = ::google::protobuf::internal::WireFormatLite::
WriteStringToArray(3, this->oneofs(i), target);
@@ -541,6 +590,12 @@ void Type::SerializeWithCachedSizes(
5, *this->source_context_, target);
}
+ // optional .google.protobuf.Syntax syntax = 6;
+ if (this->syntax() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 6, this->syntax(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Type)
return target;
}
@@ -562,6 +617,12 @@ int Type::ByteSize() const {
*this->source_context_);
}
+ // optional .google.protobuf.Syntax syntax = 6;
+ if (this->syntax() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+ }
+
// repeated .google.protobuf.Field fields = 2;
total_size += 1 * this->fields_size();
for (int i = 0; i < this->fields_size(); i++) {
@@ -615,6 +676,9 @@ void Type::MergeFrom(const Type& from) {
if (from.has_source_context()) {
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
}
+ if (from.syntax() != 0) {
+ set_syntax(from.syntax());
+ }
}
void Type::CopyFrom(const ::google::protobuf::Message& from) {
@@ -644,6 +708,7 @@ void Type::InternalSwap(Type* other) {
oneofs_.UnsafeArenaSwap(&other->oneofs_);
options_.UnsafeArenaSwap(&other->options_);
std::swap(source_context_, other->source_context_);
+ std::swap(syntax_, other->syntax_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -709,28 +774,28 @@ int Type::fields_size() const {
void Type::clear_fields() {
fields_.Clear();
}
- const ::google::protobuf::Field& Type::fields(int index) const {
+const ::google::protobuf::Field& Type::fields(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Type.fields)
return fields_.Get(index);
}
- ::google::protobuf::Field* Type::mutable_fields(int index) {
+::google::protobuf::Field* Type::mutable_fields(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Type.fields)
return fields_.Mutable(index);
}
- ::google::protobuf::Field* Type::add_fields() {
+::google::protobuf::Field* Type::add_fields() {
// @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
return fields_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
-Type::fields() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
- return fields_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
Type::mutable_fields() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields)
return &fields_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
+Type::fields() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
+ return fields_;
+}
// repeated string oneofs = 3;
int Type::oneofs_size() const {
@@ -793,28 +858,28 @@ int Type::options_size() const {
void Type::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& Type::options(int index) const {
+const ::google::protobuf::Option& Type::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Type.options)
return options_.Get(index);
}
- ::google::protobuf::Option* Type::mutable_options(int index) {
+::google::protobuf::Option* Type::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Type.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* Type::add_options() {
+::google::protobuf::Option* Type::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Type.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Type::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
- return options_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Type::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options)
return &options_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Type::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
+ return options_;
+}
// optional .google.protobuf.SourceContext source_context = 5;
bool Type::has_source_context() const {
@@ -824,11 +889,11 @@ void Type::clear_source_context() {
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
}
- const ::google::protobuf::SourceContext& Type::source_context() const {
+const ::google::protobuf::SourceContext& Type::source_context() const {
// @@protoc_insertion_point(field_get:google.protobuf.Type.source_context)
return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_;
}
- ::google::protobuf::SourceContext* Type::mutable_source_context() {
+::google::protobuf::SourceContext* Type::mutable_source_context() {
if (source_context_ == NULL) {
source_context_ = new ::google::protobuf::SourceContext;
@@ -836,13 +901,13 @@ void Type::clear_source_context() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Type.source_context)
return source_context_;
}
- ::google::protobuf::SourceContext* Type::release_source_context() {
+::google::protobuf::SourceContext* Type::release_source_context() {
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
return temp;
}
- void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
+void Type::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
delete source_context_;
source_context_ = source_context;
if (source_context) {
@@ -853,6 +918,20 @@ void Type::clear_source_context() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
}
+// optional .google.protobuf.Syntax syntax = 6;
+void Type::clear_syntax() {
+ syntax_ = 0;
+}
+ ::google::protobuf::Syntax Type::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Type::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
+}
+
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
@@ -873,6 +952,7 @@ bool Field_Kind_IsValid(int value) {
case 7:
case 8:
case 9:
+ case 10:
case 11:
case 12:
case 13:
@@ -898,6 +978,7 @@ const Field_Kind Field::TYPE_FIXED64;
const Field_Kind Field::TYPE_FIXED32;
const Field_Kind Field::TYPE_BOOL;
const Field_Kind Field::TYPE_STRING;
+const Field_Kind Field::TYPE_GROUP;
const Field_Kind Field::TYPE_MESSAGE;
const Field_Kind Field::TYPE_BYTES;
const Field_Kind Field::TYPE_UINT32;
@@ -944,6 +1025,7 @@ const int Field::kTypeUrlFieldNumber;
const int Field::kOneofIndexFieldNumber;
const int Field::kPackedFieldNumber;
const int Field::kOptionsFieldNumber;
+const int Field::kJsonNameFieldNumber;
#endif // !_MSC_VER
Field::Field()
@@ -975,6 +1057,7 @@ void Field::SharedCtor() {
type_url_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
oneof_index_ = 0;
packed_ = false;
+ json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
Field::~Field() {
@@ -985,6 +1068,7 @@ Field::~Field() {
void Field::SharedDtor() {
name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
type_url_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+ json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (this != default_instance_) {
}
}
@@ -1028,6 +1112,7 @@ void Field::Clear() {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
type_url_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
packed_ = false;
+ json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
#undef ZR_HELPER_
#undef ZR_
@@ -1097,10 +1182,10 @@ bool Field::MergePartialFromCodedStream(
parse_name:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Field.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Field.name"));
} else {
goto handle_unusual;
}
@@ -1114,10 +1199,10 @@ bool Field::MergePartialFromCodedStream(
parse_type_url:
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_type_url()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Field.type_url");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Field.type_url"));
} else {
goto handle_unusual;
}
@@ -1168,6 +1253,23 @@ bool Field::MergePartialFromCodedStream(
}
if (input->ExpectTag(74)) goto parse_loop_options;
input->UnsafeDecrementRecursionDepth();
+ if (input->ExpectTag(82)) goto parse_json_name;
+ break;
+ }
+
+ // optional string json_name = 10;
+ case 10: {
+ if (tag == 82) {
+ parse_json_name:
+ DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+ input, this->mutable_json_name()));
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->json_name().data(), this->json_name().length(),
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Field.json_name"));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -1215,9 +1317,9 @@ void Field::SerializeWithCachedSizes(
// optional string name = 4;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Field.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
4, this->name(), output);
@@ -1225,9 +1327,9 @@ void Field::SerializeWithCachedSizes(
// optional string type_url = 6;
if (this->type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Field.type_url");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
6, this->type_url(), output);
@@ -1249,6 +1351,16 @@ void Field::SerializeWithCachedSizes(
9, this->options(i), output);
}
+ // optional string json_name = 10;
+ if (this->json_name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->json_name().data(), this->json_name().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.json_name");
+ ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+ 10, this->json_name(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Field)
}
@@ -1274,9 +1386,9 @@ void Field::SerializeWithCachedSizes(
// optional string name = 4;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Field.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1285,9 +1397,9 @@ void Field::SerializeWithCachedSizes(
// optional string type_url = 6;
if (this->type_url().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->type_url().data(), this->type_url().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Field.type_url");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1311,6 +1423,17 @@ void Field::SerializeWithCachedSizes(
9, this->options(i), target);
}
+ // optional string json_name = 10;
+ if (this->json_name().size() > 0) {
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+ this->json_name().data(), this->json_name().length(),
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+ "google.protobuf.Field.json_name");
+ target =
+ ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+ 10, this->json_name(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Field)
return target;
}
@@ -1363,6 +1486,13 @@ int Field::ByteSize() const {
total_size += 1 + 1;
}
+ // optional string json_name = 10;
+ if (this->json_name().size() > 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::StringSize(
+ this->json_name());
+ }
+
// repeated .google.protobuf.Option options = 9;
total_size += 1 * this->options_size();
for (int i = 0; i < this->options_size(); i++) {
@@ -1415,6 +1545,10 @@ void Field::MergeFrom(const Field& from) {
if (from.packed() != 0) {
set_packed(from.packed());
}
+ if (from.json_name().size() > 0) {
+
+ json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_);
+ }
}
void Field::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1447,6 +1581,7 @@ void Field::InternalSwap(Field* other) {
std::swap(oneof_index_, other->oneof_index_);
std::swap(packed_, other->packed_);
options_.UnsafeArenaSwap(&other->options_);
+ json_name_.Swap(&other->json_name_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -1625,27 +1760,70 @@ int Field::options_size() const {
void Field::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& Field::options(int index) const {
+const ::google::protobuf::Option& Field::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Field.options)
return options_.Get(index);
}
- ::google::protobuf::Option* Field::mutable_options(int index) {
+::google::protobuf::Option* Field::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Field.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* Field::add_options() {
+::google::protobuf::Option* Field::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Field.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+Field::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
+ return &options_;
+}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Field::options() const {
// @@protoc_insertion_point(field_list:google.protobuf.Field.options)
return options_;
}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
-Field::mutable_options() {
- // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
- return &options_;
+
+// optional string json_name = 10;
+void Field::clear_json_name() {
+ json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& Field::json_name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
+ return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_json_name(const ::std::string& value) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+ void Field::set_json_name(const char* value) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
+}
+ void Field::set_json_name(const char* value, size_t size) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
+}
+ ::std::string* Field::mutable_json_name() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
+ return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* Field::release_json_name() {
+
+ return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void Field::set_allocated_json_name(::std::string* json_name) {
+ if (json_name != NULL) {
+
+ } else {
+
+ }
+ json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -1657,6 +1835,7 @@ const int Enum::kNameFieldNumber;
const int Enum::kEnumvalueFieldNumber;
const int Enum::kOptionsFieldNumber;
const int Enum::kSourceContextFieldNumber;
+const int Enum::kSyntaxFieldNumber;
#endif // !_MSC_VER
Enum::Enum()
@@ -1684,6 +1863,7 @@ void Enum::SharedCtor() {
_cached_size_ = 0;
name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
source_context_ = NULL;
+ syntax_ = 0;
}
Enum::~Enum() {
@@ -1727,6 +1907,7 @@ void Enum::Clear() {
name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
+ syntax_ = 0;
enumvalue_.Clear();
options_.Clear();
}
@@ -1746,10 +1927,10 @@ bool Enum::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Enum.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Enum.name"));
} else {
goto handle_unusual;
}
@@ -1799,6 +1980,22 @@ bool Enum::MergePartialFromCodedStream(
} else {
goto handle_unusual;
}
+ if (input->ExpectTag(40)) goto parse_syntax;
+ break;
+ }
+
+ // optional .google.protobuf.Syntax syntax = 5;
+ case 5: {
+ if (tag == 40) {
+ parse_syntax:
+ int value;
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+ input, &value)));
+ set_syntax(static_cast< ::google::protobuf::Syntax >(value));
+ } else {
+ goto handle_unusual;
+ }
if (input->ExpectAtEnd()) goto success;
break;
}
@@ -1829,9 +2026,9 @@ void Enum::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Enum)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Enum.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -1855,6 +2052,12 @@ void Enum::SerializeWithCachedSizes(
4, *this->source_context_, output);
}
+ // optional .google.protobuf.Syntax syntax = 5;
+ if (this->syntax() != 0) {
+ ::google::protobuf::internal::WireFormatLite::WriteEnum(
+ 5, this->syntax(), output);
+ }
+
// @@protoc_insertion_point(serialize_end:google.protobuf.Enum)
}
@@ -1863,9 +2066,9 @@ void Enum::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Enum.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -1893,6 +2096,12 @@ void Enum::SerializeWithCachedSizes(
4, *this->source_context_, target);
}
+ // optional .google.protobuf.Syntax syntax = 5;
+ if (this->syntax() != 0) {
+ target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+ 5, this->syntax(), target);
+ }
+
// @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Enum)
return target;
}
@@ -1914,6 +2123,12 @@ int Enum::ByteSize() const {
*this->source_context_);
}
+ // optional .google.protobuf.Syntax syntax = 5;
+ if (this->syntax() != 0) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::EnumSize(this->syntax());
+ }
+
// repeated .google.protobuf.EnumValue enumvalue = 2;
total_size += 1 * this->enumvalue_size();
for (int i = 0; i < this->enumvalue_size(); i++) {
@@ -1959,6 +2174,9 @@ void Enum::MergeFrom(const Enum& from) {
if (from.has_source_context()) {
mutable_source_context()->::google::protobuf::SourceContext::MergeFrom(from.source_context());
}
+ if (from.syntax() != 0) {
+ set_syntax(from.syntax());
+ }
}
void Enum::CopyFrom(const ::google::protobuf::Message& from) {
@@ -1987,6 +2205,7 @@ void Enum::InternalSwap(Enum* other) {
enumvalue_.UnsafeArenaSwap(&other->enumvalue_);
options_.UnsafeArenaSwap(&other->options_);
std::swap(source_context_, other->source_context_);
+ std::swap(syntax_, other->syntax_);
_internal_metadata_.Swap(&other->_internal_metadata_);
std::swap(_cached_size_, other->_cached_size_);
}
@@ -2052,28 +2271,28 @@ int Enum::enumvalue_size() const {
void Enum::clear_enumvalue() {
enumvalue_.Clear();
}
- const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const {
+const ::google::protobuf::EnumValue& Enum::enumvalue(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Enum.enumvalue)
return enumvalue_.Get(index);
}
- ::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) {
+::google::protobuf::EnumValue* Enum::mutable_enumvalue(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Enum.enumvalue)
return enumvalue_.Mutable(index);
}
- ::google::protobuf::EnumValue* Enum::add_enumvalue() {
+::google::protobuf::EnumValue* Enum::add_enumvalue() {
// @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
return enumvalue_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
-Enum::enumvalue() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
- return enumvalue_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
Enum::mutable_enumvalue() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue)
return &enumvalue_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
+Enum::enumvalue() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
+ return enumvalue_;
+}
// repeated .google.protobuf.Option options = 3;
int Enum::options_size() const {
@@ -2082,28 +2301,28 @@ int Enum::options_size() const {
void Enum::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& Enum::options(int index) const {
+const ::google::protobuf::Option& Enum::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.Enum.options)
return options_.Get(index);
}
- ::google::protobuf::Option* Enum::mutable_options(int index) {
+::google::protobuf::Option* Enum::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.Enum.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* Enum::add_options() {
+::google::protobuf::Option* Enum::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Enum::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
- return options_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Enum::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options)
return &options_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Enum::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
+ return options_;
+}
// optional .google.protobuf.SourceContext source_context = 4;
bool Enum::has_source_context() const {
@@ -2113,11 +2332,11 @@ void Enum::clear_source_context() {
if (GetArenaNoVirtual() == NULL && source_context_ != NULL) delete source_context_;
source_context_ = NULL;
}
- const ::google::protobuf::SourceContext& Enum::source_context() const {
+const ::google::protobuf::SourceContext& Enum::source_context() const {
// @@protoc_insertion_point(field_get:google.protobuf.Enum.source_context)
return source_context_ != NULL ? *source_context_ : *default_instance_->source_context_;
}
- ::google::protobuf::SourceContext* Enum::mutable_source_context() {
+::google::protobuf::SourceContext* Enum::mutable_source_context() {
if (source_context_ == NULL) {
source_context_ = new ::google::protobuf::SourceContext;
@@ -2125,13 +2344,13 @@ void Enum::clear_source_context() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Enum.source_context)
return source_context_;
}
- ::google::protobuf::SourceContext* Enum::release_source_context() {
+::google::protobuf::SourceContext* Enum::release_source_context() {
::google::protobuf::SourceContext* temp = source_context_;
source_context_ = NULL;
return temp;
}
- void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
+void Enum::set_allocated_source_context(::google::protobuf::SourceContext* source_context) {
delete source_context_;
source_context_ = source_context;
if (source_context) {
@@ -2142,6 +2361,20 @@ void Enum::clear_source_context() {
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
}
+// optional .google.protobuf.Syntax syntax = 5;
+void Enum::clear_syntax() {
+ syntax_ = 0;
+}
+ ::google::protobuf::Syntax Enum::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+ void Enum::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
+}
+
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
// ===================================================================
@@ -2235,10 +2468,10 @@ bool EnumValue::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.EnumValue.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.EnumValue.name"));
} else {
goto handle_unusual;
}
@@ -2304,9 +2537,9 @@ void EnumValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.EnumValue)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.EnumValue.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -2331,9 +2564,9 @@ void EnumValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.EnumValue.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -2515,28 +2748,28 @@ int EnumValue::options_size() const {
void EnumValue::clear_options() {
options_.Clear();
}
- const ::google::protobuf::Option& EnumValue::options(int index) const {
+const ::google::protobuf::Option& EnumValue::options(int index) const {
// @@protoc_insertion_point(field_get:google.protobuf.EnumValue.options)
return options_.Get(index);
}
- ::google::protobuf::Option* EnumValue::mutable_options(int index) {
+::google::protobuf::Option* EnumValue::mutable_options(int index) {
// @@protoc_insertion_point(field_mutable:google.protobuf.EnumValue.options)
return options_.Mutable(index);
}
- ::google::protobuf::Option* EnumValue::add_options() {
+::google::protobuf::Option* EnumValue::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
return options_.Add();
}
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-EnumValue::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
- return options_;
-}
- ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
EnumValue::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options)
return &options_;
}
+const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+EnumValue::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
+ return options_;
+}
#endif // PROTOBUF_INLINE_NOT_IN_HEADERS
@@ -2632,10 +2865,10 @@ bool Option::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_name()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.Option.name");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.Option.name"));
} else {
goto handle_unusual;
}
@@ -2682,9 +2915,9 @@ void Option::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.Option)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Option.name");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->name(), output);
@@ -2704,9 +2937,9 @@ void Option::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option)
// optional string name = 1;
if (this->name().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->name().data(), this->name().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.Option.name");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
@@ -2860,11 +3093,11 @@ void Option::clear_value() {
if (GetArenaNoVirtual() == NULL && value_ != NULL) delete value_;
value_ = NULL;
}
- const ::google::protobuf::Any& Option::value() const {
+const ::google::protobuf::Any& Option::value() const {
// @@protoc_insertion_point(field_get:google.protobuf.Option.value)
return value_ != NULL ? *value_ : *default_instance_->value_;
}
- ::google::protobuf::Any* Option::mutable_value() {
+::google::protobuf::Any* Option::mutable_value() {
if (value_ == NULL) {
value_ = new ::google::protobuf::Any;
@@ -2872,13 +3105,13 @@ void Option::clear_value() {
// @@protoc_insertion_point(field_mutable:google.protobuf.Option.value)
return value_;
}
- ::google::protobuf::Any* Option::release_value() {
+::google::protobuf::Any* Option::release_value() {
::google::protobuf::Any* temp = value_;
value_ = NULL;
return temp;
}
- void Option::set_allocated_value(::google::protobuf::Any* value) {
+void Option::set_allocated_value(::google::protobuf::Any* value) {
delete value_;
value_ = value;
if (value) {
diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h
index c9952efa..deda9213 100644
--- a/src/google/protobuf/type.pb.h
+++ b/src/google/protobuf/type.pb.h
@@ -40,11 +40,11 @@ void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2ftype_2eproto();
-class Type;
-class Field;
class Enum;
class EnumValue;
+class Field;
class Option;
+class Type;
enum Field_Kind {
Field_Kind_TYPE_UNKNOWN = 0,
@@ -57,6 +57,7 @@ enum Field_Kind {
Field_Kind_TYPE_FIXED32 = 7,
Field_Kind_TYPE_BOOL = 8,
Field_Kind_TYPE_STRING = 9,
+ Field_Kind_TYPE_GROUP = 10,
Field_Kind_TYPE_MESSAGE = 11,
Field_Kind_TYPE_BYTES = 12,
Field_Kind_TYPE_UINT32 = 13,
@@ -106,6 +107,27 @@ inline bool Field_Cardinality_Parse(
return ::google::protobuf::internal::ParseNamedEnum<Field_Cardinality>(
Field_Cardinality_descriptor(), name, value);
}
+enum Syntax {
+ SYNTAX_PROTO2 = 0,
+ SYNTAX_PROTO3 = 1,
+ Syntax_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
+ Syntax_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
+};
+LIBPROTOBUF_EXPORT bool Syntax_IsValid(int value);
+const Syntax Syntax_MIN = SYNTAX_PROTO2;
+const Syntax Syntax_MAX = SYNTAX_PROTO3;
+const int Syntax_ARRAYSIZE = Syntax_MAX + 1;
+
+LIBPROTOBUF_EXPORT const ::google::protobuf::EnumDescriptor* Syntax_descriptor();
+inline const ::std::string& Syntax_Name(Syntax value) {
+ return ::google::protobuf::internal::NameOfEnum(
+ Syntax_descriptor(), value);
+}
+inline bool Syntax_Parse(
+ const ::std::string& name, Syntax* value) {
+ return ::google::protobuf::internal::ParseNamedEnum<Syntax>(
+ Syntax_descriptor(), name, value);
+}
// ===================================================================
class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
@@ -182,10 +204,10 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
const ::google::protobuf::Field& fields(int index) const;
::google::protobuf::Field* mutable_fields(int index);
::google::protobuf::Field* add_fields();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
- fields() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
mutable_fields();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
+ fields() const;
// repeated string oneofs = 3;
int oneofs_size() const;
@@ -210,10 +232,10 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
// optional .google.protobuf.SourceContext source_context = 5;
bool has_source_context() const;
@@ -224,6 +246,12 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
::google::protobuf::SourceContext* release_source_context();
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
+ // optional .google.protobuf.Syntax syntax = 6;
+ void clear_syntax();
+ static const int kSyntaxFieldNumber = 6;
+ ::google::protobuf::Syntax syntax() const;
+ void set_syntax(::google::protobuf::Syntax value);
+
// @@protoc_insertion_point(class_scope:google.protobuf.Type)
private:
@@ -234,6 +262,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message {
::google::protobuf::RepeatedPtrField< ::std::string> oneofs_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
::google::protobuf::SourceContext* source_context_;
+ int syntax_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
@@ -309,6 +338,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
static const Kind TYPE_FIXED32 = Field_Kind_TYPE_FIXED32;
static const Kind TYPE_BOOL = Field_Kind_TYPE_BOOL;
static const Kind TYPE_STRING = Field_Kind_TYPE_STRING;
+ static const Kind TYPE_GROUP = Field_Kind_TYPE_GROUP;
static const Kind TYPE_MESSAGE = Field_Kind_TYPE_MESSAGE;
static const Kind TYPE_BYTES = Field_Kind_TYPE_BYTES;
static const Kind TYPE_UINT32 = Field_Kind_TYPE_UINT32;
@@ -425,10 +455,21 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
+
+ // optional string json_name = 10;
+ void clear_json_name();
+ static const int kJsonNameFieldNumber = 10;
+ const ::std::string& json_name() const;
+ void set_json_name(const ::std::string& value);
+ void set_json_name(const char* value);
+ void set_json_name(const char* value, size_t size);
+ ::std::string* mutable_json_name();
+ ::std::string* release_json_name();
+ void set_allocated_json_name(::std::string* json_name);
// @@protoc_insertion_point(class_scope:google.protobuf.Field)
private:
@@ -442,6 +483,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message {
::google::protobuf::int32 oneof_index_;
::google::protobuf::internal::ArenaStringPtr type_url_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
+ ::google::protobuf::internal::ArenaStringPtr json_name_;
bool packed_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
@@ -527,10 +569,10 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
const ::google::protobuf::EnumValue& enumvalue(int index) const;
::google::protobuf::EnumValue* mutable_enumvalue(int index);
::google::protobuf::EnumValue* add_enumvalue();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
- enumvalue() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
mutable_enumvalue();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
+ enumvalue() const;
// repeated .google.protobuf.Option options = 3;
int options_size() const;
@@ -539,10 +581,10 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
// optional .google.protobuf.SourceContext source_context = 4;
bool has_source_context() const;
@@ -553,6 +595,12 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
::google::protobuf::SourceContext* release_source_context();
void set_allocated_source_context(::google::protobuf::SourceContext* source_context);
+ // optional .google.protobuf.Syntax syntax = 5;
+ void clear_syntax();
+ static const int kSyntaxFieldNumber = 5;
+ ::google::protobuf::Syntax syntax() const;
+ void set_syntax(::google::protobuf::Syntax value);
+
// @@protoc_insertion_point(class_scope:google.protobuf.Enum)
private:
@@ -562,6 +610,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message {
::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue > enumvalue_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option > options_;
::google::protobuf::SourceContext* source_context_;
+ int syntax_;
mutable int _cached_size_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2ftype_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2ftype_2eproto();
@@ -652,10 +701,10 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message {
const ::google::protobuf::Option& options(int index) const;
::google::protobuf::Option* mutable_options(int index);
::google::protobuf::Option* add_options();
- const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
- options() const;
::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
mutable_options();
+ const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+ options() const;
// @@protoc_insertion_point(class_scope:google.protobuf.EnumValue)
private:
@@ -836,16 +885,16 @@ inline ::google::protobuf::Field* Type::add_fields() {
// @@protoc_insertion_point(field_add:google.protobuf.Type.fields)
return fields_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
-Type::fields() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
- return fields_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >*
Type::mutable_fields() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.fields)
return &fields_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Field >&
+Type::fields() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.fields)
+ return fields_;
+}
// repeated string oneofs = 3;
inline int Type::oneofs_size() const {
@@ -920,16 +969,16 @@ inline ::google::protobuf::Option* Type::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Type.options)
return options_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Type::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
- return options_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Type::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Type.options)
return &options_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Type::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Type.options)
+ return options_;
+}
// optional .google.protobuf.SourceContext source_context = 5;
inline bool Type::has_source_context() const {
@@ -968,6 +1017,20 @@ inline void Type::set_allocated_source_context(::google::protobuf::SourceContext
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Type.source_context)
}
+// optional .google.protobuf.Syntax syntax = 6;
+inline void Type::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Type::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Type.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Type::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Type.syntax)
+}
+
// -------------------------------------------------------------------
// Field
@@ -1147,15 +1210,58 @@ inline ::google::protobuf::Option* Field::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Field.options)
return options_.Add();
}
+inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
+Field::mutable_options() {
+ // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
+ return &options_;
+}
inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
Field::options() const {
// @@protoc_insertion_point(field_list:google.protobuf.Field.options)
return options_;
}
-inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
-Field::mutable_options() {
- // @@protoc_insertion_point(field_mutable_list:google.protobuf.Field.options)
- return &options_;
+
+// optional string json_name = 10;
+inline void Field::clear_json_name() {
+ json_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& Field::json_name() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Field.json_name)
+ return json_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_json_name(const ::std::string& value) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+ // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name)
+}
+inline void Field::set_json_name(const char* value) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+ // @@protoc_insertion_point(field_set_char:google.protobuf.Field.json_name)
+}
+inline void Field::set_json_name(const char* value, size_t size) {
+
+ json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+ ::std::string(reinterpret_cast<const char*>(value), size));
+ // @@protoc_insertion_point(field_set_pointer:google.protobuf.Field.json_name)
+}
+inline ::std::string* Field::mutable_json_name() {
+
+ // @@protoc_insertion_point(field_mutable:google.protobuf.Field.json_name)
+ return json_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* Field::release_json_name() {
+
+ return json_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void Field::set_allocated_json_name(::std::string* json_name) {
+ if (json_name != NULL) {
+
+ } else {
+
+ }
+ json_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), json_name);
+ // @@protoc_insertion_point(field_set_allocated:google.protobuf.Field.json_name)
}
// -------------------------------------------------------------------
@@ -1224,16 +1330,16 @@ inline ::google::protobuf::EnumValue* Enum::add_enumvalue() {
// @@protoc_insertion_point(field_add:google.protobuf.Enum.enumvalue)
return enumvalue_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
-Enum::enumvalue() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
- return enumvalue_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >*
Enum::mutable_enumvalue() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.enumvalue)
return &enumvalue_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumValue >&
+Enum::enumvalue() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.enumvalue)
+ return enumvalue_;
+}
// repeated .google.protobuf.Option options = 3;
inline int Enum::options_size() const {
@@ -1254,16 +1360,16 @@ inline ::google::protobuf::Option* Enum::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.Enum.options)
return options_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-Enum::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
- return options_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
Enum::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.Enum.options)
return &options_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+Enum::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.Enum.options)
+ return options_;
+}
// optional .google.protobuf.SourceContext source_context = 4;
inline bool Enum::has_source_context() const {
@@ -1302,6 +1408,20 @@ inline void Enum::set_allocated_source_context(::google::protobuf::SourceContext
// @@protoc_insertion_point(field_set_allocated:google.protobuf.Enum.source_context)
}
+// optional .google.protobuf.Syntax syntax = 5;
+inline void Enum::clear_syntax() {
+ syntax_ = 0;
+}
+inline ::google::protobuf::Syntax Enum::syntax() const {
+ // @@protoc_insertion_point(field_get:google.protobuf.Enum.syntax)
+ return static_cast< ::google::protobuf::Syntax >(syntax_);
+}
+inline void Enum::set_syntax(::google::protobuf::Syntax value) {
+
+ syntax_ = value;
+ // @@protoc_insertion_point(field_set:google.protobuf.Enum.syntax)
+}
+
// -------------------------------------------------------------------
// EnumValue
@@ -1382,16 +1502,16 @@ inline ::google::protobuf::Option* EnumValue::add_options() {
// @@protoc_insertion_point(field_add:google.protobuf.EnumValue.options)
return options_.Add();
}
-inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
-EnumValue::options() const {
- // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
- return options_;
-}
inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >*
EnumValue::mutable_options() {
// @@protoc_insertion_point(field_mutable_list:google.protobuf.EnumValue.options)
return &options_;
}
+inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::Option >&
+EnumValue::options() const {
+ // @@protoc_insertion_point(field_list:google.protobuf.EnumValue.options)
+ return options_;
+}
// -------------------------------------------------------------------
@@ -1506,6 +1626,11 @@ template <>
inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Field_Cardinality>() {
return ::google::protobuf::Field_Cardinality_descriptor();
}
+template <> struct is_proto_enum< ::google::protobuf::Syntax> : ::google::protobuf::internal::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::google::protobuf::Syntax>() {
+ return ::google::protobuf::Syntax_descriptor();
+}
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/type.proto b/src/google/protobuf/type.proto
index ce22d33d..4df95762 100644
--- a/src/google/protobuf/type.proto
+++ b/src/google/protobuf/type.proto
@@ -34,30 +34,27 @@ package google.protobuf;
import "google/protobuf/any.proto";
import "google/protobuf/source_context.proto";
-option java_multiple_files = true;
-option java_outer_classname = "TypeProto";
option java_package = "com.google.protobuf";
+option java_outer_classname = "TypeProto";
+option java_multiple_files = true;
+option java_generate_equals_and_hash = true;
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
// A light-weight descriptor for a proto message type.
message Type {
// The fully qualified message name.
string name = 1;
-
// The list of fields.
repeated Field fields = 2;
-
// The list of oneof definitions.
- // The list of oneofs declared in this Type
- repeated string oneofs = 3;
-
+ repeated string oneofs = 3; // The list of oneofs declared in this Type
// The proto options.
repeated Option options = 4;
-
// The source context.
SourceContext source_context = 5;
+ // The source syntax.
+ Syntax syntax = 6;
}
// Field represents a single field of a message type.
@@ -65,125 +62,99 @@ message Field {
// Kind represents a basic field type.
enum Kind {
// Field type unknown.
- TYPE_UNKNOWN = 0;
-
+ TYPE_UNKNOWN = 0;
// Field type double.
- TYPE_DOUBLE = 1;
-
+ TYPE_DOUBLE = 1;
// Field type float.
- TYPE_FLOAT = 2;
-
+ TYPE_FLOAT = 2;
// Field type int64.
- TYPE_INT64 = 3;
-
+ TYPE_INT64 = 3;
// Field type uint64.
- TYPE_UINT64 = 4;
-
+ TYPE_UINT64 = 4;
// Field type int32.
- TYPE_INT32 = 5;
-
+ TYPE_INT32 = 5;
// Field type fixed64.
- TYPE_FIXED64 = 6;
-
+ TYPE_FIXED64 = 6;
// Field type fixed32.
- TYPE_FIXED32 = 7;
-
+ TYPE_FIXED32 = 7;
// Field type bool.
- TYPE_BOOL = 8;
-
+ TYPE_BOOL = 8;
// Field type string.
- TYPE_STRING = 9;
-
+ TYPE_STRING = 9;
+ // Field type group (deprecated proto2 type)
+ TYPE_GROUP = 10;
// Field type message.
- TYPE_MESSAGE = 11;
-
+ TYPE_MESSAGE = 11;
// Field type bytes.
- TYPE_BYTES = 12;
-
+ TYPE_BYTES = 12;
// Field type uint32.
- TYPE_UINT32 = 13;
-
+ TYPE_UINT32 = 13;
// Field type enum.
- TYPE_ENUM = 14;
-
+ TYPE_ENUM = 14;
// Field type sfixed32.
- TYPE_SFIXED32 = 15;
-
+ TYPE_SFIXED32 = 15;
// Field type sfixed64.
- TYPE_SFIXED64 = 16;
-
+ TYPE_SFIXED64 = 16;
// Field type sint32.
- TYPE_SINT32 = 17;
-
+ TYPE_SINT32 = 17;
// Field type sint64.
- TYPE_SINT64 = 18;
- }
+ TYPE_SINT64 = 18;
+ };
// Cardinality represents whether a field is optional, required, or
// repeated.
enum Cardinality {
// The field cardinality is unknown. Typically an error condition.
CARDINALITY_UNKNOWN = 0;
-
// For optional fields.
CARDINALITY_OPTIONAL = 1;
-
// For required fields. Not used for proto3.
CARDINALITY_REQUIRED = 2;
-
// For repeated fields.
CARDINALITY_REPEATED = 3;
- }
+ };
// The field kind.
Kind kind = 1;
-
// The field cardinality, i.e. optional/required/repeated.
Cardinality cardinality = 2;
-
// The proto field number.
int32 number = 3;
-
// The field name.
string name = 4;
-
// The type URL (without the scheme) when the type is MESSAGE or ENUM,
// such as `type.googleapis.com/google.protobuf.Empty`.
string type_url = 6;
-
// Index in Type.oneofs. Starts at 1. Zero means no oneof mapping.
int32 oneof_index = 7;
-
// Whether to use alternative packed wire representation.
bool packed = 8;
-
// The proto options.
repeated Option options = 9;
+ // The JSON name for this field.
+ string json_name = 10;
}
// Enum type definition.
message Enum {
// Enum type name.
string name = 1;
-
// Enum value definitions.
repeated EnumValue enumvalue = 2;
-
// Proto options for the enum type.
repeated Option options = 3;
-
// The source context.
SourceContext source_context = 4;
+ // The source syntax.
+ Syntax syntax = 5;
}
// Enum value definition.
message EnumValue {
// Enum value name.
string name = 1;
-
// Enum value number.
int32 number = 2;
-
// Proto options for the enum value.
repeated Option options = 3;
}
@@ -192,7 +163,14 @@ message EnumValue {
message Option {
// Proto option name.
string name = 1;
-
// Proto option value.
Any value = 2;
}
+
+// Syntax specifies the syntax in which a service element was defined.
+enum Syntax {
+ // Syntax "proto2"
+ SYNTAX_PROTO2 = 0;
+ // Syntax "proto3"
+ SYNTAX_PROTO3 = 1;
+}
diff --git a/src/google/protobuf/unittest_mset.proto b/src/google/protobuf/unittest_mset.proto
index 3aa31fa9..49d9adad 100644
--- a/src/google/protobuf/unittest_mset.proto
+++ b/src/google/protobuf/unittest_mset.proto
@@ -32,33 +32,31 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
//
-// This file contains messages for testing message_set_wire_format.
+// This file is similar to unittest_mset_wire_format.proto, but does not
+// have a TestMessageSet, so it can be downgraded to proto1.
syntax = "proto2";
+
+import "google/protobuf/unittest_mset_wire_format.proto";
+
package protobuf_unittest;
option cc_enable_arenas = true;
option optimize_for = SPEED;
-// A message with message_set_wire_format.
-message TestMessageSet {
- option message_set_wire_format = true;
- extensions 4 to max;
-}
-
message TestMessageSetContainer {
- optional TestMessageSet message_set = 1;
+ optional proto2_wireformat_unittest.TestMessageSet message_set = 1;
}
message TestMessageSetExtension1 {
- extend TestMessageSet {
+ extend proto2_wireformat_unittest.TestMessageSet {
optional TestMessageSetExtension1 message_set_extension = 1545008;
}
optional int32 i = 15;
}
message TestMessageSetExtension2 {
- extend TestMessageSet {
+ extend proto2_wireformat_unittest.TestMessageSet {
optional TestMessageSetExtension2 message_set_extension = 1547769;
}
optional string str = 25;
@@ -82,4 +80,3 @@ message RawMessageSet {
required bytes message = 3;
}
}
-
diff --git a/src/google/protobuf/unittest_mset_wire_format.proto b/src/google/protobuf/unittest_mset_wire_format.proto
new file mode 100644
index 00000000..04e4352e
--- /dev/null
+++ b/src/google/protobuf/unittest_mset_wire_format.proto
@@ -0,0 +1,52 @@
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+// Based on original Protocol Buffers design by
+// Sanjay Ghemawat, Jeff Dean, and others.
+//
+// This file contains messages for testing message_set_wire_format.
+
+syntax = "proto2";
+package proto2_wireformat_unittest;
+
+option cc_enable_arenas = true;
+option optimize_for = SPEED;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+
+// A message with message_set_wire_format.
+message TestMessageSet {
+ option message_set_wire_format = true;
+ extensions 4 to max;
+}
+
+message TestMessageSetWireFormatContainer {
+ optional TestMessageSet message_set = 1;
+}
diff --git a/src/google/protobuf/unittest_no_arena.proto b/src/google/protobuf/unittest_no_arena.proto
index 36fb8656..41518df2 100644
--- a/src/google/protobuf/unittest_no_arena.proto
+++ b/src/google/protobuf/unittest_no_arena.proto
@@ -44,6 +44,7 @@ option cc_generic_services = true; // auto-added
option java_generic_services = true; // auto-added
option py_generic_services = true; // auto-added
option cc_enable_arenas = false;
+option objc_class_prefix = "NOARN";
import "google/protobuf/unittest_import.proto";
import "google/protobuf/unittest_arena.proto";
diff --git a/src/google/protobuf/unittest_no_arena_lite.proto b/src/google/protobuf/unittest_no_arena_lite.proto
new file mode 100644
index 00000000..34c7b7ce
--- /dev/null
+++ b/src/google/protobuf/unittest_no_arena_lite.proto
@@ -0,0 +1,42 @@
+// 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.
+
+syntax = "proto2";
+
+option optimize_for = LITE_RUNTIME;
+
+// We don't put this in a package within proto2 because we need to make sure
+// that the generated code doesn't depend on being in the proto2 namespace.
+// In test_util.h we do "using namespace unittest = protobuf_unittest".
+package protobuf_unittest_no_arena;
+
+message ForeignMessageLite {
+ optional int32 c = 1;
+}
diff --git a/src/google/protobuf/unknown_enum_impl.h b/src/google/protobuf/unknown_enum_impl.h
index 39c10cbc..7c68ad6c 100644
--- a/src/google/protobuf/unknown_enum_impl.h
+++ b/src/google/protobuf/unknown_enum_impl.h
@@ -34,7 +34,6 @@
#include <stdlib.h>
#include <google/protobuf/stubs/common.h>
-#include "net/proto/tagmapper.h"
#include <google/protobuf/bridge/compatibility_mode_support.h>
namespace google {
@@ -59,10 +58,10 @@ namespace util {
// In proto2, invalid enum values will be treated as unknown fields. This
// function checks that case.
bool HasUnknownEnum(const Message& message, int32 field_number,
- int32* unknown_value = nullptr);
+ int32* unknown_value = NULL);
// Same as above, but returns all unknown enums.
bool GetRepeatedEnumUnknowns(const Message& message, int32 field_number,
- vector<int32>* unknown_values = nullptr);
+ vector<int32>* unknown_values = NULL);
// In proto1, invalue enum values are stored in the same way as valid enum
// values.
// TODO(karner): Delete this once the migration to proto2 is complete.
@@ -75,7 +74,7 @@ bool GetRepeatedEnumUnknownsProto1(const Message& message, int32 field_number,
// or proto2.
template <typename T>
bool HasUnknownEnum_Template(const T& message, int32 field_number,
- int32* unknown_value = nullptr) {
+ int32* unknown_value = NULL) {
if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
!internal::is_base_of<ProtocolMessage, T>::value) {
return HasUnknownEnum(message, field_number, unknown_value);
@@ -88,7 +87,7 @@ bool HasUnknownEnum_Template(const T& message, int32 field_number,
template <typename T>
bool GetRepeatedEnumUnknowns_Template(
const T& message, int32 field_number,
- vector<int32>* unknown_values = nullptr) {
+ vector<int32>* unknown_values = NULL) {
if (internal::is_base_of<bridge::internal::Proto1CompatibleMessage, T>::value ||
!internal::is_base_of<ProtocolMessage, T>::value) {
return GetRepeatedEnumUnknowns(message, field_number, unknown_values);
diff --git a/src/google/protobuf/unknown_enum_test.proto b/src/google/protobuf/unknown_enum_test.proto
index 0ea1ede3..3c549cc7 100644
--- a/src/google/protobuf/unknown_enum_test.proto
+++ b/src/google/protobuf/unknown_enum_test.proto
@@ -36,6 +36,8 @@ syntax = "proto2";
package google.protobuf.util;
+option csharp_namespace = "Google.ProtocolBuffers.TestProtos";
+
message DownRevision {
enum Enum {
DEFAULT_VALUE = 2;
diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc
index 93f0f206..d4e383da 100644
--- a/src/google/protobuf/unknown_field_set.cc
+++ b/src/google/protobuf/unknown_field_set.cc
@@ -34,6 +34,7 @@
#include <google/protobuf/unknown_field_set.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream.h>
diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h
index 6781cd0f..612a942a 100644
--- a/src/google/protobuf/unknown_field_set.h
+++ b/src/google/protobuf/unknown_field_set.h
@@ -42,6 +42,7 @@
#include <string>
#include <vector>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/unknown_field_set_unittest.cc b/src/google/protobuf/unknown_field_set_unittest.cc
index 9b02f0b0..5de72630 100644
--- a/src/google/protobuf/unknown_field_set_unittest.cc
+++ b/src/google/protobuf/unknown_field_set_unittest.cc
@@ -43,7 +43,10 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/mutex.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/stubs/stl_util.h>
diff --git a/src/google/protobuf/util/field_comparator_test.cc b/src/google/protobuf/util/field_comparator_test.cc
index 748c7d11..845839ac 100644
--- a/src/google/protobuf/util/field_comparator_test.cc
+++ b/src/google/protobuf/util/field_comparator_test.cc
@@ -34,8 +34,8 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/descriptor.h>
-#include <gtest/gtest.h>
#include <google/protobuf/stubs/mathutil.h>
+#include <gtest/gtest.h>
namespace google {
namespace protobuf {
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
new file mode 100644
index 00000000..82034bd4
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -0,0 +1,418 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/field_mask_util.h>
+
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/map_util.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::FieldMask;
+
+string FieldMaskUtil::ToString(const FieldMask& mask) {
+ return Join(mask.paths(), ",");
+}
+
+void FieldMaskUtil::FromString(const string& str, FieldMask* out) {
+ out->Clear();
+ vector<string> paths = Split(str, ",");
+ for (int i = 0; i < paths.size(); ++i) {
+ if (paths[i].empty()) continue;
+ out->add_paths(paths[i]);
+ }
+}
+
+bool FieldMaskUtil::InternalIsValidPath(const Descriptor* descriptor,
+ const string& path) {
+ vector<string> parts = Split(path, ".");
+ for (int i = 0; i < parts.size(); ++i) {
+ const string& field_name = parts[i];
+ if (descriptor == NULL) {
+ return false;
+ }
+ const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
+ if (field == NULL) {
+ return false;
+ }
+ if (!field->is_repeated() &&
+ field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ descriptor = field->message_type();
+ } else {
+ descriptor = NULL;
+ }
+ }
+ return true;
+}
+
+void FieldMaskUtil::InternalGetFieldMaskForAllFields(
+ const Descriptor* descriptor, FieldMask* out) {
+ for (int i = 0; i < descriptor->field_count(); ++i) {
+ out->add_paths(descriptor->field(i)->name());
+ }
+}
+
+namespace {
+// A FieldMaskTree represents a FieldMask in a tree structure. For example,
+// given a FieldMask "foo.bar,foo.baz,bar.baz", the FieldMaskTree will be:
+//
+// [root] -+- foo -+- bar
+// | |
+// | +- baz
+// |
+// +- bar --- baz
+//
+// In the tree, each leaf node represents a field path.
+class FieldMaskTree {
+ public:
+ FieldMaskTree();
+ ~FieldMaskTree();
+
+ void MergeFromFieldMask(const FieldMask& mask);
+ void MergeToFieldMask(FieldMask* mask);
+
+ // Add a field path into the tree. In a FieldMask, each field path matches
+ // the specified field and also all its sub-fields. If the field path to
+ // add is a sub-path of an existing field path in the tree (i.e., a leaf
+ // node), it means the tree already matchesthe the given path so nothing will
+ // be added to the tree. If the path matches an existing non-leaf node in the
+ // tree, that non-leaf node will be turned into a leaf node with all its
+ // children removed because the path matches all the node's children.
+ void AddPath(const string& path);
+
+ // Calculate the intersection part of a field path with this tree and add
+ // the intersection field path into out.
+ void IntersectPath(const string& path, FieldMaskTree* out);
+
+ // Merge all fields specified by this tree from one message to another.
+ void MergeMessage(const Message& source,
+ const FieldMaskUtil::MergeOptions& options,
+ Message* destination) {
+ // Do nothing if the tree is empty.
+ if (root_.children.empty()) {
+ return;
+ }
+ MergeMessage(&root_, source, options, destination);
+ }
+
+ private:
+ struct Node {
+ Node() {}
+
+ ~Node() { ClearChildren(); }
+
+ void ClearChildren() {
+ for (map<string, Node*>::iterator it = children.begin();
+ it != children.end(); ++it) {
+ delete it->second;
+ }
+ children.clear();
+ }
+
+ map<string, Node*> children;
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node);
+ };
+
+ // Merge a sub-tree to mask. This method adds the field paths represented
+ // by all leaf nodes descended from "node" to mask.
+ void MergeToFieldMask(const string& prefix, const Node* node, FieldMask* out);
+
+ // Merge all leaf nodes of a sub-tree to another tree.
+ void MergeLeafNodesToTree(const string& prefix, const Node* node,
+ FieldMaskTree* out);
+
+ // Merge all fields specified by a sub-tree from one message to another.
+ void MergeMessage(const Node* node, const Message& source,
+ const FieldMaskUtil::MergeOptions& options,
+ Message* destination);
+
+ Node root_;
+
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldMaskTree);
+};
+
+FieldMaskTree::FieldMaskTree() {}
+
+FieldMaskTree::~FieldMaskTree() {}
+
+void FieldMaskTree::MergeFromFieldMask(const FieldMask& mask) {
+ for (int i = 0; i < mask.paths_size(); ++i) {
+ AddPath(mask.paths(i));
+ }
+}
+
+void FieldMaskTree::MergeToFieldMask(FieldMask* mask) {
+ MergeToFieldMask("", &root_, mask);
+}
+
+void FieldMaskTree::MergeToFieldMask(const string& prefix, const Node* node,
+ FieldMask* out) {
+ if (node->children.empty()) {
+ if (prefix.empty()) {
+ // This is the root node.
+ return;
+ }
+ out->add_paths(prefix);
+ return;
+ }
+ for (map<string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
+ MergeToFieldMask(current_path, it->second, out);
+ }
+}
+
+void FieldMaskTree::AddPath(const string& path) {
+ vector<string> parts = Split(path, ".");
+ if (parts.empty()) {
+ return;
+ }
+ bool new_branch = false;
+ Node* node = &root_;
+ for (int i = 0; i < parts.size(); ++i) {
+ if (!new_branch && node != &root_ && node->children.empty()) {
+ // Path matches an existing leaf node. This means the path is already
+ // coverred by this tree (for example, adding "foo.bar.baz" to a tree
+ // which already contains "foo.bar").
+ return;
+ }
+ const string& node_name = parts[i];
+ Node*& child = node->children[node_name];
+ if (child == NULL) {
+ new_branch = true;
+ child = new Node();
+ }
+ node = child;
+ }
+ if (!node->children.empty()) {
+ node->ClearChildren();
+ }
+}
+
+void FieldMaskTree::IntersectPath(const string& path, FieldMaskTree* out) {
+ vector<string> parts = Split(path, ".");
+ if (parts.empty()) {
+ return;
+ }
+ const Node* node = &root_;
+ for (int i = 0; i < parts.size(); ++i) {
+ if (node->children.empty()) {
+ if (node != &root_) {
+ out->AddPath(path);
+ }
+ return;
+ }
+ const string& node_name = parts[i];
+ const Node* result = FindPtrOrNull(node->children, node_name);
+ if (result == NULL) {
+ // No intersection found.
+ return;
+ }
+ node = result;
+ }
+ // Now we found a matching node with the given path. Add all leaf nodes
+ // to out.
+ MergeLeafNodesToTree(path, node, out);
+}
+
+void FieldMaskTree::MergeLeafNodesToTree(const string& prefix, const Node* node,
+ FieldMaskTree* out) {
+ if (node->children.empty()) {
+ out->AddPath(prefix);
+ }
+ for (map<string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ string current_path = prefix.empty() ? it->first : prefix + "." + it->first;
+ MergeLeafNodesToTree(current_path, it->second, out);
+ }
+}
+
+void FieldMaskTree::MergeMessage(const Node* node, const Message& source,
+ const FieldMaskUtil::MergeOptions& options,
+ Message* destination) {
+ GOOGLE_DCHECK(!node->children.empty());
+ const Reflection* source_reflection = source.GetReflection();
+ const Reflection* destination_reflection = destination->GetReflection();
+ const Descriptor* descriptor = source.GetDescriptor();
+ for (map<string, Node*>::const_iterator it = node->children.begin();
+ it != node->children.end(); ++it) {
+ const string& field_name = it->first;
+ const Node* child = it->second;
+ const FieldDescriptor* field = descriptor->FindFieldByName(field_name);
+ if (field == NULL) {
+ GOOGLE_LOG(ERROR) << "Cannot find field \"" << field_name << "\" in message "
+ << descriptor->full_name();
+ continue;
+ }
+ if (!child->children.empty()) {
+ // Sub-paths are only allowed for singular message fields.
+ if (field->is_repeated() ||
+ field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
+ GOOGLE_LOG(ERROR) << "Field \"" << field_name << "\" in message "
+ << descriptor->full_name()
+ << " is not a singular message field and cannot "
+ << "have sub-fields.";
+ continue;
+ }
+ MergeMessage(child, source_reflection->GetMessage(source, field), options,
+ destination_reflection->MutableMessage(destination, field));
+ continue;
+ }
+ if (!field->is_repeated()) {
+ switch (field->cpp_type()) {
+#define COPY_VALUE(TYPE, Name) \
+ case FieldDescriptor::CPPTYPE_##TYPE: { \
+ destination_reflection->Set##Name( \
+ destination, field, source_reflection->Get##Name(source, field)); \
+ break; \
+ }
+ COPY_VALUE(BOOL, Bool)
+ COPY_VALUE(INT32, Int32)
+ COPY_VALUE(INT64, Int64)
+ COPY_VALUE(UINT32, UInt32)
+ COPY_VALUE(UINT64, UInt64)
+ COPY_VALUE(FLOAT, Float)
+ COPY_VALUE(DOUBLE, Double)
+ COPY_VALUE(ENUM, Enum)
+ COPY_VALUE(STRING, String)
+#undef COPY_VALUE
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ if (options.replace_message_fields()) {
+ destination_reflection->ClearField(destination, field);
+ }
+ if (source_reflection->HasField(source, field)) {
+ destination_reflection->MutableMessage(destination, field)
+ ->MergeFrom(source_reflection->GetMessage(source, field));
+ }
+ break;
+ }
+ }
+ } else {
+ if (options.replace_repeated_fields()) {
+ destination_reflection->ClearField(destination, field);
+ }
+ switch (field->cpp_type()) {
+#define COPY_REPEATED_VALUE(TYPE, Name) \
+ case FieldDescriptor::CPPTYPE_##TYPE: { \
+ int size = source_reflection->FieldSize(source, field); \
+ for (int i = 0; i < size; ++i) { \
+ destination_reflection->Add##Name( \
+ destination, field, \
+ source_reflection->GetRepeated##Name(source, field, i)); \
+ } \
+ break; \
+ }
+ COPY_REPEATED_VALUE(BOOL, Bool)
+ COPY_REPEATED_VALUE(INT32, Int32)
+ COPY_REPEATED_VALUE(INT64, Int64)
+ COPY_REPEATED_VALUE(UINT32, UInt32)
+ COPY_REPEATED_VALUE(UINT64, UInt64)
+ COPY_REPEATED_VALUE(FLOAT, Float)
+ COPY_REPEATED_VALUE(DOUBLE, Double)
+ COPY_REPEATED_VALUE(ENUM, Enum)
+ COPY_REPEATED_VALUE(STRING, String)
+#undef COPY_REPEATED_VALUE
+ case FieldDescriptor::CPPTYPE_MESSAGE: {
+ int size = source_reflection->FieldSize(source, field);
+ for (int i = 0; i < size; ++i) {
+ destination_reflection->AddMessage(destination, field)
+ ->MergeFrom(
+ source_reflection->GetRepeatedMessage(source, field, i));
+ }
+ break;
+ }
+ }
+ }
+ }
+}
+
+} // namespace
+
+void FieldMaskUtil::ToCanonicalForm(const FieldMask& mask, FieldMask* out) {
+ FieldMaskTree tree;
+ tree.MergeFromFieldMask(mask);
+ out->Clear();
+ tree.MergeToFieldMask(out);
+}
+
+void FieldMaskUtil::Union(const FieldMask& mask1, const FieldMask& mask2,
+ FieldMask* out) {
+ FieldMaskTree tree;
+ tree.MergeFromFieldMask(mask1);
+ tree.MergeFromFieldMask(mask2);
+ out->Clear();
+ tree.MergeToFieldMask(out);
+}
+
+void FieldMaskUtil::Intersect(const FieldMask& mask1, const FieldMask& mask2,
+ FieldMask* out) {
+ FieldMaskTree tree, intersection;
+ tree.MergeFromFieldMask(mask1);
+ for (int i = 0; i < mask2.paths_size(); ++i) {
+ tree.IntersectPath(mask2.paths(i), &intersection);
+ }
+ out->Clear();
+ intersection.MergeToFieldMask(out);
+}
+
+bool FieldMaskUtil::IsPathInFieldMask(const string& path,
+ const FieldMask& mask) {
+ for (int i = 0; i < mask.paths_size(); ++i) {
+ const string& mask_path = mask.paths(i);
+ if (path == mask_path) {
+ return true;
+ } else if (mask_path.length() < path.length()) {
+ // Also check whether mask.paths(i) is a prefix of path.
+ if (path.compare(0, mask_path.length() + 1, mask_path + ".") == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void FieldMaskUtil::MergeMessageTo(const Message& source, const FieldMask& mask,
+ const MergeOptions& options,
+ Message* destination) {
+ GOOGLE_CHECK(source.GetDescriptor() == destination->GetDescriptor());
+ // Build a FieldMaskTree and walk through the tree to merge all specified
+ // fields.
+ FieldMaskTree tree;
+ tree.MergeFromFieldMask(mask);
+ tree.MergeMessage(source, options, destination);
+}
+
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/util/field_mask_util.h b/src/google/protobuf/util/field_mask_util.h
new file mode 100644
index 00000000..c99c34f8
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util.h
@@ -0,0 +1,146 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
+
+#include <string>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/field_mask.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class LIBPROTOBUF_EXPORT FieldMaskUtil {
+ typedef google::protobuf::FieldMask FieldMask;
+
+ public:
+ // Converts FieldMask to/from string, formatted according to proto3 JSON
+ // spec for FieldMask (e.g., "foo,bar,baz.quz").
+ static string ToString(const FieldMask& mask);
+ static void FromString(const string& str, FieldMask* out);
+
+ // Checks whether the given path is valid for type T.
+ template <typename T>
+ static bool IsValidPath(const string& path) {
+ return InternalIsValidPath(T::descriptor(), path);
+ }
+
+ // Checks whether the given FieldMask is valid for type T.
+ template <typename T>
+ static bool IsValidFieldMask(const FieldMask& mask) {
+ for (int i = 0; i < mask.paths_size(); ++i) {
+ if (!InternalIsValidPath(T::descriptor(), mask.paths(i))) return false;
+ }
+ return true;
+ }
+
+ // Adds a path to FieldMask after checking whether the given path is valid.
+ // This method check-fails if the path is not a valid path for type T.
+ template <typename T>
+ static void AddPathToFieldMask(const string& path, FieldMask* mask) {
+ GOOGLE_CHECK(IsValidPath<T>(path));
+ mask->add_paths(path);
+ }
+
+ // Creates a FieldMask with all fields of type T. This FieldMask only
+ // contains fields of T but not any sub-message fields.
+ template <typename T>
+ static void GetFieldMaskForAllFields(FieldMask* out) {
+ InternalGetFieldMaskForAllFields(T::descriptor(), out);
+ }
+
+ // Converts a FieldMask to the canonical form. It will:
+ // 1. Remove paths that are covered by another path. For example,
+ // "foo.bar" is covered by "foo" and will be removed if "foo"
+ // is also in the FieldMask.
+ // 2. Sort all paths in alphabetical order.
+ static void ToCanonicalForm(const FieldMask& mask, FieldMask* out);
+
+ // Creates an union of two FieldMasks.
+ static void Union(const FieldMask& mask1, const FieldMask& mask2,
+ FieldMask* out);
+
+ // Creates an intersection of two FieldMasks.
+ static void Intersect(const FieldMask& mask1, const FieldMask& mask2,
+ FieldMask* out);
+
+ // Returns true if path is covered by the given FieldMask. Note that path
+ // "foo.bar" covers all paths like "foo.bar.baz", "foo.bar.quz.x", etc.
+ static bool IsPathInFieldMask(const string& path, const FieldMask& mask);
+
+ class MergeOptions;
+ // Merges fields specified in a FieldMask into another message.
+ static void MergeMessageTo(const Message& source, const FieldMask& mask,
+ const MergeOptions& options, Message* destination);
+
+ private:
+ static bool InternalIsValidPath(const Descriptor* descriptor,
+ const string& path);
+
+ static void InternalGetFieldMaskForAllFields(const Descriptor* descriptor,
+ FieldMask* out);
+};
+
+class LIBPROTOBUF_EXPORT FieldMaskUtil::MergeOptions {
+ public:
+ MergeOptions()
+ : replace_message_fields_(false), replace_repeated_fields_(false) {}
+ // When merging message fields, the default behavior is to merge the
+ // content of two message fields together. If you instead want to use
+ // the field from the source message to replace the corresponding field
+ // in the destination message, set this flag to true. When this flag is set,
+ // specified submessage fields that are missing in source will be cleared in
+ // destination.
+ void set_replace_message_fields(bool value) {
+ replace_message_fields_ = value;
+ }
+ bool replace_message_fields() const { return replace_message_fields_; }
+ // The default merging behavior will append entries from the source
+ // repeated field to the destination repeated field. If you only want
+ // to keep the entries from the source repeated field, set this flag
+ // to true.
+ void set_replace_repeated_fields(bool value) {
+ replace_repeated_fields_ = value;
+ }
+ bool replace_repeated_fields() const { return replace_repeated_fields_; }
+
+ private:
+ bool replace_message_fields_;
+ bool replace_repeated_fields_;
+};
+
+} // namespace util
+} // namespace protobuf
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_UTIL_FIELD_MASK_UTIL_H__
diff --git a/src/google/protobuf/util/field_mask_util_test.cc b/src/google/protobuf/util/field_mask_util_test.cc
new file mode 100644
index 00000000..a9523250
--- /dev/null
+++ b/src/google/protobuf/util/field_mask_util_test.cc
@@ -0,0 +1,395 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/field_mask_util.h>
+
+#include <google/protobuf/field_mask.pb.h>
+#include <google/protobuf/unittest.pb.h>
+#include <google/protobuf/test_util.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+namespace {
+
+using protobuf_unittest::TestAllTypes;
+using protobuf_unittest::NestedTestAllTypes;
+using google::protobuf::FieldMask;
+
+TEST(FieldMaskUtilTest, StringFormat) {
+ FieldMask mask;
+ EXPECT_EQ("", FieldMaskUtil::ToString(mask));
+ mask.add_paths("foo");
+ EXPECT_EQ("foo", FieldMaskUtil::ToString(mask));
+ mask.add_paths("bar");
+ EXPECT_EQ("foo,bar", FieldMaskUtil::ToString(mask));
+
+ FieldMaskUtil::FromString("", &mask);
+ EXPECT_EQ(0, mask.paths_size());
+ FieldMaskUtil::FromString("foo", &mask);
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_EQ("foo", mask.paths(0));
+ FieldMaskUtil::FromString("foo,bar", &mask);
+ EXPECT_EQ(2, mask.paths_size());
+ EXPECT_EQ("foo", mask.paths(0));
+ EXPECT_EQ("bar", mask.paths(1));
+}
+
+TEST(FieldMaskUtilTest, TestIsVaildPath) {
+ EXPECT_TRUE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_int32"));
+ EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nonexist"));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsValidPath<TestAllTypes>("optional_nested_message.bb"));
+ EXPECT_FALSE(FieldMaskUtil::IsValidPath<TestAllTypes>(
+ "optional_nested_message.nonexist"));
+ // FieldMask cannot be used to specify sub-fields of a repeated message.
+ EXPECT_FALSE(
+ FieldMaskUtil::IsValidPath<TestAllTypes>("repeated_nested_message.bb"));
+}
+
+TEST(FieldMaskUtilTest, TestIsValidFieldMask) {
+ FieldMask mask;
+ FieldMaskUtil::FromString("optional_int32,optional_nested_message.bb", &mask);
+ EXPECT_TRUE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+
+ FieldMaskUtil::FromString(
+ "optional_int32,optional_nested_message.bb,optional_nonexist", &mask);
+ EXPECT_FALSE(FieldMaskUtil::IsValidFieldMask<TestAllTypes>(mask));
+}
+
+TEST(FieldMaskUtilTest, TestGetFieldMaskForAllFields) {
+ FieldMask mask;
+ FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes::NestedMessage>(&mask);
+ EXPECT_EQ(1, mask.paths_size());
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("bb", mask));
+
+ FieldMaskUtil::GetFieldMaskForAllFields<TestAllTypes>(&mask);
+ EXPECT_EQ(76, mask.paths_size());
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_int64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_uint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_fixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_sfixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_float", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_double", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bool", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_string", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_bytes", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_nested_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_foreign_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("optional_import_message", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_nested_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_foreign_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("optional_import_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_int64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_uint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sint64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_fixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed32", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_sfixed64", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_float", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_double", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bool", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_string", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_bytes", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_nested_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_foreign_message", mask));
+ EXPECT_TRUE(
+ FieldMaskUtil::IsPathInFieldMask("repeated_import_message", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_nested_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_foreign_enum", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("repeated_import_enum", mask));
+}
+
+TEST(FieldMaskUtilTest, TestToCanonicalForm) {
+ FieldMask in, out;
+ // Paths will be sorted.
+ FieldMaskUtil::FromString("baz.quz,bar,foo", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,baz.quz,foo", FieldMaskUtil::ToString(out));
+ // Duplicated paths will be removed.
+ FieldMaskUtil::FromString("foo,bar,foo", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,foo", FieldMaskUtil::ToString(out));
+ // Sub-paths of other paths will be removed.
+ FieldMaskUtil::FromString("foo.b1,bar.b1,foo.b2,bar", &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("bar,foo.b1,foo.b2", FieldMaskUtil::ToString(out));
+
+ // Test more deeply nested cases.
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2.quz,"
+ "foo.bar.baz2",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar.baz1,foo.bar.baz2", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz,"
+ "foo.bar",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo.bar", FieldMaskUtil::ToString(out));
+ FieldMaskUtil::FromString(
+ "foo.bar.baz1,"
+ "foo.bar.baz2,"
+ "foo.bar.baz2.quz,"
+ "foo",
+ &in);
+ FieldMaskUtil::ToCanonicalForm(in, &out);
+ EXPECT_EQ("foo", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestUnion) {
+ FieldMask mask1, mask2, out;
+ // Test cases without overlapping.
+ FieldMaskUtil::FromString("foo,baz", &mask1);
+ FieldMaskUtil::FromString("bar,quz", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("bar,baz,foo,quz", FieldMaskUtil::ToString(out));
+ // Overlap with duplicated paths.
+ FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+ FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("baz.bb,foo,quz", FieldMaskUtil::ToString(out));
+ // Overlap with paths covering some other paths.
+ FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+ FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+ FieldMaskUtil::Union(mask1, mask2, &out);
+ EXPECT_EQ("bar,foo.bar,quz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIntersect) {
+ FieldMask mask1, mask2, out;
+ // Test cases without overlapping.
+ FieldMaskUtil::FromString("foo,baz", &mask1);
+ FieldMaskUtil::FromString("bar,quz", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("", FieldMaskUtil::ToString(out));
+ // Overlap with duplicated paths.
+ FieldMaskUtil::FromString("foo,baz.bb", &mask1);
+ FieldMaskUtil::FromString("baz.bb,quz", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("baz.bb", FieldMaskUtil::ToString(out));
+ // Overlap with paths covering some other paths.
+ FieldMaskUtil::FromString("foo.bar.baz,quz", &mask1);
+ FieldMaskUtil::FromString("foo.bar,bar", &mask2);
+ FieldMaskUtil::Intersect(mask1, mask2, &out);
+ EXPECT_EQ("foo.bar.baz", FieldMaskUtil::ToString(out));
+}
+
+TEST(FieldMaskUtilTest, TestIspathInFieldMask) {
+ FieldMask mask;
+ FieldMaskUtil::FromString("foo.bar", &mask);
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("", mask));
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar", mask));
+ EXPECT_TRUE(FieldMaskUtil::IsPathInFieldMask("foo.bar.baz", mask));
+ EXPECT_FALSE(FieldMaskUtil::IsPathInFieldMask("foo.bar0.baz", mask));
+}
+
+TEST(FieldMaskUtilTest, MergeMessage) {
+ TestAllTypes src, dst;
+ TestUtil::SetAllFields(&src);
+ FieldMaskUtil::MergeOptions options;
+
+#define TEST_MERGE_ONE_PRIMITIVE_FIELD(field_name) \
+ { \
+ TestAllTypes tmp; \
+ tmp.set_##field_name(src.field_name()); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ dst.Clear(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ }
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_int64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_uint64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sint64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_fixed64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed32)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_sfixed64)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_float)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_double)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bool)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_string)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_bytes)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_nested_enum)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_foreign_enum)
+ TEST_MERGE_ONE_PRIMITIVE_FIELD(optional_import_enum)
+#undef TEST_MERGE_ONE_PRIMITIVE_FIELD
+
+#define TEST_MERGE_ONE_FIELD(field_name) \
+ { \
+ TestAllTypes tmp; \
+ *tmp.mutable_##field_name() = src.field_name(); \
+ FieldMask mask; \
+ mask.add_paths(#field_name); \
+ dst.Clear(); \
+ FieldMaskUtil::MergeMessageTo(src, mask, options, &dst); \
+ EXPECT_EQ(tmp.DebugString(), dst.DebugString()); \
+ }
+ TEST_MERGE_ONE_FIELD(optional_nested_message)
+ TEST_MERGE_ONE_FIELD(optional_foreign_message)
+ TEST_MERGE_ONE_FIELD(optional_import_message)
+
+ TEST_MERGE_ONE_FIELD(repeated_int32)
+ TEST_MERGE_ONE_FIELD(repeated_int64)
+ TEST_MERGE_ONE_FIELD(repeated_uint32)
+ TEST_MERGE_ONE_FIELD(repeated_uint64)
+ TEST_MERGE_ONE_FIELD(repeated_sint32)
+ TEST_MERGE_ONE_FIELD(repeated_sint64)
+ TEST_MERGE_ONE_FIELD(repeated_fixed32)
+ TEST_MERGE_ONE_FIELD(repeated_fixed64)
+ TEST_MERGE_ONE_FIELD(repeated_sfixed32)
+ TEST_MERGE_ONE_FIELD(repeated_sfixed64)
+ TEST_MERGE_ONE_FIELD(repeated_float)
+ TEST_MERGE_ONE_FIELD(repeated_double)
+ TEST_MERGE_ONE_FIELD(repeated_bool)
+ TEST_MERGE_ONE_FIELD(repeated_string)
+ TEST_MERGE_ONE_FIELD(repeated_bytes)
+ TEST_MERGE_ONE_FIELD(repeated_nested_message)
+ TEST_MERGE_ONE_FIELD(repeated_foreign_message)
+ TEST_MERGE_ONE_FIELD(repeated_import_message)
+ TEST_MERGE_ONE_FIELD(repeated_nested_enum)
+ TEST_MERGE_ONE_FIELD(repeated_foreign_enum)
+ TEST_MERGE_ONE_FIELD(repeated_import_enum)
+#undef TEST_MERGE_ONE_FIELD
+
+ // Test merge nested fields.
+ NestedTestAllTypes nested_src, nested_dst;
+ nested_src.mutable_child()->mutable_payload()->set_optional_int32(1234);
+ nested_src.mutable_child()
+ ->mutable_child()
+ ->mutable_payload()
+ ->set_optional_int32(5678);
+ FieldMask mask;
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(0, nested_dst.child().child().payload().optional_int32());
+
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ nested_dst.Clear();
+ FieldMaskUtil::FromString("child.child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(0, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ nested_dst.Clear();
+ FieldMaskUtil::FromString("child", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(5678, nested_dst.child().child().payload().optional_int32());
+
+ // Test MergeOptions.
+
+ nested_dst.Clear();
+ nested_dst.mutable_child()->mutable_payload()->set_optional_int64(4321);
+ // Message fields will be merged by default.
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(4321, nested_dst.child().payload().optional_int64());
+ // Change the behavior to replace message fields.
+ options.set_replace_message_fields(true);
+ FieldMaskUtil::FromString("child.payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_EQ(1234, nested_dst.child().payload().optional_int32());
+ EXPECT_EQ(0, nested_dst.child().payload().optional_int64());
+
+ // By default, fields missing in source are not cleared in destination.
+ options.set_replace_message_fields(false);
+ nested_dst.mutable_payload();
+ EXPECT_TRUE(nested_dst.has_payload());
+ FieldMaskUtil::FromString("payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_TRUE(nested_dst.has_payload());
+ // But they are cleared when replacing message fields.
+ options.set_replace_message_fields(true);
+ nested_dst.Clear();
+ nested_dst.mutable_payload();
+ FieldMaskUtil::FromString("payload", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ EXPECT_FALSE(nested_dst.has_payload());
+
+ nested_src.mutable_payload()->add_repeated_int32(1234);
+ nested_dst.mutable_payload()->add_repeated_int32(5678);
+ // Repeated fields will be appended by default.
+ FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ ASSERT_EQ(2, nested_dst.payload().repeated_int32_size());
+ EXPECT_EQ(5678, nested_dst.payload().repeated_int32(0));
+ EXPECT_EQ(1234, nested_dst.payload().repeated_int32(1));
+ // Change the behavior to replace repeated fields.
+ options.set_replace_repeated_fields(true);
+ FieldMaskUtil::FromString("payload.repeated_int32", &mask);
+ FieldMaskUtil::MergeMessageTo(nested_src, mask, options, &nested_dst);
+ ASSERT_EQ(1, nested_dst.payload().repeated_int32_size());
+ EXPECT_EQ(1234, nested_dst.payload().repeated_int32(0));
+}
+
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index 944fb2e3..ea360798 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -79,7 +79,9 @@ StatusOr<To> NumberConvertAndCheck(From before) {
// For conversion between double and float only.
template <typename To, typename From>
StatusOr<To> FloatingPointConvertAndCheck(From before) {
- if (MathLimits<From>::IsNaN(before)) return std::numeric_limits<To>::quiet_NaN();
+ if (MathLimits<From>::IsNaN(before)) {
+ return std::numeric_limits<To>::quiet_NaN();
+ }
To after = static_cast<To>(before);
if (MathUtil::AlmostEquals<To>(after, before)) {
@@ -167,7 +169,7 @@ StatusOr<string> DataPiece::ToString() const {
return str_.ToString();
case TYPE_BYTES: {
string base64;
- WebSafeBase64Escape(str_, &base64);
+ Base64Escape(str_, &base64);
return base64;
}
default:
diff --git a/src/google/protobuf/util/internal/datapiece.h b/src/google/protobuf/util/internal/datapiece.h
index 30947252..2ab3fa88 100644
--- a/src/google/protobuf/util/internal/datapiece.h
+++ b/src/google/protobuf/util/internal/datapiece.h
@@ -193,13 +193,13 @@ class LIBPROTOBUF_EXPORT DataPiece {
// Stored piece of data.
union {
- const int32 i32_;
- const int64 i64_;
- const uint32 u32_;
- const uint64 u64_;
- const double double_;
- const float float_;
- const bool bool_;
+ int32 i32_;
+ int64 i64_;
+ uint32 u32_;
+ uint64 u64_;
+ double double_;
+ float float_;
+ bool bool_;
StringPiecePod str_;
};
};
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 267e2cd3..97b248ff 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -46,6 +46,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter(
TypeResolver* type_resolver, const google::protobuf::Type& type,
ObjectWriter* ow)
: typeinfo_(TypeInfo::NewTypeInfo(type_resolver)),
+ own_typeinfo_(true),
type_(type),
disable_normalize_(false),
current_(NULL),
@@ -56,6 +57,9 @@ DefaultValueObjectWriter::~DefaultValueObjectWriter() {
for (int i = 0; i < string_values_.size(); ++i) {
delete string_values_[i];
}
+ if (own_typeinfo_) {
+ delete typeinfo_;
+ }
}
DefaultValueObjectWriter* DefaultValueObjectWriter::RenderBool(StringPiece name,
@@ -197,33 +201,47 @@ void DefaultValueObjectWriter::Node::WriteTo(ObjectWriter* ow) {
if (disable_normalize_) {
ow->DisableCaseNormalizationForNextKey();
}
+
if (kind_ == PRIMITIVE) {
ObjectWriter::RenderDataPieceTo(data_, name_, ow);
return;
}
- if (is_placeholder_) {
- // If is_placeholder_ = true, we didn't see this node in the response, so
- // skip output.
+
+ // Render maps. Empty maps are rendered as "{}".
+ if (kind_ == MAP) {
+ ow->StartObject(name_);
+ WriteChildren(ow);
+ ow->EndObject();
return;
}
+
+ // Write out lists. If we didn't have any list in response, write out empty
+ // list.
if (kind_ == LIST) {
ow->StartList(name_);
- } else {
- ow->StartObject(name_);
+ WriteChildren(ow);
+ ow->EndList();
+ return;
}
+
+ // If is_placeholder_ = true, we didn't see this node in the response, so
+ // skip output.
+ if (is_placeholder_) return;
+
+ ow->StartObject(name_);
+ WriteChildren(ow);
+ ow->EndObject();
+}
+
+void DefaultValueObjectWriter::Node::WriteChildren(ObjectWriter* ow) {
for (int i = 0; i < children_.size(); ++i) {
Node* child = children_[i];
child->WriteTo(ow);
}
- if (kind_ == LIST) {
- ow->EndList();
- } else {
- ow->EndObject();
- }
}
const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType(
- const google::protobuf::Type& found_type, TypeInfo* typeinfo) {
+ const google::protobuf::Type& found_type, const TypeInfo* typeinfo) {
// If this field is a map, we should use the type of its "Value" as
// the type of the child node.
for (int i = 0; i < found_type.fields_size(); ++i) {
@@ -248,7 +266,8 @@ const google::protobuf::Type* DefaultValueObjectWriter::Node::GetMapValueType(
return NULL;
}
-void DefaultValueObjectWriter::Node::PopulateChildren(TypeInfo* typeinfo) {
+void DefaultValueObjectWriter::Node::PopulateChildren(
+ const TypeInfo* typeinfo) {
// Ignores well known types that don't require automatically populating their
// primitive children. For type "Any", we only populate its children when the
// "@type" field is set.
@@ -310,15 +329,17 @@ void DefaultValueObjectWriter::Node::PopulateChildren(TypeInfo* typeinfo) {
google::protobuf::Field_Cardinality_CARDINALITY_REPEATED) {
kind = LIST;
}
- // If the child field is of primitive type, sets its data to the default
- // value of its type.
+
// If oneof_index() != 0, the child field is part of a "oneof", which means
// the child field is optional and we shouldn't populate its default value.
+ if (field.oneof_index() != 0) continue;
+
+ // If the child field is of primitive type, sets its data to the default
+ // value of its type.
google::protobuf::scoped_ptr<Node> child(
- new Node(field.name(), field_type, kind,
- ((kind == PRIMITIVE && field.oneof_index() == 0)
- ? CreateDefaultDataPieceForField(field)
- : DataPiece::NullData()),
+ new Node(field.json_name(), field_type, kind,
+ kind == PRIMITIVE ? CreateDefaultDataPieceForField(field)
+ : DataPiece::NullData(),
true));
new_children.push_back(child.release());
}
@@ -338,7 +359,7 @@ void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) {
// have been added, populates its children.
if (node != NULL && node->is_any() && node->type() != NULL &&
node->type()->name() != kAnyType && node->number_of_children() == 1) {
- node->PopulateChildren(typeinfo_.get());
+ node->PopulateChildren(typeinfo_);
}
}
@@ -388,7 +409,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
false));
root_->set_disable_normalize(GetAndResetDisableNormalize());
- root_->PopulateChildren(typeinfo_.get());
+ root_->PopulateChildren(typeinfo_);
current_ = root_.get();
return this;
}
@@ -409,7 +430,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
child->set_is_placeholder(false);
child->set_disable_normalize(GetAndResetDisableNormalize());
if (child->kind() == OBJECT && child->number_of_children() == 0) {
- child->PopulateChildren(typeinfo_.get());
+ child->PopulateChildren(typeinfo_);
}
stack_.push(current_);
@@ -492,12 +513,11 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
// first value field is rendered before we populate the children, because
// the "value" field of a Any message could be omitted.
if (current_->number_of_children() > 1 && current_->type() != NULL) {
- current_->PopulateChildren(typeinfo_.get());
+ current_->PopulateChildren(typeinfo_);
}
}
Node* child = current_->FindChild(name);
if (child == NULL || child->kind() != PRIMITIVE) {
- GOOGLE_LOG(WARNING) << "Cannot find primitive field '" << name << "'.";
// No children are found, creates a new child.
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, PRIMITIVE, data, false));
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index 759ba91b..d4547601 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -129,7 +129,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Populates children of this Node based on its type. If there are already
// children created, they will be merged to the result. Caller should pass
// in TypeInfo for looking up types of the children.
- void PopulateChildren(TypeInfo* typeinfo);
+ void PopulateChildren(const TypeInfo* typeinfo);
// If this node is a leaf (has data), writes the current node to the
// ObjectWriter; if not, then recursively writes the children to the
@@ -165,7 +165,10 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Returns the Value Type of a map given the Type of the map entry and a
// TypeInfo instance.
const google::protobuf::Type* GetMapValueType(
- const google::protobuf::Type& entry_type, TypeInfo* typeinfo);
+ const google::protobuf::Type& entry_type, const TypeInfo* typeinfo);
+
+ // Calls WriteTo() on every child in children_.
+ void WriteChildren(ObjectWriter* ow);
// The name of this node.
string name_;
@@ -210,7 +213,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Type information for all the types used in the descriptor. Used to find
// google::protobuf::Type of nested messages/enums.
- google::protobuf::scoped_ptr<TypeInfo> typeinfo_;
+ const TypeInfo* typeinfo_;
+ // Whether the TypeInfo object is owned by this class.
+ bool own_typeinfo_;
// google::protobuf::Type of the root message type.
const google::protobuf::Type& type_;
// Holds copies of strings passed to RenderString.
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 593c7105..237d0722 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter_test.cc
@@ -73,15 +73,15 @@ INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
TEST_P(DefaultValueObjectWriterTest, Empty) {
// Set expectation
expects_.StartObject("")
- ->RenderDouble("double_value", 0.0)
- ->RenderFloat("float_value", 0.0)
- ->RenderInt64("int64_value", 0)
- ->RenderUint64("uint64_value", 0)
- ->RenderInt32("int32_value", 0)
- ->RenderUint32("uint32_value", 0)
- ->RenderBool("bool_value", false)
- ->RenderString("string_value", "")
- ->RenderBytes("bytes_value", "")
+ ->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", "")
->EndObject();
// Actual testing
@@ -91,42 +91,42 @@ TEST_P(DefaultValueObjectWriterTest, Empty) {
TEST_P(DefaultValueObjectWriterTest, NonDefaultDouble) {
// Set expectation
expects_.StartObject("")
- ->RenderDouble("double_value", 1.0)
- ->RenderFloat("float_value", 0.0)
- ->RenderInt64("int64_value", 0)
- ->RenderUint64("uint64_value", 0)
- ->RenderInt32("int32_value", 0)
- ->RenderUint32("uint32_value", 0)
- ->RenderBool("bool_value", false)
- ->RenderString("string_value", "")
+ ->RenderDouble("doubleValue", 1.0)
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
->EndObject();
// Actual testing
- testing_->StartObject("")->RenderDouble("double_value", 1.0)->EndObject();
+ testing_->StartObject("")->RenderDouble("doubleValue", 1.0)->EndObject();
}
TEST_P(DefaultValueObjectWriterTest, ShouldRetainUnknownField) {
// Set expectation
expects_.StartObject("")
- ->RenderDouble("double_value", 1.0)
- ->RenderFloat("float_value", 0.0)
- ->RenderInt64("int64_value", 0)
- ->RenderUint64("uint64_value", 0)
- ->RenderInt32("int32_value", 0)
- ->RenderUint32("uint32_value", 0)
- ->RenderBool("bool_value", false)
- ->RenderString("string_value", "")
+ ->RenderDouble("doubleValue", 1.0)
+ ->RenderFloat("floatValue", 0.0)
+ ->RenderInt64("int64Value", 0)
+ ->RenderUint64("uint64Value", 0)
+ ->RenderInt32("int32Value", 0)
+ ->RenderUint32("uint32Value", 0)
+ ->RenderBool("boolValue", false)
+ ->RenderString("stringValue", "")
->RenderString("unknown", "abc")
- ->StartObject("unknown_object")
+ ->StartObject("unknownObject")
->RenderString("unknown", "def")
->EndObject()
->EndObject();
// Actual testing
testing_->StartObject("")
- ->RenderDouble("double_value", 1.0)
+ ->RenderDouble("doubleValue", 1.0)
->RenderString("unknown", "abc")
- ->StartObject("unknown_object")
+ ->StartObject("unknownObject")
->RenderString("unknown", "def")
->EndObject()
->EndObject();
diff --git a/src/google/protobuf/util/internal/error_listener.h b/src/google/protobuf/util/internal/error_listener.h
index 9b907df5..2699684d 100644
--- a/src/google/protobuf/util/internal/error_listener.h
+++ b/src/google/protobuf/util/internal/error_listener.h
@@ -37,7 +37,9 @@
#endif
#include <string>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/util/internal/location_tracker.h>
#include <google/protobuf/stubs/stringpiece.h>
diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc
index 92468959..f0e8fc88 100644
--- a/src/google/protobuf/util/internal/field_mask_utility.cc
+++ b/src/google/protobuf/util/internal/field_mask_utility.cc
@@ -34,7 +34,6 @@
#include <google/protobuf/stubs/status_macros.h>
namespace google {
-
namespace protobuf {
namespace util {
namespace converter {
@@ -138,7 +137,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
}
// Un-escaped '"' must be followed with a ']'.
if (i >= length - 1 || paths[i + 1] != ']') {
- return CreatePublicError(
+ return util::Status(
util::error::INVALID_ARGUMENT,
StrCat("Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
@@ -150,7 +149,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
// Checks whether the key ends at the end of a path segment.
if (i < length - 1 && paths[i + 1] != '.' && paths[i + 1] != ',' &&
paths[i + 1] != ')' && paths[i + 1] != '(') {
- return CreatePublicError(
+ return util::Status(
util::error::INVALID_ARGUMENT,
StrCat("Invalid FieldMask '", paths,
"'. Map keys should be at the end of a path segment."));
@@ -162,7 +161,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
// We are not in a map key, look for the start of one.
if (paths[i] == '[') {
if (i >= length - 1 || paths[i + 1] != '\"') {
- return CreatePublicError(
+ return util::Status(
util::error::INVALID_ARGUMENT,
StrCat("Invalid FieldMask '", paths,
"'. Map keys should be represented as [\"some_key\"]."));
@@ -198,7 +197,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
// Removes the last prefix after seeing a ')'.
if (i < length && paths[i] == ')') {
if (prefix.empty()) {
- return CreatePublicError(
+ return util::Status(
util::error::INVALID_ARGUMENT,
StrCat("Invalid FieldMask '", paths,
"'. Cannot find matching '(' for all ')'."));
@@ -208,16 +207,14 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths,
previous_position = i + 1;
}
if (in_map_key) {
- return CreatePublicError(
- util::error::INVALID_ARGUMENT,
- StrCat("Invalid FieldMask '", paths,
- "'. Cannot find matching ']' for all '['."));
+ return util::Status(util::error::INVALID_ARGUMENT,
+ StrCat("Invalid FieldMask '", paths,
+ "'. Cannot find matching ']' for all '['."));
}
if (!prefix.empty()) {
- return CreatePublicError(
- util::error::INVALID_ARGUMENT,
- StrCat("Invalid FieldMask '", paths,
- "'. Cannot find matching ')' for all '('."));
+ return util::Status(util::error::INVALID_ARGUMENT,
+ StrCat("Invalid FieldMask '", paths,
+ "'. Cannot find matching ')' for all '('."));
}
return util::Status::OK;
}
diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc
index 5ac23421..36dc8ef9 100644
--- a/src/google/protobuf/util/internal/json_escaping.cc
+++ b/src/google/protobuf/util/internal/json_escaping.cc
@@ -30,6 +30,7 @@
#include <google/protobuf/util/internal/json_escaping.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
namespace google {
diff --git a/src/google/protobuf/util/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc
index 0c41515f..f81e3306 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter.cc
@@ -33,9 +33,11 @@
#include <math.h>
#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/util/internal/json_escaping.h>
+#include <google/protobuf/stubs/mathlimits.h>
#include <google/protobuf/stubs/strutil.h>
namespace google {
@@ -114,7 +116,9 @@ JsonObjectWriter* JsonObjectWriter::RenderUint64(StringPiece name,
JsonObjectWriter* JsonObjectWriter::RenderDouble(StringPiece name,
double value) {
- if (isfinite(value)) return RenderSimple(name, SimpleDtoa(value));
+ if (google::protobuf::MathLimits<double>::IsFinite(value)) {
+ return RenderSimple(name, SimpleDtoa(value));
+ }
// Render quoted with NaN/Infinity-aware DoubleAsString.
return RenderString(name, DoubleAsString(value));
@@ -122,7 +126,9 @@ JsonObjectWriter* JsonObjectWriter::RenderDouble(StringPiece name,
JsonObjectWriter* JsonObjectWriter::RenderFloat(StringPiece name,
float value) {
- if (isfinite(value)) return RenderSimple(name, SimpleFtoa(value));
+ if (google::protobuf::MathLimits<float>::IsFinite(value)) {
+ return RenderSimple(name, SimpleFtoa(value));
+ }
// Render quoted with NaN/Infinity-aware FloatAsString.
return RenderString(name, FloatAsString(value));
@@ -142,7 +148,7 @@ JsonObjectWriter* JsonObjectWriter::RenderBytes(StringPiece name,
StringPiece value) {
WritePrefix(name);
string base64;
- WebSafeBase64EscapeWithPadding(value, &base64);
+ Base64Escape(value, &base64);
WriteChar('"');
// TODO(wpoon): Consider a ByteSink solution that writes the base64 bytes
// directly to the stream, rather than first putting them
diff --git a/src/google/protobuf/util/internal/json_objectwriter_test.cc b/src/google/protobuf/util/internal/json_objectwriter_test.cc
index df9a133e..dcd60601 100644
--- a/src/google/protobuf/util/internal/json_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter_test.cc
@@ -47,7 +47,8 @@ class JsonObjectWriterTest : public ::testing::Test {
JsonObjectWriterTest()
: str_stream_(new StringOutputStream(&output_)),
out_stream_(new CodedOutputStream(str_stream_)),
- ow_(NULL) {}
+ ow_(NULL) {
+ }
virtual ~JsonObjectWriterTest() {
delete ow_;
@@ -63,34 +64,36 @@ class JsonObjectWriterTest : public ::testing::Test {
TEST_F(JsonObjectWriterTest, EmptyRootObject) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->EndObject();
+ ow_->StartObject("")
+ ->EndObject();
EXPECT_EQ("{}", output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
+ ->RenderString("test", "value")
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
EXPECT_EQ("{\"test\":\"value\",\"empty\":{}}",
output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyRootList) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartList("")->EndList();
+ ow_->StartList("")
+ ->EndList();
EXPECT_EQ("[]", output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, EmptyList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderString("test", "value")
- ->StartList("empty")
- ->EndList()
- ->EndObject();
+ ->RenderString("test", "value")
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
EXPECT_EQ("{\"test\":\"value\",\"empty\":[]}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -98,10 +101,10 @@ TEST_F(JsonObjectWriterTest, EmptyList) {
TEST_F(JsonObjectWriterTest, ObjectInObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->StartObject("nested")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndObject();
+ ->StartObject("nested")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndObject();
EXPECT_EQ("{\"nested\":{\"field\":\"value\"}}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -109,10 +112,10 @@ TEST_F(JsonObjectWriterTest, ObjectInObject) {
TEST_F(JsonObjectWriterTest, ListInObject) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->StartList("nested")
- ->RenderString("", "value")
- ->EndList()
- ->EndObject();
+ ->StartList("nested")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndObject();
EXPECT_EQ("{\"nested\":[\"value\"]}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -120,10 +123,10 @@ TEST_F(JsonObjectWriterTest, ListInObject) {
TEST_F(JsonObjectWriterTest, ObjectInList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartList("")
- ->StartObject("")
- ->RenderString("field", "value")
- ->EndObject()
- ->EndList();
+ ->StartObject("")
+ ->RenderString("field", "value")
+ ->EndObject()
+ ->EndList();
EXPECT_EQ("[{\"field\":\"value\"}]",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -131,10 +134,10 @@ TEST_F(JsonObjectWriterTest, ObjectInList) {
TEST_F(JsonObjectWriterTest, ListInList) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartList("")
- ->StartList("")
- ->RenderString("", "value")
- ->EndList()
- ->EndList();
+ ->StartList("")
+ ->RenderString("", "value")
+ ->EndList()
+ ->EndList();
EXPECT_EQ("[[\"value\"]]", output_.substr(0, out_stream_->ByteCount()));
}
@@ -164,97 +167,95 @@ TEST_F(JsonObjectWriterTest, RenderPrimitives) {
output_.substr(0, out_stream_->ByteCount()));
}
-TEST_F(JsonObjectWriterTest, BytesEncodesAsWebSafeBase64) {
+TEST_F(JsonObjectWriterTest, BytesEncodesAsNonWebSafeBase64) {
string s;
s.push_back('\377');
s.push_back('\357');
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")->RenderBytes("bytes", s)->EndObject();
// Non-web-safe would encode this as "/+8="
- EXPECT_EQ("{\"bytes\":\"_-8=\"}",
+ EXPECT_EQ("{\"bytes\":\"/+8=\"}",
output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintList) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartList("items")
- ->RenderString("", "item1")
- ->RenderString("", "item2")
- ->RenderString("", "item3")
- ->EndList()
- ->StartList("empty")
- ->EndList()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"items\": [\n"
- " \"item1\",\n"
- " \"item2\",\n"
- " \"item3\"\n"
- " ],\n"
- " \"empty\": []\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartList("items")
+ ->RenderString("", "item1")
+ ->RenderString("", "item2")
+ ->RenderString("", "item3")
+ ->EndList()
+ ->StartList("empty")
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ("{\n"
+ " \"items\": [\n"
+ " \"item1\",\n"
+ " \"item2\",\n"
+ " \"item3\"\n"
+ " ],\n"
+ " \"empty\": []\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintObject) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartObject("items")
- ->RenderString("key1", "item1")
- ->RenderString("key2", "item2")
- ->RenderString("key3", "item3")
- ->EndObject()
- ->StartObject("empty")
- ->EndObject()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"items\": {\n"
- " \"key1\": \"item1\",\n"
- " \"key2\": \"item2\",\n"
- " \"key3\": \"item3\"\n"
- " },\n"
- " \"empty\": {}\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartObject("items")
+ ->RenderString("key1", "item1")
+ ->RenderString("key2", "item2")
+ ->RenderString("key3", "item3")
+ ->EndObject()
+ ->StartObject("empty")
+ ->EndObject()
+ ->EndObject();
+ EXPECT_EQ("{\n"
+ " \"items\": {\n"
+ " \"key1\": \"item1\",\n"
+ " \"key2\": \"item2\",\n"
+ " \"key3\": \"item3\"\n"
+ " },\n"
+ " \"empty\": {}\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintEmptyObjectInEmptyList) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->StartList("list")
- ->StartObject("")
- ->EndObject()
- ->EndList()
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"list\": [\n"
- " {}\n"
- " ]\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->StartList("list")
+ ->StartObject("")
+ ->EndObject()
+ ->EndList()
+ ->EndObject();
+ EXPECT_EQ("{\n"
+ " \"list\": [\n"
+ " {}\n"
+ " ]\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, PrettyPrintDoubleIndent) {
ow_ = new JsonObjectWriter(" ", out_stream_);
ow_->StartObject("")
- ->RenderBool("bool", true)
- ->RenderInt32("int", 42)
- ->EndObject();
- EXPECT_EQ(
- "{\n"
- " \"bool\": true,\n"
- " \"int\": 42\n"
- "}\n",
- output_.substr(0, out_stream_->ByteCount()));
+ ->RenderBool("bool", true)
+ ->RenderInt32("int", 42)
+ ->EndObject();
+ EXPECT_EQ("{\n"
+ " \"bool\": true,\n"
+ " \"int\": 42\n"
+ "}\n",
+ output_.substr(0, out_stream_->ByteCount()));
}
TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
ow_ = new JsonObjectWriter("", out_stream_);
- ow_->StartObject("")->RenderString("string", "'<>&amp;\\\"\r\n")->EndObject();
+ ow_->StartObject("")
+ ->RenderString("string", "'<>&amp;\\\"\r\n")
+ ->EndObject();
EXPECT_EQ("{\"string\":\"'\\u003c\\u003e&amp;\\\\\\\"\\r\\n\"}",
output_.substr(0, out_stream_->ByteCount()));
}
@@ -262,13 +263,13 @@ TEST_F(JsonObjectWriterTest, StringsEscapedAndEnclosedInDoubleQuotes) {
TEST_F(JsonObjectWriterTest, Stringification) {
ow_ = new JsonObjectWriter("", out_stream_);
ow_->StartObject("")
- ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
- ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
- ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
- ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
- ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
- ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
- ->EndObject();
+ ->RenderDouble("double_nan", std::numeric_limits<double>::quiet_NaN())
+ ->RenderFloat("float_nan", std::numeric_limits<float>::quiet_NaN())
+ ->RenderDouble("double_pos", std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_pos", std::numeric_limits<float>::infinity())
+ ->RenderDouble("double_neg", -std::numeric_limits<double>::infinity())
+ ->RenderFloat("float_neg", -std::numeric_limits<float>::infinity())
+ ->EndObject();
EXPECT_EQ(
"{\"double_nan\":\"NaN\","
"\"float_nan\":\"NaN\","
diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc
index d439a221..a7ef7fe2 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -40,6 +40,7 @@
#include <google/protobuf/stubs/shared_ptr.h>
#endif
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/util/internal/object_writer.h>
@@ -104,16 +105,42 @@ JsonStreamParser::JsonStreamParser(ObjectWriter* ow)
parsed_(),
parsed_storage_(),
string_open_(0),
- utf8_storage_(),
- utf8_length_(0) {
+ chunk_storage_(),
+ coerce_to_utf8_(false) {
// Initialize the stack with a single value to be parsed.
stack_.push(VALUE);
}
JsonStreamParser::~JsonStreamParser() {}
+
util::Status JsonStreamParser::Parse(StringPiece json) {
- return ParseChunk(json);
+ StringPiece chunk = json;
+ // If we have leftovers from a previous chunk, append the new chunk to it
+ // and create a new StringPiece pointing at the string's data. This could
+ // be large but we rely on the chunks to be small, assuming they are
+ // fragments of a Cord.
+ if (!leftover_.empty()) {
+ // Don't point chunk to leftover_ because leftover_ will be updated in
+ // ParseChunk(chunk).
+ chunk_storage_.swap(leftover_);
+ json.AppendToString(&chunk_storage_);
+ chunk = StringPiece(chunk_storage_);
+ }
+
+ // Find the structurally valid UTF8 prefix and parse only that.
+ int n = internal::UTF8SpnStructurallyValid(chunk);
+ if (n > 0) {
+ util::Status status = ParseChunk(chunk.substr(0, n));
+
+ // Any leftover characters are stashed in leftover_ for later parsing when
+ // there is more data available.
+ chunk.substr(n).AppendToString(&leftover_);
+ return status;
+ } else {
+ chunk.CopyToString(&leftover_);
+ return util::Status::OK;
+ }
}
util::Status JsonStreamParser::FinishParse() {
@@ -122,9 +149,22 @@ util::Status JsonStreamParser::FinishParse() {
if (stack_.empty() && leftover_.empty()) {
return util::Status::OK;
}
+
+ // Storage for UTF8-coerced string.
+ google::protobuf::scoped_array<char> utf8;
+ if (coerce_to_utf8_) {
+ utf8.reset(new char[leftover_.size()]);
+ char* coerced = internal::UTF8CoerceToStructurallyValid(leftover_, utf8.get(), ' ');
+ p_ = json_ = StringPiece(coerced, leftover_.size());
+ } else {
+ if (!internal::IsStructurallyValidUTF8(leftover_)) {
+ return ReportFailure("Encountered non UTF-8 code points.");
+ }
+ p_ = json_ = leftover_;
+ }
+
// Parse the remainder in finishing mode, which reports errors for things like
// unterminated strings or unknown tokens that would normally be retried.
- p_ = json_ = StringPiece(leftover_);
finishing_ = true;
util::Status result = RunParser();
if (result.ok()) {
@@ -137,16 +177,10 @@ util::Status JsonStreamParser::FinishParse() {
}
util::Status JsonStreamParser::ParseChunk(StringPiece chunk) {
- // If we have leftovers from a previous chunk, append the new chunk to it and
- // create a new StringPiece pointing at the string's data. This could be
- // large but we rely on the chunks to be small, assuming they are fragments
- // of a Cord.
- if (!leftover_.empty()) {
- chunk.AppendToString(&leftover_);
- p_ = json_ = StringPiece(leftover_);
- } else {
- p_ = json_ = chunk;
- }
+ // Do not do any work if the chunk is empty.
+ if (chunk.empty()) return util::Status::OK;
+
+ p_ = json_ = chunk;
finishing_ = false;
util::Status result = RunParser();
diff --git a/src/google/protobuf/util/internal/json_stream_parser.h b/src/google/protobuf/util/internal/json_stream_parser.h
index 17b094ae..0278c28f 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.h
+++ b/src/google/protobuf/util/internal/json_stream_parser.h
@@ -75,12 +75,14 @@ class LIBPROTOBUF_EXPORT JsonStreamParser {
explicit JsonStreamParser(ObjectWriter* ow);
virtual ~JsonStreamParser();
- // Parse a JSON string (UTF-8 encoded).
+ // Parses a UTF-8 encoded JSON string from a StringPiece.
util::Status Parse(StringPiece json);
+
// Finish parsing the JSON string.
util::Status FinishParse();
+
private:
enum TokenType {
BEGIN_STRING, // " or '
@@ -239,11 +241,11 @@ class LIBPROTOBUF_EXPORT JsonStreamParser {
// A value of 0 indicates that string parsing is not in process.
char string_open_;
- // Storage for utf8-coerced bytes.
- google::protobuf::scoped_array<char> utf8_storage_;
+ // Storage for the chunk that are being parsed in ParseChunk().
+ string chunk_storage_;
- // Length of the storage for utf8-coerced bytes.
- int utf8_length_;
+ // Whether to allow non UTF-8 encoded input and replace invalid code points.
+ bool coerce_to_utf8_;
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(JsonStreamParser);
};
diff --git a/src/google/protobuf/util/internal/json_stream_parser_test.cc b/src/google/protobuf/util/internal/json_stream_parser_test.cc
index b0775a2f..c833ed1f 100644
--- a/src/google/protobuf/util/internal/json_stream_parser_test.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser_test.cc
@@ -30,6 +30,7 @@
#include <google/protobuf/util/internal/json_stream_parser.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/time.h>
#include <google/protobuf/util/internal/expecting_objectwriter.h>
@@ -85,7 +86,7 @@ class JsonStreamParserTest : public ::testing::Test {
JsonStreamParserTest() : mock_(), ow_(&mock_) {}
virtual ~JsonStreamParserTest() {}
- util::Status RunTest(StringPiece json, int split) {
+ util::Status RunTest(StringPiece json, int split, bool coerce_utf8 = false) {
JsonStreamParser parser(&mock_);
// Special case for split == length, test parsing one character at a time.
@@ -115,8 +116,8 @@ class JsonStreamParserTest : public ::testing::Test {
return result;
}
- void DoTest(StringPiece json, int split) {
- util::Status result = RunTest(json, split);
+ void DoTest(StringPiece json, int split, bool coerce_utf8 = false) {
+ util::Status result = RunTest(json, split, coerce_utf8);
if (!result.ok()) {
GOOGLE_LOG(WARNING) << result;
}
@@ -337,14 +338,26 @@ TEST_F(JsonStreamParserTest, ObjectValues) {
}
}
+
+TEST_F(JsonStreamParserTest, RejectNonUtf8WhenNotCoerced) {
+ StringPiece json = "{\"address\":\xFF\"חרושת 23, רעננה, ישראל\"}";
+ for (int i = 0; i <= json.length(); ++i) {
+ DoErrorTest(json, i, "Encountered non UTF-8 code points.");
+ }
+ json = "{\"address\": \"חרושת 23,\xFFרעננה, ישראל\"}";
+ for (int i = 0; i <= json.length(); ++i) {
+ DoErrorTest(json, i, "Encountered non UTF-8 code points.");
+ }
+}
+
#ifndef _MSC_VER
// - unicode handling in strings
TEST_F(JsonStreamParserTest, UnicodeEscaping) {
StringPiece str = "[\"\\u0639\\u0631\\u0628\\u0649\"]";
for (int i = 0; i <= str.length(); ++i) {
// TODO(xiaofeng): Figure out what default encoding to use for JSON strings.
- // In protobuf we use UTF-8 for strings, but for JSON we probably should allow
- // different encodings?
+ // In protobuf we use UTF-8 for strings, but for JSON we probably should
+ // allow different encodings?
ow_.StartList("")->RenderString("", "\u0639\u0631\u0628\u0649")->EndList();
DoTest(str, i);
}
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 53a0e47a..996e1f8c 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -33,6 +33,7 @@
#include <utility>
#include <google/protobuf/stubs/casts.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/stubs/time.h>
@@ -46,6 +47,7 @@
#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
+#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/status_macros.h>
@@ -96,7 +98,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
}
ProtoStreamObjectSource::ProtoStreamObjectSource(
- google::protobuf::io::CodedInputStream* stream, TypeInfo* typeinfo,
+ google::protobuf::io::CodedInputStream* stream, const TypeInfo* typeinfo,
const google::protobuf::Type& type)
: stream_(stream), typeinfo_(typeinfo), own_typeinfo_(false), type_(type) {
GOOGLE_LOG_IF(DFATAL, stream == NULL) << "Input stream is NULL.";
@@ -156,7 +158,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type,
last_tag = tag;
field = FindAndVerifyField(type, tag);
if (field != NULL) {
- field_name = field->name();
+ field_name = field->json_name();
}
}
if (field == NULL) {
@@ -214,7 +216,7 @@ StatusOr<uint32> ProtoStreamObjectSource::RenderMap(
const google::protobuf::Field* field, StringPiece name, uint32 list_tag,
ObjectWriter* ow) const {
const google::protobuf::Type* field_type =
- typeinfo_->GetType(field->type_url());
+ typeinfo_->GetTypeByTypeUrl(field->type_url());
uint32 tag_to_return = 0;
if (IsPackable(*field) &&
list_tag ==
@@ -647,46 +649,53 @@ Status ProtoStreamObjectSource::RenderFieldMask(
}
hash_map<string, ProtoStreamObjectSource::TypeRenderer>*
-ProtoStreamObjectSource::CreateRendererMap() {
- hash_map<string, ProtoStreamObjectSource::TypeRenderer>* result =
- new hash_map<string, ProtoStreamObjectSource::TypeRenderer>();
- (*result)["google.protobuf.Timestamp"] =
+ ProtoStreamObjectSource::renderers_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(source_renderers_init_);
+
+void ProtoStreamObjectSource::InitRendererMap() {
+ renderers_ = new hash_map<string, ProtoStreamObjectSource::TypeRenderer>();
+ (*renderers_)["google.protobuf.Timestamp"] =
&ProtoStreamObjectSource::RenderTimestamp;
- (*result)["google.protobuf.Duration"] =
+ (*renderers_)["google.protobuf.Duration"] =
&ProtoStreamObjectSource::RenderDuration;
- (*result)["google.protobuf.DoubleValue"] =
+ (*renderers_)["google.protobuf.DoubleValue"] =
&ProtoStreamObjectSource::RenderDouble;
- (*result)["google.protobuf.FloatValue"] =
+ (*renderers_)["google.protobuf.FloatValue"] =
&ProtoStreamObjectSource::RenderFloat;
- (*result)["google.protobuf.Int64Value"] =
+ (*renderers_)["google.protobuf.Int64Value"] =
&ProtoStreamObjectSource::RenderInt64;
- (*result)["google.protobuf.UInt64Value"] =
+ (*renderers_)["google.protobuf.UInt64Value"] =
&ProtoStreamObjectSource::RenderUInt64;
- (*result)["google.protobuf.Int32Value"] =
+ (*renderers_)["google.protobuf.Int32Value"] =
&ProtoStreamObjectSource::RenderInt32;
- (*result)["google.protobuf.UInt32Value"] =
+ (*renderers_)["google.protobuf.UInt32Value"] =
&ProtoStreamObjectSource::RenderUInt32;
- (*result)["google.protobuf.BoolValue"] = &ProtoStreamObjectSource::RenderBool;
- (*result)["google.protobuf.StringValue"] =
+ (*renderers_)["google.protobuf.BoolValue"] = &ProtoStreamObjectSource::RenderBool;
+ (*renderers_)["google.protobuf.StringValue"] =
&ProtoStreamObjectSource::RenderString;
- (*result)["google.protobuf.BytesValue"] =
+ (*renderers_)["google.protobuf.BytesValue"] =
&ProtoStreamObjectSource::RenderBytes;
- (*result)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny;
- (*result)["google.protobuf.Struct"] = &ProtoStreamObjectSource::RenderStruct;
- (*result)["google.protobuf.Value"] =
+ (*renderers_)["google.protobuf.Any"] = &ProtoStreamObjectSource::RenderAny;
+ (*renderers_)["google.protobuf.Struct"] = &ProtoStreamObjectSource::RenderStruct;
+ (*renderers_)["google.protobuf.Value"] =
&ProtoStreamObjectSource::RenderStructValue;
- (*result)["google.protobuf.ListValue"] =
+ (*renderers_)["google.protobuf.ListValue"] =
&ProtoStreamObjectSource::RenderStructListValue;
- (*result)["google.protobuf.FieldMask"] =
+ (*renderers_)["google.protobuf.FieldMask"] =
&ProtoStreamObjectSource::RenderFieldMask;
- return result;
+ ::google::protobuf::internal::OnShutdown(&DeleteRendererMap);
+}
+
+void ProtoStreamObjectSource::DeleteRendererMap() {
+ delete ProtoStreamObjectSource::renderers_;
+ renderers_ = NULL;
}
// static
ProtoStreamObjectSource::TypeRenderer*
ProtoStreamObjectSource::FindTypeRenderer(const string& type_url) {
- static hash_map<string, TypeRenderer>* renderers = CreateRendererMap();
- return FindOrNull(*renderers, type_url);
+ ::google::protobuf::GoogleOnceInit(&source_renderers_init_, &InitRendererMap);
+ return FindOrNull(*renderers_, type_url);
}
Status ProtoStreamObjectSource::RenderField(
@@ -784,7 +793,8 @@ Status ProtoStreamObjectSource::RenderField(
// Get the nested enum type for this field.
// TODO(skarvaje): Avoid string manipulation. Find ways to speed this
// up.
- const google::protobuf::Enum* en = typeinfo_->GetEnum(field->type_url());
+ const google::protobuf::Enum* en =
+ typeinfo_->GetEnumByTypeUrl(field->type_url());
// Lookup the name of the enum, and render that. Skips unknown enums.
if (en != NULL) {
const google::protobuf::EnumValue* enum_value =
@@ -819,7 +829,7 @@ Status ProtoStreamObjectSource::RenderField(
int old_limit = stream_->PushLimit(buffer32);
// Get the nested message type for this field.
const google::protobuf::Type* type =
- typeinfo_->GetType(field->type_url());
+ typeinfo_->GetTypeByTypeUrl(field->type_url());
if (type == NULL) {
return Status(util::error::INTERNAL,
StrCat("Invalid configuration. Could not find the type: ",
@@ -928,7 +938,8 @@ const string ProtoStreamObjectSource::ReadFieldValueAsString(
// Get the nested enum type for this field.
// TODO(skarvaje): Avoid string manipulation. Find ways to speed this
// up.
- const google::protobuf::Enum* en = typeinfo_->GetEnum(field.type_url());
+ const google::protobuf::Enum* en =
+ typeinfo_->GetEnumByTypeUrl(field.type_url());
// Lookup the name of the enum, and render that. Skips unknown enums.
if (en != NULL) {
const google::protobuf::EnumValue* enum_value =
@@ -962,7 +973,7 @@ const string ProtoStreamObjectSource::ReadFieldValueAsString(
bool ProtoStreamObjectSource::IsMap(
const google::protobuf::Field& field) const {
const google::protobuf::Type* field_type =
- typeinfo_->GetType(field.type_url());
+ typeinfo_->GetTypeByTypeUrl(field.type_url());
// TODO(xiaofeng): Unify option names.
return field.kind() == google::protobuf::Field_Kind_TYPE_MESSAGE &&
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 4a4e6bbf..f52383a1 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -46,7 +46,6 @@
#include <google/protobuf/stubs/statusor.h>
-
namespace google {
namespace protobuf {
class Field;
@@ -61,7 +60,10 @@ namespace converter {
class TypeInfo;
// An ObjectSource that can parse a stream of bytes as a protocol buffer.
-// This implementation uses a tech Type for tag lookup.
+// Its WriteTo() method can be given an ObjectWriter.
+// This implementation uses a google.protobuf.Type for tag and name lookup.
+// The field names are converted into lower camel-case when writing to the
+// ObjectWriter.
//
// Sample usage: (suppose input is: string proto)
// ArrayInputStream arr_stream(proto.data(), proto.size());
@@ -93,7 +95,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
private:
ProtoStreamObjectSource(google::protobuf::io::CodedInputStream* stream,
- TypeInfo* typeinfo,
+ const TypeInfo* typeinfo,
const google::protobuf::Type& type);
// Function that renders a well known type with a modified behavior.
typedef util::Status (*TypeRenderer)(const ProtoStreamObjectSource*,
@@ -200,7 +202,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
const google::protobuf::Type& type,
StringPiece name, ObjectWriter* ow);
- static hash_map<string, TypeRenderer>* CreateRendererMap();
+ static hash_map<string, TypeRenderer>* renderers_;
+ static void InitRendererMap();
+ static void DeleteRendererMap();
static TypeRenderer* FindTypeRenderer(const string& type_url);
// Renders a field value to the ObjectWriter.
@@ -226,7 +230,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
// Type information for all the types used in the descriptor. Used to find
// google::protobuf::Type of nested messages/enums.
- TypeInfo* typeinfo_;
+ const TypeInfo* typeinfo_;
// Whether this class owns the typeinfo_ object. If true the typeinfo_ object
// should be deleted in the destructor.
bool own_typeinfo_;
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index 4cc62410..f6e5ee7a 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -117,61 +117,61 @@ class ProtostreamObjectSourceTest
void PrepareExpectingObjectWriterForRepeatedPrimitive() {
ow_.StartObject("")
- ->StartList("rep_fix32")
+ ->StartList("repFix32")
->RenderUint32("", bit_cast<uint32>(3201))
->RenderUint32("", bit_cast<uint32>(0))
->RenderUint32("", bit_cast<uint32>(3202))
->EndList()
- ->StartList("rep_u32")
+ ->StartList("repU32")
->RenderUint32("", bit_cast<uint32>(3203))
->RenderUint32("", bit_cast<uint32>(0))
->EndList()
- ->StartList("rep_i32")
+ ->StartList("repI32")
->RenderInt32("", 0)
->RenderInt32("", 3204)
->RenderInt32("", 3205)
->EndList()
- ->StartList("rep_sf32")
+ ->StartList("repSf32")
->RenderInt32("", 3206)
->RenderInt32("", 0)
->EndList()
- ->StartList("rep_s32")
+ ->StartList("repS32")
->RenderInt32("", 0)
->RenderInt32("", 3207)
->RenderInt32("", 3208)
->EndList()
- ->StartList("rep_fix64")
+ ->StartList("repFix64")
->RenderUint64("", bit_cast<uint64>(6401LL))
->RenderUint64("", bit_cast<uint64>(0LL))
->EndList()
- ->StartList("rep_u64")
+ ->StartList("repU64")
->RenderUint64("", bit_cast<uint64>(0LL))
->RenderUint64("", bit_cast<uint64>(6402LL))
->RenderUint64("", bit_cast<uint64>(6403LL))
->EndList()
- ->StartList("rep_i64")
+ ->StartList("repI64")
->RenderInt64("", 6404L)
->RenderInt64("", 0L)
->EndList()
- ->StartList("rep_sf64")
+ ->StartList("repSf64")
->RenderInt64("", 0L)
->RenderInt64("", 6405L)
->RenderInt64("", 6406L)
->EndList()
- ->StartList("rep_s64")
+ ->StartList("repS64")
->RenderInt64("", 6407L)
->RenderInt64("", 0L)
->EndList()
- ->StartList("rep_float")
+ ->StartList("repFloat")
->RenderFloat("", 0.0f)
->RenderFloat("", 32.1f)
->RenderFloat("", 32.2f)
->EndList()
- ->StartList("rep_double")
+ ->StartList("repDouble")
->RenderDouble("", 64.1L)
->RenderDouble("", 0.0L)
->EndList()
- ->StartList("rep_bool")
+ ->StartList("repBool")
->RenderBool("", true)
->RenderBool("", false)
->EndList()
@@ -317,11 +317,11 @@ TEST_P(ProtostreamObjectSourceTest, RepeatingPrimitives) {
primitive.add_rep_str("String Two");
primitive.add_rep_bytes("Some Bytes");
- ow_.StartList("rep_str")
+ ow_.StartList("repStr")
->RenderString("", "String One")
->RenderString("", "String Two")
->EndList()
- ->StartList("rep_bytes")
+ ->StartList("repBytes")
->RenderBytes("", "Some Bytes")
->EndList();
DoTest(primitive, Primitive::descriptor());
@@ -794,16 +794,16 @@ TEST_P(ProtostreamObjectSourceFieldMaskTest, FieldMaskRenderSuccess) {
ow_.StartObject("")
->RenderString("id", "1")
- ->RenderString("single_mask", "path1,snakeCasePath2")
- ->StartList("repeated_mask")
+ ->RenderString("singleMask", "path1,snakeCasePath2")
+ ->StartList("repeatedMask")
->RenderString("", "path3")
->RenderString("", "snakeCasePath4,path5")
->EndList()
- ->StartList("nested_mask")
+ ->StartList("nestedMask")
->StartObject("")
->RenderString("data", "data")
- ->RenderString("single_mask", "nested.path1,nestedField.snakeCasePath2")
- ->StartList("repeated_mask")
+ ->RenderString("singleMask", "nested.path1,nestedField.snakeCasePath2")
+ ->StartList("repeatedMask")
->RenderString("", "nestedField.path3,nested.snakeCasePath4")
->RenderString("", "nested.path5")
->RenderString("",
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index 7f6f3c35..a935ac39 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -39,6 +39,7 @@
#include <google/protobuf/util/internal/object_location_tracker.h>
#include <google/protobuf/util/internal/constants.h>
#include <google/protobuf/util/internal/utility.h>
+#include <google/protobuf/stubs/once.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/statusor.h>
@@ -74,7 +75,7 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter(
tracker_(new ObjectLocationTracker()) {}
ProtoStreamObjectWriter::ProtoStreamObjectWriter(
- TypeInfo* typeinfo, const google::protobuf::Type& type,
+ const TypeInfo* typeinfo, const google::protobuf::Type& type,
strings::ByteSink* output, ErrorListener* listener)
: master_type_(type),
typeinfo_(typeinfo),
@@ -91,14 +92,19 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter(
tracker_(new ObjectLocationTracker()) {}
ProtoStreamObjectWriter::~ProtoStreamObjectWriter() {
- // Cleanup explicitly in order to avoid destructor stack overflow when input
- // is deeply nested.
- while (element_ != NULL) {
- element_.reset(element_->pop());
- }
if (own_typeinfo_) {
delete typeinfo_;
}
+ if (element_ == NULL) return;
+ // Cleanup explicitly in order to avoid destructor stack overflow when input
+ // is deeply nested.
+ // Cast to BaseElement to avoid doing additional checks (like missing fields)
+ // during pop().
+ google::protobuf::scoped_ptr<BaseElement> element(
+ static_cast<BaseElement*>(element_.get())->pop<BaseElement>());
+ while (element != NULL) {
+ element.reset(element->pop<BaseElement>());
+ }
}
namespace {
@@ -454,7 +460,7 @@ void ProtoStreamObjectWriter::AnyWriter::WriteAny() {
}
ProtoStreamObjectWriter::ProtoElement::ProtoElement(
- TypeInfo* typeinfo, const google::protobuf::Type& type,
+ const TypeInfo* typeinfo, const google::protobuf::Type& type,
ProtoStreamObjectWriter* enclosing)
: BaseElement(NULL),
ow_(enclosing),
@@ -586,6 +592,14 @@ string ProtoStreamObjectWriter::ProtoElement::ToString() const {
return loc.empty() ? "." : loc;
}
+bool ProtoStreamObjectWriter::ProtoElement::OneofIndexTaken(int32 index) {
+ return ContainsKey(oneof_indices_, index);
+}
+
+void ProtoStreamObjectWriter::ProtoElement::TakeOneofIndex(int32 index) {
+ InsertIfNotPresent(&oneof_indices_, index);
+}
+
inline void ProtoStreamObjectWriter::InvalidName(StringPiece unknown_name,
StringPiece message) {
listener_->InvalidName(location(), ToSnakeCase(unknown_name), message);
@@ -655,6 +669,13 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartObject(
return this;
}
+ // Check to see if this field is a oneof and that no oneof in that group has
+ // already been set.
+ if (!ValidOneof(*field, name)) {
+ ++invalid_depth_;
+ return this;
+ }
+
if (field->type_url() == GetFullTypeWithUrl(kStructType)) {
// Start a struct object.
StartStruct(field);
@@ -932,6 +953,14 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::StartList(StringPiece name) {
// Also we ignore if the field is not found here as it is caught later.
field = typeinfo_->FindField(&element_->type(), name);
+ // Only check for oneof collisions on the first StartList call. We identify
+ // the first call with !name.empty() check. Subsequent list element calls
+ // will not have the name filled.
+ if (!name.empty() && field && !ValidOneof(*field, name)) {
+ ++invalid_depth_;
+ return this;
+ }
+
// It is an error to try to bind to map, which behind the scenes is a list.
if (field && IsMap(*field)) {
// Push field to stack for error location tracking & reporting.
@@ -1080,9 +1109,9 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow,
data.ValueAsStringOrDefault("")));
}
- // TODO(tsun): figure out how to do proto descriptor based snake case
- // conversions as much as possible. Because ToSnakeCase sometimes returns the
- // wrong value.
+// TODO(tsun): figure out how to do proto descriptor based snake case
+// conversions as much as possible. Because ToSnakeCase sometimes returns the
+// wrong value.
google::protobuf::scoped_ptr<ResultCallback1<util::Status, StringPiece> > callback(
NewPermanentCallback(&RenderOneFieldPath, ow));
return DecodeCompactFieldMaskPaths(data.str(), callback.get());
@@ -1154,6 +1183,7 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece(
const google::protobuf::Field* field = NULL;
string type_url;
bool is_map_entry = false;
+ // We are at the root when element_ == NULL.
if (element_ == NULL) {
type_url = GetFullTypeWithUrl(master_type_.name());
} else {
@@ -1166,6 +1196,11 @@ ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece(
if (field == NULL) {
return this;
}
+
+ // Check to see if this field is a oneof and that no oneof in that group has
+ // already been set.
+ if (!ValidOneof(*field, name)) return this;
+
type_url = field->type_url();
}
@@ -1314,7 +1349,8 @@ void ProtoStreamObjectWriter::RenderSimpleDataPiece(
}
case google::protobuf::Field_Kind_TYPE_ENUM: {
status = WriteEnum(field.number(), data,
- typeinfo_->GetEnum(field.type_url()), stream_.get());
+ typeinfo_->GetEnumByTypeUrl(field.type_url()),
+ stream_.get());
break;
}
default: // TYPE_GROUP or TYPE_MESSAGE
@@ -1330,60 +1366,67 @@ void ProtoStreamObjectWriter::RenderSimpleDataPiece(
// Map of functions that are responsible for rendering well known type
// represented by the key.
hash_map<string, ProtoStreamObjectWriter::TypeRenderer>*
-ProtoStreamObjectWriter::CreateRendererMap() {
- google::protobuf::scoped_ptr<hash_map<string, ProtoStreamObjectWriter::TypeRenderer> >
- result(new hash_map<string, ProtoStreamObjectWriter::TypeRenderer>());
- (*result)["type.googleapis.com/google.protobuf.Timestamp"] =
+ ProtoStreamObjectWriter::renderers_ = NULL;
+GOOGLE_PROTOBUF_DECLARE_ONCE(writer_renderers_init_);
+
+void ProtoStreamObjectWriter::InitRendererMap() {
+ renderers_ = new hash_map<string, ProtoStreamObjectWriter::TypeRenderer>();
+ (*renderers_)["type.googleapis.com/google.protobuf.Timestamp"] =
&ProtoStreamObjectWriter::RenderTimestamp;
- (*result)["type.googleapis.com/google.protobuf.Duration"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Duration"] =
&ProtoStreamObjectWriter::RenderDuration;
- (*result)["type.googleapis.com/google.protobuf.FieldMask"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.FieldMask"] =
&ProtoStreamObjectWriter::RenderFieldMask;
- (*result)["type.googleapis.com/google.protobuf.Double"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Double"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Float"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Float"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int64"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int64"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt64"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt64"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int32"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int32"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt32"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt32"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Bool"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Bool"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.String"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.String"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Bytes"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Bytes"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.DoubleValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.DoubleValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.FloatValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.FloatValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int64Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int64Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt64Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt64Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Int32Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Int32Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.UInt32Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.UInt32Value"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.BoolValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.BoolValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.StringValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.StringValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.BytesValue"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.BytesValue"] =
&ProtoStreamObjectWriter::RenderWrapperType;
- (*result)["type.googleapis.com/google.protobuf.Value"] =
+ (*renderers_)["type.googleapis.com/google.protobuf.Value"] =
&ProtoStreamObjectWriter::RenderStructValue;
- return result.release();
+ ::google::protobuf::internal::OnShutdown(&DeleteRendererMap);
+}
+
+void ProtoStreamObjectWriter::DeleteRendererMap() {
+ delete ProtoStreamObjectWriter::renderers_;
+ renderers_ = NULL;
}
ProtoStreamObjectWriter::TypeRenderer*
ProtoStreamObjectWriter::FindTypeRenderer(const string& type_url) {
- static hash_map<string, TypeRenderer>* renderers = CreateRendererMap();
- return FindOrNull(*renderers, type_url);
+ ::google::protobuf::GoogleOnceInit(&writer_renderers_init_, &InitRendererMap);
+ return FindOrNull(*renderers_, type_url);
}
ProtoStreamObjectWriter::ProtoElement::ElementType
@@ -1401,6 +1444,24 @@ ProtoStreamObjectWriter::GetElementType(const google::protobuf::Type& type) {
}
}
+bool ProtoStreamObjectWriter::ValidOneof(const google::protobuf::Field& field,
+ StringPiece unnormalized_name) {
+ if (element_ == NULL) return true;
+
+ if (field.oneof_index() > 0) {
+ if (element_->OneofIndexTaken(field.oneof_index())) {
+ InvalidValue(
+ "oneof",
+ StrCat("oneof field '",
+ element_->type().oneofs(field.oneof_index() - 1),
+ "' is already set. Cannot set '", unnormalized_name, "'"));
+ return false;
+ }
+ element_->TakeOneofIndex(field.oneof_index());
+ }
+ return true;
+}
+
const google::protobuf::Field* ProtoStreamObjectWriter::BeginNamed(
StringPiece name, bool is_list) {
if (invalid_depth_ > 0) {
@@ -1450,7 +1511,7 @@ const google::protobuf::Field* ProtoStreamObjectWriter::Lookup(
const google::protobuf::Type* ProtoStreamObjectWriter::LookupType(
const google::protobuf::Field* field) {
return (field->kind() == google::protobuf::Field_Kind_TYPE_MESSAGE
- ? typeinfo_->GetType(field->type_url())
+ ? typeinfo_->GetTypeByTypeUrl(field->type_url())
: &element_->type());
}
@@ -1539,7 +1600,7 @@ bool ProtoStreamObjectWriter::IsMap(const google::protobuf::Field& field) {
return false;
}
const google::protobuf::Type* field_type =
- typeinfo_->GetType(field.type_url());
+ typeinfo_->GetTypeByTypeUrl(field.type_url());
// TODO(xiaofeng): Unify option names.
return GetBoolOptionOrDefault(field_type->options(),
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h
index eb4a59f9..8f49120b 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.h
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.h
@@ -71,7 +71,7 @@ class ObjectLocationTracker;
// It also supports streaming.
class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter {
public:
- // Constructor. Does not take ownership of any parameter passed in.
+// Constructor. Does not take ownership of any parameter passed in.
ProtoStreamObjectWriter(TypeResolver* type_resolver,
const google::protobuf::Type& type,
strings::ByteSink* output, ErrorListener* listener);
@@ -82,20 +82,17 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
virtual ProtoStreamObjectWriter* EndObject();
virtual ProtoStreamObjectWriter* StartList(StringPiece name);
virtual ProtoStreamObjectWriter* EndList();
- virtual ProtoStreamObjectWriter* RenderBool(StringPiece name,
- bool value) {
+ virtual ProtoStreamObjectWriter* RenderBool(StringPiece name, bool value) {
return RenderDataPiece(name, DataPiece(value));
}
- virtual ProtoStreamObjectWriter* RenderInt32(StringPiece name,
- int32 value) {
+ virtual ProtoStreamObjectWriter* RenderInt32(StringPiece name, int32 value) {
return RenderDataPiece(name, DataPiece(value));
}
virtual ProtoStreamObjectWriter* RenderUint32(StringPiece name,
uint32 value) {
return RenderDataPiece(name, DataPiece(value));
}
- virtual ProtoStreamObjectWriter* RenderInt64(StringPiece name,
- int64 value) {
+ virtual ProtoStreamObjectWriter* RenderInt64(StringPiece name, int64 value) {
return RenderDataPiece(name, DataPiece(value));
}
virtual ProtoStreamObjectWriter* RenderUint64(StringPiece name,
@@ -106,8 +103,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
double value) {
return RenderDataPiece(name, DataPiece(value));
}
- virtual ProtoStreamObjectWriter* RenderFloat(StringPiece name,
- float value) {
+ virtual ProtoStreamObjectWriter* RenderFloat(StringPiece name, float value) {
return RenderDataPiece(name, DataPiece(value));
}
virtual ProtoStreamObjectWriter* RenderString(StringPiece name,
@@ -217,7 +213,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
};
// Constructor for the root element. No parent nor field.
- ProtoElement(TypeInfo* typeinfo, const google::protobuf::Type& type,
+ ProtoElement(const TypeInfo* typeinfo, const google::protobuf::Type& type,
ProtoStreamObjectWriter* enclosing);
// Constructor for a field of an element.
@@ -256,6 +252,13 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
return static_cast<ProtoElement*>(BaseElement::parent());
}
+ // Returns true if the index is already taken by a preceeding oneof input.
+ bool OneofIndexTaken(int32 index);
+
+ // Marks the oneof 'index' as taken. Future inputs to this oneof will
+ // generate an error.
+ void TakeOneofIndex(int32 index);
+
private:
// Used for access to variables of the enclosing instance of
// ProtoStreamObjectWriter.
@@ -269,7 +272,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
const google::protobuf::Field* field_;
// TypeInfo to lookup types.
- TypeInfo* typeinfo_;
+ const TypeInfo* typeinfo_;
// Additional variables if this element is a message:
// (Root element is always a message).
@@ -289,6 +292,10 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// The type of this element, see enum for permissible types.
ElementType element_type_;
+ // 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_;
+
GOOGLE_DISALLOW_IMPLICIT_CONSTRUCTORS(ProtoElement);
};
@@ -298,7 +305,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
int size;
};
- ProtoStreamObjectWriter(TypeInfo* typeinfo,
+ ProtoStreamObjectWriter(const TypeInfo* typeinfo,
const google::protobuf::Type& type,
strings::ByteSink* output, ErrorListener* listener);
@@ -400,18 +407,28 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public StructuredObjectWriter
// Helper functions to create the map and find functions responsible for
// rendering well known types, keyed by type URL.
- static hash_map<string, TypeRenderer>* CreateRendererMap();
+ static hash_map<string, TypeRenderer>* renderers_;
+ static void InitRendererMap();
+ static void DeleteRendererMap();
static TypeRenderer* FindTypeRenderer(const string& type_url);
// Returns the ProtoElement::ElementType for the given Type.
static ProtoElement::ElementType GetElementType(
const google::protobuf::Type& type);
+ // Returns true if the field for type_ can be set as a oneof. If field is not
+ // a oneof type, this function does nothing and returns true.
+ // If another field for this oneof is already set, this function returns
+ // false. It also calls the appropriate error callback.
+ // unnormalized_name is used for error string.
+ bool ValidOneof(const google::protobuf::Field& field,
+ StringPiece unnormalized_name);
+
// Variables for describing the structure of the input tree:
// master_type_: descriptor for the whole protobuf message.
// typeinfo_ : the TypeInfo object to lookup types.
const google::protobuf::Type& master_type_;
- TypeInfo* typeinfo_;
+ const TypeInfo* typeinfo_;
// Whether we own the typeinfo_ object.
bool own_typeinfo_;
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
index bd4f29f5..96e5ccfb 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc
@@ -49,6 +49,7 @@
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/util/internal/testdata/anys.pb.h>
#include <google/protobuf/util/internal/testdata/maps.pb.h>
+#include <google/protobuf/util/internal/testdata/oneofs.pb.h>
#include <google/protobuf/util/internal/testdata/struct.pb.h>
#include <google/protobuf/util/internal/testdata/timestamp_duration.pb.h>
#include <gtest/gtest.h>
@@ -75,6 +76,7 @@ using ::testing::_;
using ::testing::Args;
using google::protobuf::testing::anys::AnyM;
using google::protobuf::testing::anys::AnyOut;
+using google::protobuf::testing::oneofs::OneOfsRequest;
using google::protobuf::testing::FieldMaskTest;
using google::protobuf::testing::maps::MapIn;
using google::protobuf::testing::structs::StructType;
@@ -143,7 +145,7 @@ class BaseProtoStreamObjectWriterTest
void CheckOutput(const Message& expected) { CheckOutput(expected, -1); }
const google::protobuf::Type* GetType(const Descriptor* descriptor) {
- return helper_.GetTypeInfo()->GetType(GetTypeUrl(descriptor));
+ return helper_.GetTypeInfo()->GetTypeByTypeUrl(GetTypeUrl(descriptor));
}
testing::TypeInfoTestHelper helper_;
@@ -854,11 +856,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError1) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
- StringPiece(
- "Field 'ts', Illegal timestamp format; timestamps "
- "must end with 'Z'")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Illegal timestamp format; timestamps "
+ "must end with 'Z'")));
ow_->StartObject("")->RenderString("ts", "")->EndObject();
CheckOutput(timestamp);
@@ -883,11 +884,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidTimestampError3) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
- StringPiece(
- "Field 'ts', Invalid time format, failed to parse nano "
- "seconds")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Timestamp"),
+ StringPiece("Field 'ts', Invalid time format, failed to parse nano "
+ "seconds")));
ow_->StartObject("")
->RenderString("ts", "1970-01-01T00:00:00.ABZ")
@@ -919,11 +919,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError1) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.Duration"),
- StringPiece(
- "Field 'dur', Illegal duration format; duration must "
- "end with 's'")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Illegal duration format; duration must "
+ "end with 's'")));
ow_->StartObject("")->RenderString("dur", "")->EndObject();
CheckOutput(duration);
@@ -934,11 +933,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError2) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.Duration"),
- StringPiece(
- "Field 'dur', Invalid duration format, failed to parse "
- "seconds")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Invalid duration format, failed to parse "
+ "seconds")));
ow_->StartObject("")->RenderString("dur", "s")->EndObject();
CheckOutput(duration);
@@ -949,11 +947,10 @@ TEST_P(ProtoStreamObjectWriterTimestampDurationTest, InvalidDurationError3) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.Duration"),
- StringPiece(
- "Field 'dur', Invalid duration format, failed to "
- "parse nanos seconds")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.Duration"),
+ StringPiece("Field 'dur', Invalid duration format, failed to "
+ "parse nanos seconds")));
ow_->StartObject("")->RenderString("dur", "123.DEFs")->EndObject();
CheckOutput(duration);
@@ -1174,10 +1171,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, EmptyAnyFromEmptyObject) {
TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
AnyOut any;
- EXPECT_CALL(listener_,
- InvalidValue(_, StringPiece("Any"),
- StringPiece(
- "Missing or invalid @type for any field in "
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing or invalid @type for any field in "
"google.protobuf.testing.anys.AnyOut")));
ow_->StartObject("")
@@ -1192,10 +1189,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails1) {
TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
AnyOut any;
- EXPECT_CALL(listener_,
- InvalidValue(_, StringPiece("Any"),
- StringPiece(
- "Missing or invalid @type for any field in "
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing or invalid @type for any field in "
"google.protobuf.testing.anys.AnyOut")));
ow_->StartObject("")
@@ -1210,10 +1207,10 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails2) {
TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
AnyOut any;
- EXPECT_CALL(listener_,
- InvalidValue(_, StringPiece("Any"),
- StringPiece(
- "Missing or invalid @type for any field in "
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(_, StringPiece("Any"),
+ StringPiece("Missing or invalid @type for any field in "
"google.protobuf.testing.anys.AnyOut")));
ow_->StartObject("")
@@ -1227,13 +1224,12 @@ TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithoutTypeUrlFails3) {
TEST_P(ProtoStreamObjectWriterAnyTest, AnyWithInvalidTypeUrlFails) {
AnyOut any;
- EXPECT_CALL(
- listener_,
- InvalidValue(_, StringPiece("Any"),
- StringPiece(
- "Invalid type URL, type URLs must be of the form "
- "'type.googleapis.com/<typename>', got: "
- "type.other.com/some.Type")));
+ EXPECT_CALL(listener_,
+ InvalidValue(
+ _, StringPiece("Any"),
+ StringPiece("Invalid type URL, type URLs must be of the form "
+ "'type.googleapis.com/<typename>', got: "
+ "type.other.com/some.Type")));
ow_->StartObject("")
->StartObject("any")
@@ -1401,11 +1397,10 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MaskUsingApiaryStyleShouldWork) {
TEST_P(ProtoStreamObjectWriterFieldMaskTest, MoreCloseThanOpenParentheses) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
- StringPiece(
- "Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
- "Cannot find matching '(' for all ')'.")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece("Field 'single_mask', Invalid FieldMask 'a(b,c))'. "
+ "Cannot find matching '(' for all ')'.")));
ow_->StartObject("");
ow_->RenderString("id", "1");
@@ -1448,12 +1443,11 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest,
MapKeyMustBeAtTheEndOfAPathSegment) {
EXPECT_CALL(
listener_,
- InvalidValue(_,
- StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
- StringPiece(
- "Field 'single_mask', Invalid FieldMask "
- "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
- "Map keys should be at the end of a path segment.")));
+ InvalidValue(
+ _, StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
+ StringPiece("Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"key1\"]a,path.to.map[\"key2\"]'. "
+ "Map keys should be at the end of a path segment.")));
ow_->StartObject("");
ow_->RenderString("single_mask",
@@ -1466,10 +1460,9 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustEnd) {
listener_,
InvalidValue(_,
StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
- StringPiece(
- "Field 'single_mask', Invalid FieldMask "
- "'path.to.map[\"key1\"'. Map keys should be "
- "represented as [\"some_key\"].")));
+ StringPiece("Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"key1\"'. Map keys should be "
+ "represented as [\"some_key\"].")));
ow_->StartObject("");
ow_->RenderString("single_mask", "path.to.map[\"key1\"");
@@ -1481,10 +1474,9 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyMustBeEscapedCorrectly) {
listener_,
InvalidValue(_,
StringPiece("type.googleapis.com/google.protobuf.FieldMask"),
- StringPiece(
- "Field 'single_mask', Invalid FieldMask "
- "'path.to.map[\"ke\"y1\"]'. Map keys should be "
- "represented as [\"some_key\"].")));
+ StringPiece("Field 'single_mask', Invalid FieldMask "
+ "'path.to.map[\"ke\"y1\"]'. Map keys should be "
+ "represented as [\"some_key\"].")));
ow_->StartObject("");
ow_->RenderString("single_mask", "path.to.map[\"ke\"y1\"]");
@@ -1507,6 +1499,192 @@ TEST_P(ProtoStreamObjectWriterFieldMaskTest, MapKeyCanContainAnyChars) {
CheckOutput(expected);
}
+class ProtoStreamObjectWriterOneOfsTest
+ : public BaseProtoStreamObjectWriterTest {
+ protected:
+ ProtoStreamObjectWriterOneOfsTest() {
+ vector<const Descriptor*> descriptors;
+ descriptors.push_back(OneOfsRequest::descriptor());
+ descriptors.push_back(google::protobuf::Struct::descriptor());
+ ResetTypeInfo(descriptors);
+ }
+};
+
+INSTANTIATE_TEST_CASE_P(DifferentTypeInfoSourceTest,
+ ProtoStreamObjectWriterOneOfsTest,
+ ::testing::Values(
+ testing::USE_TYPE_RESOLVER));
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForPrimitiveTypesTest) {
+ EXPECT_CALL(
+ listener_,
+ InvalidValue(
+ _, StringPiece("oneof"),
+ StringPiece(
+ "oneof field 'data' is already set. Cannot set 'intData'")));
+
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->RenderString("intData", "123");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForMessageTypesPrimitiveFirstTest) {
+ // Test for setting primitive oneof field first and then message field.
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'messageData'")));
+
+ // JSON: { "strData": "blah", "messageData": { "dataValue": 123 } }
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForMessageTypesMessageFirstTest) {
+ // Test for setting message oneof field first and then primitive field.
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'strData'")));
+
+ // JSON: { "messageData": { "dataValue": 123 }, "strData": "blah" }
+ ow_->StartObject("");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->RenderString("strData", "blah");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructTypesPrimitiveFirstTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'structData'")));
+
+ // JSON: { "strData": "blah", "structData": { "a": "b" } }
+ ow_->StartObject("");
+ ow_->RenderString("strData", "blah");
+ ow_->StartObject("structData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructTypesStructFirstTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'strData'")));
+
+ // JSON: { "structData": { "a": "b" }, "strData": "blah" }
+ ow_->StartObject("");
+ ow_->StartObject("structData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->RenderString("strData", "blah");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForStructValueTypesTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'valueData'")));
+
+ // JSON: { "messageData": { "dataValue": 123 }, "valueData": { "a": "b" } }
+ ow_->StartObject("");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->StartObject("valueData");
+ ow_->RenderString("a", "b");
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesPrimitiveFirstTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'tsData'")));
+
+ // JSON: { "intData": 123, "tsData": "1970-01-02T01:00:00.000Z" }
+ ow_->StartObject("");
+ ow_->RenderInt32("intData", 123);
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesWktFirstTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'intData'")));
+
+ // JSON: { "tsData": "1970-01-02T01:00:00.000Z", "intData": 123 }
+ ow_->StartObject("");
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->RenderInt32("intData", 123);
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForWellKnownTypesAndMessageTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'messageData'")));
+
+ // JSON: { "tsData": "1970-01-02T01:00:00.000Z",
+ // "messageData": { "dataValue": 123 } }
+ ow_->StartObject("");
+ ow_->RenderString("tsData", "1970-01-02T01:00:00.000Z");
+ ow_->StartObject("messageData");
+ ow_->RenderInt32("dataValue", 123);
+ ow_->EndObject();
+ ow_->EndObject();
+}
+
+TEST_P(ProtoStreamObjectWriterOneOfsTest,
+ MultipleOneofsFailForOneofWithinAnyTest) {
+ EXPECT_CALL(listener_,
+ InvalidValue(_, StringPiece("oneof"),
+ StringPiece("oneof field 'data' is already set. "
+ "Cannot set 'intData'")));
+
+ using google::protobuf::testing::oneofs::OneOfsRequest;
+ // JSON:
+ // { "anyData":
+ // { "@type":
+ // "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest",
+ // "strData": "blah",
+ // "intData": 123
+ // }
+ // }
+ ow_->StartObject("");
+ ow_->StartObject("anyData");
+ ow_->RenderString(
+ "@type",
+ "type.googleapis.com/google.protobuf.testing.oneofs.OneOfsRequest");
+ ow_->RenderString("strData", "blah");
+ ow_->RenderInt32("intData", 123);
+ ow_->EndObject();
+}
+
} // namespace converter
} // namespace util
} // namespace protobuf
diff --git a/src/google/protobuf/util/internal/snake2camel_objectwriter.h b/src/google/protobuf/util/internal/snake2camel_objectwriter.h
index 1a32bc56..9b4ab8a3 100644
--- a/src/google/protobuf/util/internal/snake2camel_objectwriter.h
+++ b/src/google/protobuf/util/internal/snake2camel_objectwriter.h
@@ -58,9 +58,7 @@ class Snake2CamelObjectWriter : public ObjectWriter {
// ObjectWriter methods.
virtual Snake2CamelObjectWriter* StartObject(StringPiece name) {
- ow_->StartObject(ShouldNormalizeCase(name)
- ? StringPiece(StringPiece(ToCamelCase(name)))
- : name);
+ ow_->StartObject(name);
return this;
}
@@ -70,8 +68,7 @@ class Snake2CamelObjectWriter : public ObjectWriter {
}
virtual Snake2CamelObjectWriter* StartList(StringPiece name) {
- ow_->StartList(ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name))
- : name);
+ ow_->StartList(name);
return this;
}
@@ -81,76 +78,57 @@ class Snake2CamelObjectWriter : public ObjectWriter {
}
virtual Snake2CamelObjectWriter* RenderBool(StringPiece name, bool value) {
- ow_->RenderBool(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderBool(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderInt32(StringPiece name, int32 value) {
- ow_->RenderInt32(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderInt32(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderUint32(StringPiece name,
uint32 value) {
- ow_->RenderUint32(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderUint32(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderInt64(StringPiece name, int64 value) {
- ow_->RenderInt64(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderInt64(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderUint64(StringPiece name,
uint64 value) {
- ow_->RenderUint64(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderUint64(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderDouble(StringPiece name,
double value) {
- ow_->RenderDouble(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderDouble(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderFloat(StringPiece name, float value) {
- ow_->RenderFloat(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderFloat(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderString(StringPiece name,
StringPiece value) {
- ow_->RenderString(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderString(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderBytes(StringPiece name,
StringPiece value) {
- ow_->RenderBytes(
- ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name)) : name,
- value);
+ ow_->RenderBytes(name, value);
return this;
}
virtual Snake2CamelObjectWriter* RenderNull(StringPiece name) {
- ow_->RenderNull(ShouldNormalizeCase(name) ? StringPiece(ToCamelCase(name))
- : name);
+ ow_->RenderNull(name);
return this;
}
diff --git a/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc b/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc
index 67388c3b..e5db844c 100644
--- a/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc
+++ b/src/google/protobuf/util/internal/snake2camel_objectwriter_test.cc
@@ -47,263 +47,9 @@ class Snake2CamelObjectWriterTest : public ::testing::Test {
Snake2CamelObjectWriter testing_;
};
-TEST_F(Snake2CamelObjectWriterTest, Empty) {
- // Set expectation
- expects_.StartObject("")->EndObject();
-
- // Actual testing
- testing_.StartObject("")->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, UnderscoresOnly) {
- // Set expectation
- expects_.StartObject("")
- ->RenderInt32("", 1)
- ->RenderInt32("", 2)
- ->RenderInt32("", 3)
- ->RenderInt32("", 4)
- ->RenderInt32("", 5)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderInt32("_", 1)
- ->RenderInt32("__", 2)
- ->RenderInt32("___", 3)
- ->RenderInt32("____", 4)
- ->RenderInt32("_____", 5)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, LowercaseOnly) {
- // Set expectation
- expects_.StartObject("")
- ->RenderString("key", "value")
- ->RenderString("abracadabra", "magic")
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderString("key", "value")
- ->RenderString("abracadabra", "magic")
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, UppercaseOnly) {
- // Set expectation
- expects_.StartObject("")
- ->RenderString("key", "VALUE")
- ->RenderString("abracadabra", "MAGIC")
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderString("KEY", "VALUE")
- ->RenderString("ABRACADABRA", "MAGIC")
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, CamelCase) {
- // Set expectation
- expects_.StartObject("")
- ->RenderString("camelCase", "camelCase")
- ->RenderString("theQuickBrownFoxJumpsOverTheLazyDog",
- "theQuickBrownFoxJumpsOverTheLazyDog")
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderString("camelCase", "camelCase")
- ->RenderString("theQuickBrownFoxJumpsOverTheLazyDog",
- "theQuickBrownFoxJumpsOverTheLazyDog")
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, FirstCapCamelCase) {
- // Sets expectation
- expects_.StartObject("camel")
- ->RenderString("camelCase", "CamelCase")
- ->RenderString("theQuickBrownFoxJumpsOverTheLazyDog",
- "TheQuickBrownFoxJumpsOverTheLazyDog")
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("Camel")
- ->RenderString("CamelCase", "CamelCase")
- ->RenderString("TheQuickBrownFoxJumpsOverTheLazyDog",
- "TheQuickBrownFoxJumpsOverTheLazyDog")
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, LastCapCamelCase) {
- // Sets expectation
- expects_.StartObject("lastCapCamelCasE")->EndObject();
-
- // Actual testing
- testing_.StartObject("lastCapCamelCasE")->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, MixedCapCamelCase) {
- // Sets expectation
- expects_.StartObject("googleIsTheBest")
- ->RenderFloat("iLoveGOOGLE", 1.61803f)
- ->RenderFloat("goGoogleGO", 2.71828f)
- ->RenderFloat("gBikeISCool", 3.14159f)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("GOOGLEIsTheBest")
- ->RenderFloat("ILoveGOOGLE", 1.61803f)
- ->RenderFloat("GOGoogleGO", 2.71828f)
- ->RenderFloat("GBikeISCool", 3.14159f)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, MixedCase) {
- // Sets expectation
- expects_.StartObject("snakeCaseCamelCase")
- ->RenderBool("camelCaseSnakeCase", false)
- ->RenderBool("mixedCamelAndUnderScores", false)
- ->RenderBool("goGOOGLEGo", true)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("snake_case_camelCase")
- ->RenderBool("camelCase_snake_case", false)
- ->RenderBool("MixedCamel_And_UnderScores", false)
- ->RenderBool("Go_GOOGLEGo", true)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, SnakeCase) {
- // Sets expectation
- expects_.StartObject("")
- ->RenderString("snakeCase", "snake_case")
- ->RenderString("theQuickBrownFoxJumpsOverTheLazyDog",
- "the_quick_brown_fox_jumps_over_the_lazy_dog")
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderString("snake_case", "snake_case")
- ->RenderString("the_quick_brown_fox_jumps_over_the_lazy_dog",
- "the_quick_brown_fox_jumps_over_the_lazy_dog")
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, FirstCapSnakeCase) {
- // Sets expectation
- expects_.StartObject("firstCapSnakeCase")
- ->RenderBool("helloWorld", true)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("First_Cap_Snake_Case")
- ->RenderBool("Hello_World", true)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, AllCapSnakeCase) {
- // Sets expectation
- expects_.StartObject("allCAPSNAKECASE")
- ->RenderDouble("nyseGOOGL", 600.0L)
- ->RenderDouble("aBCDE", 1.0L)
- ->RenderDouble("klMNOP", 2.0L)
- ->RenderDouble("abcIJKPQRXYZ", 3.0L)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("ALL_CAP_SNAKE_CASE")
- ->RenderDouble("NYSE_GOOGL", 600.0L)
- ->RenderDouble("A_B_C_D_E", 1.0L)
- ->RenderDouble("KL_MN_OP", 2.0L)
- ->RenderDouble("ABC_IJK_PQR_XYZ", 3.0L)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, RepeatedUnderScoreSnakeCase) {
- // Sets expectation
- expects_.StartObject("")
- ->RenderInt32("doubleUnderscoreSnakeCase", 2)
- ->RenderInt32("tripleUnderscoreFirstCap", 3)
- ->RenderInt32("quadrupleUNDERSCOREALLCAP", 4)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderInt32("double__underscore__snake__case", 2)
- ->RenderInt32("Triple___Underscore___First___Cap", 3)
- ->RenderInt32("QUADRUPLE____UNDERSCORE____ALL____CAP", 4)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, LeadingUnderscoreSnakeCase) {
- // Sets expectation
- expects_.StartObject("leadingUnderscoreSnakeCase")
- ->RenderUint32("leadingDoubleUnderscore", 2)
- ->RenderUint32("leadingTripleUnderscoreFirstCap", 3)
- ->RenderUint32("leadingQUADRUPLEUNDERSCOREALLCAP", 4)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("_leading_underscore_snake_case")
- ->RenderUint32("__leading_double_underscore", 2)
- ->RenderUint32("___Leading_Triple_Underscore_First_Cap", 3)
- ->RenderUint32("____LEADING_QUADRUPLE_UNDERSCORE_ALL_CAP", 4)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, TrailingUnderscoreSnakeCase) {
- // Sets expectation
- expects_.StartObject("trailingUnderscoreSnakeCase")
- ->RenderInt64("trailingDoubleUnderscore", 2L)
- ->RenderInt64("trailingTripleUnderscoreFirstCap", 3L)
- ->RenderInt64("trailingQUADRUPLEUNDERSCOREALLCAP", 4L)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("trailing_underscore_snake_case")
- ->RenderInt64("trailing_double_underscore__", 2L)
- ->RenderInt64("Trailing_Triple_Underscore_First_Cap___", 3L)
- ->RenderInt64("TRAILING_QUADRUPLE_UNDERSCORE_ALL_CAP____", 4L)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, EnclosingUnderscoreSnakeCase) {
- // Sets expectation
- expects_.StartObject("enclosingUnderscoreSnakeCase")
- ->RenderUint64("enclosingDoubleUnderscore", 2L)
- ->RenderUint64("enclosingTripleUnderscoreFirstCap", 3L)
- ->RenderUint64("enclosingQUADRUPLEUNDERSCOREALLCAP", 4L)
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("_enclosing_underscore_snake_case_")
- ->RenderUint64("__enclosing_double_underscore__", 2L)
- ->RenderUint64("___Enclosing_Triple_Underscore_First_Cap___", 3L)
- ->RenderUint64("____ENCLOSING_QUADRUPLE_UNDERSCORE_ALL_CAP____", 4L)
- ->EndObject();
-}
-
-TEST_F(Snake2CamelObjectWriterTest, DisableCaseNormalizationOnlyDisablesFirst) {
- // Sets expectation
- expects_.StartObject("")
- ->RenderString("snakeCase", "snake_case")
- ->RenderString(
- "the_quick_brown_fox_jumps_over_the_lazy_dog", // case retained
- "the_quick_brown_fox_jumps_over_the_lazy_dog")
- ->RenderBool("theSlowFox", true) // disable case not in effect
- ->EndObject();
-
- // Actual testing
- testing_.StartObject("")
- ->RenderString("snake_case", "snake_case")
- ->DisableCaseNormalizationForNextKey()
- ->RenderString("the_quick_brown_fox_jumps_over_the_lazy_dog",
- "the_quick_brown_fox_jumps_over_the_lazy_dog")
- ->RenderBool("the_slow_fox", true)
- ->EndObject();
-}
+// All tests are deleted as they are no longer needed. This file will be removed
+// after the component dependecies are cleaned up.
+// TODO(skarvaje): Remove this file.
} // namespace converter
} // namespace util
diff --git a/src/google/protobuf/util/internal/testdata/default_value.proto b/src/google/protobuf/util/internal/testdata/default_value.proto
index ecfc8119..ebbdf6ab 100644
--- a/src/google/protobuf/util/internal/testdata/default_value.proto
+++ b/src/google/protobuf/util/internal/testdata/default_value.proto
@@ -43,6 +43,7 @@ message DefaultValueTestCases {
DoubleMessage repeated_double = 4;
DoubleMessage nested_message = 5;
DoubleMessage repeated_nested_message = 6;
+ DoubleMessage double_message_with_oneof = 7;
StructMessage empty_struct = 201;
StructMessage empty_struct2 = 202;
StructMessage struct_with_null_value = 203;
@@ -75,6 +76,8 @@ message DefaultValueTestCases {
MixedMap mixed1 = 404;
MixedMap2 mixed2 = 405;
MessageMap map_of_objects = 406;
+ MixedMap mixed_empty = 407;
+ MessageMap message_map_empty = 408;
DoubleValueMessage double_value = 501;
DoubleValueMessage double_value_default = 502;
}
@@ -85,6 +88,10 @@ message DoubleMessage {
DoubleMessage nested_message = 3;
repeated DoubleMessage repeated_nested_message = 4;
google.protobuf.DoubleValue double_wrapper = 100;
+ oneof value {
+ string str_value = 112;
+ int64 num_value = 113;
+ }
}
message StructMessage {
diff --git a/src/google/protobuf/util/internal/testdata/oneofs.proto b/src/google/protobuf/util/internal/testdata/oneofs.proto
new file mode 100644
index 00000000..5bc9fa08
--- /dev/null
+++ b/src/google/protobuf/util/internal/testdata/oneofs.proto
@@ -0,0 +1,68 @@
+// 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.
+
+// Proto to test oneofs.
+syntax = "proto3";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/timestamp.proto";
+
+package google.protobuf.testing.oneofs;
+option java_package = "com.google.protobuf.testing.oneofs";
+
+message OneOfsRequest {
+ string value = 1;
+ oneof data {
+ string str_data = 2;
+ int32 int_data = 3;
+ // Simple message
+ Data message_data = 4;
+ // Well known types
+ google.protobuf.Struct struct_data = 5;
+ google.protobuf.Value value_data = 6;
+ google.protobuf.ListValue list_value_data = 7;
+ google.protobuf.Timestamp ts_data = 8;
+ }
+ google.protobuf.Any any_data = 19;
+}
+
+message Data {
+ int32 data_value = 1;
+}
+
+message Response {
+ string value = 1;
+}
+
+service TestService {
+ // Test call.
+ rpc Call(OneOfsRequest) returns (Response);
+}
diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc
index 6392e18c..a45a76e3 100644
--- a/src/google/protobuf/util/internal/type_info.cc
+++ b/src/google/protobuf/util/internal/type_info.cc
@@ -35,11 +35,11 @@
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/type.pb.h>
+#include <google/protobuf/util/internal/utility.h>
#include <google/protobuf/stubs/stringpiece.h>
#include <google/protobuf/stubs/map_util.h>
#include <google/protobuf/stubs/status.h>
#include <google/protobuf/stubs/statusor.h>
-#include <google/protobuf/util/internal/utility.h>
namespace google {
namespace protobuf {
@@ -47,7 +47,6 @@ namespace util {
namespace converter {
namespace {
-
// A TypeInfo that looks up information provided by a TypeResolver.
class TypeInfoForTypeResolver : public TypeInfo {
public:
@@ -60,7 +59,7 @@ class TypeInfoForTypeResolver : public TypeInfo {
}
virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
- StringPiece type_url) {
+ StringPiece type_url) const {
map<StringPiece, StatusOrType>::iterator it = cached_types_.find(type_url);
if (it != cached_types_.end()) {
return it->second;
@@ -78,12 +77,14 @@ class TypeInfoForTypeResolver : public TypeInfo {
return result;
}
- virtual const google::protobuf::Type* GetType(StringPiece type_url) {
+ virtual const google::protobuf::Type* GetTypeByTypeUrl(
+ StringPiece type_url) const {
StatusOrType result = ResolveTypeUrl(type_url);
return result.ok() ? result.ValueOrDie() : NULL;
}
- virtual const google::protobuf::Enum* GetEnum(StringPiece type_url) {
+ virtual const google::protobuf::Enum* GetEnumByTypeUrl(
+ StringPiece type_url) const {
map<StringPiece, StatusOrEnum>::iterator it = cached_enums_.find(type_url);
if (it != cached_enums_.end()) {
return it->second.ok() ? it->second.ValueOrDie() : NULL;
@@ -103,7 +104,7 @@ class TypeInfoForTypeResolver : public TypeInfo {
}
virtual const google::protobuf::Field* FindField(
- const google::protobuf::Type* type, StringPiece camel_case_name) {
+ const google::protobuf::Type* type, StringPiece camel_case_name) const {
if (indexed_types_.find(type) == indexed_types_.end()) {
PopulateNameLookupTable(type);
indexed_types_.insert(type);
@@ -131,7 +132,7 @@ class TypeInfoForTypeResolver : public TypeInfo {
}
}
- void PopulateNameLookupTable(const google::protobuf::Type* type) {
+ void PopulateNameLookupTable(const google::protobuf::Type* type) const {
for (int i = 0; i < type->fields_size(); ++i) {
const google::protobuf::Field& field = type->fields(i);
StringPiece name = field.name();
@@ -151,13 +152,13 @@ class TypeInfoForTypeResolver : public TypeInfo {
// Stores string values that will be referenced by StringPieces in
// cached_types_, cached_enums_ and camel_case_name_table_.
- set<string> string_storage_;
+ mutable set<string> string_storage_;
- map<StringPiece, StatusOrType> cached_types_;
- map<StringPiece, StatusOrEnum> cached_enums_;
+ mutable map<StringPiece, StatusOrType> cached_types_;
+ mutable map<StringPiece, StatusOrEnum> cached_enums_;
- set<const google::protobuf::Type*> indexed_types_;
- map<StringPiece, StringPiece> camel_case_name_table_;
+ mutable set<const google::protobuf::Type*> indexed_types_;
+ mutable map<StringPiece, StringPiece> camel_case_name_table_;
};
} // namespace
diff --git a/src/google/protobuf/util/internal/type_info.h b/src/google/protobuf/util/internal/type_info.h
index 67403fff..d8133176 100644
--- a/src/google/protobuf/util/internal/type_info.h
+++ b/src/google/protobuf/util/internal/type_info.h
@@ -55,24 +55,29 @@ class LIBPROTOBUF_EXPORT TypeInfo {
//
// This TypeInfo class retains the ownership of the returned pointer.
virtual util::StatusOr<const google::protobuf::Type*> ResolveTypeUrl(
- StringPiece type_url) = 0;
+ StringPiece type_url) const = 0;
// Resolves a type url into a Type. Like ResolveTypeUrl() but returns
// NULL if the type url is invalid or the type cannot be found.
//
// This TypeInfo class retains the ownership of the returned pointer.
- virtual const google::protobuf::Type* GetType(StringPiece type_url) = 0;
+ virtual const google::protobuf::Type* GetTypeByTypeUrl(
+ StringPiece type_url) const = 0;
// Resolves a type url for an enum. Returns NULL if the type url is
// invalid or the type cannot be found.
//
// This TypeInfo class retains the ownership of the returned pointer.
- virtual const google::protobuf::Enum* GetEnum(StringPiece type_url) = 0;
+ virtual const google::protobuf::Enum* GetEnumByTypeUrl(
+ StringPiece type_url) const = 0;
// Looks up a field in the specified type given a CamelCase name.
virtual const google::protobuf::Field* FindField(
- const google::protobuf::Type* type, StringPiece camel_case_name) = 0;
+ const google::protobuf::Type* type,
+ StringPiece camel_case_name) const = 0;
+ // Creates a TypeInfo object that looks up type information from a
+ // TypeResolver. Caller takes ownership of the returned pointer.
static TypeInfo* NewTypeInfo(TypeResolver* type_resolver);
private:
diff --git a/src/google/protobuf/util/internal/type_info_test_helper.cc b/src/google/protobuf/util/internal/type_info_test_helper.cc
index 177b96e2..1b9c5154 100644
--- a/src/google/protobuf/util/internal/type_info_test_helper.cc
+++ b/src/google/protobuf/util/internal/type_info_test_helper.cc
@@ -36,6 +36,7 @@
#endif
#include <vector>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/util/internal/default_value_objectwriter.h>
@@ -89,7 +90,7 @@ TypeInfo* TypeInfoTestHelper::GetTypeInfo() { return typeinfo_.get(); }
ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
io::CodedInputStream* coded_input, const string& type_url) {
- const google::protobuf::Type* type = typeinfo_->GetType(type_url);
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
switch (type_) {
case USE_TYPE_RESOLVER: {
return new ProtoStreamObjectSource(coded_input, type_resolver_.get(),
@@ -103,7 +104,7 @@ ProtoStreamObjectSource* TypeInfoTestHelper::NewProtoSource(
ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
const string& type_url, strings::ByteSink* output,
ErrorListener* listener) {
- const google::protobuf::Type* type = typeinfo_->GetType(type_url);
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
switch (type_) {
case USE_TYPE_RESOLVER: {
return new ProtoStreamObjectWriter(type_resolver_.get(), *type, output,
@@ -116,7 +117,7 @@ ProtoStreamObjectWriter* TypeInfoTestHelper::NewProtoWriter(
DefaultValueObjectWriter* TypeInfoTestHelper::NewDefaultValueWriter(
const string& type_url, ObjectWriter* writer) {
- const google::protobuf::Type* type = typeinfo_->GetType(type_url);
+ const google::protobuf::Type* type = typeinfo_->GetTypeByTypeUrl(type_url);
switch (type_) {
case USE_TYPE_RESOLVER: {
return new DefaultValueObjectWriter(type_resolver_.get(), *type, writer);
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index 794777d4..5d7dcc87 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -30,11 +30,9 @@
#include <google/protobuf/util/internal/utility.h>
-#include <cmath>
-#include <algorithm>
-#include <utility>
-
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/wrappers.pb.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
@@ -301,15 +299,15 @@ bool IsMap(const google::protobuf::Field& field,
}
string DoubleAsString(double value) {
- if (value == std::numeric_limits<double>::infinity()) return "Infinity";
- if (value == -std::numeric_limits<double>::infinity()) return "-Infinity";
+ if (google::protobuf::MathLimits<double>::IsPosInf(value)) return "Infinity";
+ if (google::protobuf::MathLimits<double>::IsNegInf(value)) return "-Infinity";
if (google::protobuf::MathLimits<double>::IsNaN(value)) return "NaN";
return SimpleDtoa(value);
}
string FloatAsString(float value) {
- if (isfinite(value)) return SimpleFtoa(value);
+ if (google::protobuf::MathLimits<float>::IsFinite(value)) return SimpleFtoa(value);
return DoubleAsString(value);
}
@@ -320,8 +318,7 @@ bool SafeStrToFloat(StringPiece str, float *value) {
}
*value = static_cast<float>(double_value);
- if ((*value == numeric_limits<float>::infinity()) ||
- (*value == -numeric_limits<float>::infinity())) {
+ if (google::protobuf::MathLimits<float>::IsInf(*value)) {
return false;
}
return true;
diff --git a/src/google/protobuf/util/internal/utility.h b/src/google/protobuf/util/internal/utility.h
index d0d88c19..87f7602a 100644
--- a/src/google/protobuf/util/internal/utility.h
+++ b/src/google/protobuf/util/internal/utility.h
@@ -39,6 +39,7 @@
#include <utility>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/type.pb.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/stubs/stringpiece.h>
@@ -117,23 +118,23 @@ LIBPROTOBUF_EXPORT const string GetFullTypeWithUrl(StringPiece simple_type);
// Finds and returns option identified by name and option_name within the
// provided map. Returns NULL if none found.
-LIBPROTOBUF_EXPORT const google::protobuf::Option* FindOptionOrNull(
+const google::protobuf::Option* FindOptionOrNull(
const google::protobuf::RepeatedPtrField<google::protobuf::Option>& options,
const string& option_name);
// Finds and returns the field identified by field_name in the passed tech Type
// object. Returns NULL if none found.
-LIBPROTOBUF_EXPORT const google::protobuf::Field* FindFieldInTypeOrNull(
+const google::protobuf::Field* FindFieldInTypeOrNull(
const google::protobuf::Type* type, StringPiece field_name);
// Finds and returns the EnumValue identified by enum_name in the passed tech
// Enum object. Returns NULL if none found.
-LIBPROTOBUF_EXPORT const google::protobuf::EnumValue* FindEnumValueByNameOrNull(
+const google::protobuf::EnumValue* FindEnumValueByNameOrNull(
const google::protobuf::Enum* enum_type, StringPiece enum_name);
// Finds and returns the EnumValue identified by value in the passed tech
// Enum object. Returns NULL if none found.
-LIBPROTOBUF_EXPORT const google::protobuf::EnumValue* FindEnumValueByNumberOrNull(
+const google::protobuf::EnumValue* FindEnumValueByNumberOrNull(
const google::protobuf::Enum* enum_type, int32 value);
// Converts input to camel-case and returns it.
@@ -153,7 +154,7 @@ LIBPROTOBUF_EXPORT bool IsWellKnownType(const string& type_name);
LIBPROTOBUF_EXPORT bool IsValidBoolString(const string& bool_string);
// Returns true if "field" is a protobuf map field based on its type.
-bool IsMap(const google::protobuf::Field& field,
+LIBPROTOBUF_EXPORT bool IsMap(const google::protobuf::Field& field,
const google::protobuf::Type& type);
// Infinity/NaN-aware conversion to string.
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index 6796ea08..1718bfb5 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -44,7 +44,7 @@ class ZeroCopyOutputStream;
} // namespace io
namespace util {
-struct LIBPROTOBUF_EXPORT JsonOptions {
+struct JsonOptions {
// Whether to add spaces, line breaks and indentation to make the JSON output
// easy to read.
bool add_whitespace;
@@ -65,7 +65,7 @@ struct LIBPROTOBUF_EXPORT JsonOptions {
// 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.
-LIBPROTOBUF_EXPORT util::Status BinaryToJsonStream(
+util::Status BinaryToJsonStream(
TypeResolver* resolver,
const string& type_url,
io::ZeroCopyInputStream* binary_input,
@@ -101,7 +101,7 @@ inline util::Status BinaryToJsonString(TypeResolver* resolver,
// 2. input is not valid JSON format, or conflicts with the type
// information returned by TypeResolver.
// 3. input has unknown fields.
-LIBPROTOBUF_EXPORT util::Status JsonToBinaryStream(
+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 6686416c..f4dc3562 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -99,27 +99,28 @@ TEST_F(JsonUtilTest, TestWhitespaces) {
ToJson(m, options));
}
-TEST_F(JsonUtilTest, TestDefaultValues) {
- TestMessage m;
- JsonOptions options;
- EXPECT_EQ("{}", ToJson(m, options));
- options.always_print_primitive_fields = true;
- EXPECT_EQ(
- "{\"boolValue\":false,"
- "\"int32Value\":0,"
- "\"int64Value\":\"0\","
- "\"uint32Value\":0,"
- "\"uint64Value\":\"0\","
- "\"floatValue\":0,"
- "\"doubleValue\":0,"
- "\"stringValue\":\"\","
- "\"bytesValue\":\"\","
- // TODO(xiaofeng): The default enum value should be FOO. I believe
- // this is a bug in DefaultValueObjectWriter.
- "\"enumValue\":null"
- "}",
- ToJson(m, options));
-}
+// TODO(skarvaje): Uncomment after cl/96232915 is submitted.
+// TEST_F(JsonUtilTest, TestDefaultValues) {
+ // TestMessage m;
+ // JsonOptions options;
+ // EXPECT_EQ("{}", ToJson(m, options));
+ // options.always_print_primitive_fields = true;
+ // EXPECT_EQ(
+ // "{\"boolValue\":false,"
+ // "\"int32Value\":0,"
+ // "\"int64Value\":\"0\","
+ // "\"uint32Value\":0,"
+ // "\"uint64Value\":\"0\","
+ // "\"floatValue\":0,"
+ // "\"doubleValue\":0,"
+ // "\"stringValue\":\"\","
+ // "\"bytesValue\":\"\","
+ // // TODO(xiaofeng): The default enum value should be FOO. I believe
+ // // this is a bug in DefaultValueObjectWriter.
+ // "\"enumValue\":null"
+ // "}",
+ // ToJson(m, options));
+// }
TEST_F(JsonUtilTest, ParseMessage) {
// Some random message but good enough to verify that the parsing warpper
diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc
index 057b414a..d709da57 100644
--- a/src/google/protobuf/util/message_differencer.cc
+++ b/src/google/protobuf/util/message_differencer.cc
@@ -45,6 +45,7 @@
#endif
#include <utility>
+#include <google/protobuf/stubs/callback.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/any.h>
diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc
index bd19f695..701b94ae 100755
--- a/src/google/protobuf/util/message_differencer_unittest.cc
+++ b/src/google/protobuf/util/message_differencer_unittest.cc
@@ -52,6 +52,7 @@
#include <google/protobuf/map_test_util.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/testing/googletest.h>
@@ -131,7 +132,7 @@ TEST(MessageDifferencerTest, MapFieldEqualityTest) {
unittest::TestMap msg1;
unittest::TestMap msg2;
- MapTestUtil::MapReflectionTester tester(unittest::TestMap::descriptor());
+ MapReflectionTester tester(unittest::TestMap::descriptor());
tester.SetMapFieldsViaReflection(&msg1);
tester.SetMapFieldsViaReflection(&msg2);
tester.SwapMapsViaReflection(&msg1);
diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc
new file mode 100644
index 00000000..c782d691
--- /dev/null
+++ b/src/google/protobuf/util/time_util.cc
@@ -0,0 +1,525 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/time_util.h>
+
+#include <google/protobuf/stubs/time.h>
+#include <google/protobuf/stubs/int128.h>
+#include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stringprintf.h>
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/timestamp.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::Timestamp;
+using google::protobuf::Duration;
+
+namespace {
+static const int kNanosPerSecond = 1000000000;
+static const int kMicrosPerSecond = 1000000;
+static const int kMillisPerSecond = 1000;
+static const int kNanosPerMillisecond = 1000000;
+static const int kMicrosPerMillisecond = 1000;
+static const int kNanosPerMicrosecond = 1000;
+static const int kSecondsPerMinute = 60; // Note that we ignore leap seconds.
+static const int kSecondsPerHour = 3600;
+static const char kTimestampFormat[] = "%E4Y-%m-%dT%H:%M:%S";
+
+template <typename T>
+T CreateNormalized(int64 seconds, int64 nanos);
+
+template <>
+Timestamp CreateNormalized(int64 seconds, int64 nanos) {
+ // Make sure nanos is in the range.
+ if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
+ seconds += nanos / kNanosPerSecond;
+ nanos = nanos % kNanosPerSecond;
+ }
+ // For Timestamp nanos should be in the range [0, 999999999]
+ if (nanos < 0) {
+ seconds -= 1;
+ nanos += kNanosPerSecond;
+ }
+ GOOGLE_DCHECK(seconds >= TimeUtil::kTimestampMinSeconds &&
+ seconds <= TimeUtil::kTimestampMaxSeconds);
+ Timestamp result;
+ result.set_seconds(seconds);
+ result.set_nanos(static_cast<int32>(nanos));
+ return result;
+}
+
+template <>
+Duration CreateNormalized(int64 seconds, int64 nanos) {
+ // Make sure nanos is in the range.
+ if (nanos <= -kNanosPerSecond || nanos >= kNanosPerSecond) {
+ seconds += nanos / kNanosPerSecond;
+ nanos = nanos % kNanosPerSecond;
+ }
+ // nanos should have the same sign as seconds.
+ if (seconds < 0 && nanos > 0) {
+ seconds += 1;
+ nanos -= kNanosPerSecond;
+ } else if (seconds > 0 && nanos < 0) {
+ seconds -= 1;
+ nanos += kNanosPerSecond;
+ }
+ GOOGLE_DCHECK(seconds >= TimeUtil::kDurationMinSeconds &&
+ seconds <= TimeUtil::kDurationMaxSeconds);
+ Duration result;
+ result.set_seconds(seconds);
+ result.set_nanos(static_cast<int32>(nanos));
+ return result;
+}
+
+// Format nanoseconds with either 3, 6, or 9 digits depending on the required
+// precision to represent the exact value.
+string FormatNanos(int32 nanos) {
+ if (nanos % kNanosPerMillisecond == 0) {
+ return StringPrintf("%03d", nanos / kNanosPerMillisecond);
+ } else if (nanos % kNanosPerMicrosecond == 0) {
+ return StringPrintf("%06d", nanos / kNanosPerMicrosecond);
+ } else {
+ return StringPrintf("%09d", nanos);
+ }
+}
+
+string FormatTime(int64 seconds, int32 nanos) {
+ return ::google::protobuf::internal::FormatTime(seconds, nanos);
+}
+
+bool ParseTime(const string& value, int64* seconds, int32* nanos) {
+ return ::google::protobuf::internal::ParseTime(value, seconds, nanos);
+}
+
+void CurrentTime(int64* seconds, int32* nanos) {
+ return ::google::protobuf::internal::GetCurrentTime(seconds, nanos);
+}
+
+// Truncates the remainder part after division.
+int64 RoundTowardZero(int64 value, int64 divider) {
+ int64 result = value / divider;
+ int64 remainder = value % divider;
+ // Before C++11, the sign of the remainder is implementation dependent if
+ // any of the operands is negative. Here we try to enforce C++11's "rounded
+ // toward zero" semantics. For example, for (-5) / 2 an implementation may
+ // give -3 as the result with the remainder being 1. This function ensures
+ // we always return -2 (closer to zero) regardless of the implementation.
+ if (result < 0 && remainder > 0) {
+ return result + 1;
+ } else {
+ return result;
+ }
+}
+} // namespace
+
+string TimeUtil::ToString(const Timestamp& timestamp) {
+ return FormatTime(timestamp.seconds(), timestamp.nanos());
+}
+
+bool TimeUtil::FromString(const string& value, Timestamp* timestamp) {
+ int64 seconds;
+ int32 nanos;
+ if (!ParseTime(value, &seconds, &nanos)) {
+ return false;
+ }
+ *timestamp = CreateNormalized<Timestamp>(seconds, nanos);
+ return true;
+}
+
+Timestamp TimeUtil::GetCurrentTime() {
+ int64 seconds;
+ int32 nanos;
+ CurrentTime(&seconds, &nanos);
+ return CreateNormalized<Timestamp>(seconds, nanos);
+}
+
+Timestamp TimeUtil::GetEpoch() { return Timestamp(); }
+
+string TimeUtil::ToString(const Duration& duration) {
+ string result;
+ int64 seconds = duration.seconds();
+ int32 nanos = duration.nanos();
+ if (seconds < 0 || nanos < 0) {
+ result += "-";
+ seconds = -seconds;
+ nanos = -nanos;
+ }
+ result += StringPrintf("%" GOOGLE_LL_FORMAT "d", seconds);
+ if (nanos != 0) {
+ result += "." + FormatNanos(nanos);
+ }
+ result += "s";
+ return result;
+}
+
+static int64 Pow(int64 x, int y) {
+ int64 result = 1;
+ for (int i = 0; i < y; ++i) {
+ result *= x;
+ }
+ return result;
+}
+
+bool TimeUtil::FromString(const string& value, Duration* duration) {
+ if (value.length() <= 1 || value[value.length() - 1] != 's') {
+ return false;
+ }
+ bool negative = (value[0] == '-');
+ int sign_length = (negative ? 1 : 0);
+ // Parse the duration value as two integers rather than a float value
+ // to avoid precision loss.
+ string seconds_part, nanos_part;
+ size_t pos = value.find_last_of(".");
+ if (pos == string::npos) {
+ seconds_part = value.substr(sign_length, value.length() - 1 - sign_length);
+ nanos_part = "0";
+ } else {
+ seconds_part = value.substr(sign_length, pos - sign_length);
+ nanos_part = value.substr(pos + 1, value.length() - pos - 2);
+ }
+ char* end;
+ int64 seconds = strto64(seconds_part.c_str(), &end, 10);
+ if (end != seconds_part.c_str() + seconds_part.length()) {
+ return false;
+ }
+ int64 nanos = strto64(nanos_part.c_str(), &end, 10);
+ if (end != nanos_part.c_str() + nanos_part.length()) {
+ return false;
+ }
+ nanos = nanos * Pow(10, 9 - nanos_part.length());
+ if (negative) {
+ // If a Duration is negative, both seconds and nanos should be negative.
+ seconds = -seconds;
+ nanos = -nanos;
+ }
+ duration->set_seconds(seconds);
+ duration->set_nanos(static_cast<int32>(nanos));
+ return true;
+}
+
+Duration TimeUtil::NanosecondsToDuration(int64 nanos) {
+ return CreateNormalized<Duration>(nanos / kNanosPerSecond,
+ nanos % kNanosPerSecond);
+}
+
+Duration TimeUtil::MicrosecondsToDuration(int64 micros) {
+ return CreateNormalized<Duration>(
+ micros / kMicrosPerSecond,
+ (micros % kMicrosPerSecond) * kNanosPerMicrosecond);
+}
+
+Duration TimeUtil::MillisecondsToDuration(int64 millis) {
+ return CreateNormalized<Duration>(
+ millis / kMillisPerSecond,
+ (millis % kMillisPerSecond) * kNanosPerMillisecond);
+}
+
+Duration TimeUtil::SecondsToDuration(int64 seconds) {
+ return CreateNormalized<Duration>(seconds, 0);
+}
+
+Duration TimeUtil::MinutesToDuration(int64 minutes) {
+ return CreateNormalized<Duration>(minutes * kSecondsPerMinute, 0);
+}
+
+Duration TimeUtil::HoursToDuration(int64 hours) {
+ return CreateNormalized<Duration>(hours * kSecondsPerHour, 0);
+}
+
+int64 TimeUtil::DurationToNanoseconds(const Duration& duration) {
+ return duration.seconds() * kNanosPerSecond + duration.nanos();
+}
+
+int64 TimeUtil::DurationToMicroseconds(const Duration& duration) {
+ return duration.seconds() * kMicrosPerSecond +
+ RoundTowardZero(duration.nanos(), kNanosPerMicrosecond);
+}
+
+int64 TimeUtil::DurationToMilliseconds(const Duration& duration) {
+ return duration.seconds() * kMillisPerSecond +
+ RoundTowardZero(duration.nanos(), kNanosPerMillisecond);
+}
+
+int64 TimeUtil::DurationToSeconds(const Duration& duration) {
+ return duration.seconds();
+}
+
+int64 TimeUtil::DurationToMinutes(const Duration& duration) {
+ return RoundTowardZero(duration.seconds(), kSecondsPerMinute);
+}
+
+int64 TimeUtil::DurationToHours(const Duration& duration) {
+ return RoundTowardZero(duration.seconds(), kSecondsPerHour);
+}
+
+Timestamp TimeUtil::NanosecondsToTimestamp(int64 nanos) {
+ return CreateNormalized<Timestamp>(nanos / kNanosPerSecond,
+ nanos % kNanosPerSecond);
+}
+
+Timestamp TimeUtil::MicrosecondsToTimestamp(int64 micros) {
+ return CreateNormalized<Timestamp>(
+ micros / kMicrosPerSecond,
+ micros % kMicrosPerSecond * kNanosPerMicrosecond);
+}
+
+Timestamp TimeUtil::MillisecondsToTimestamp(int64 millis) {
+ return CreateNormalized<Timestamp>(
+ millis / kMillisPerSecond,
+ millis % kMillisPerSecond * kNanosPerMillisecond);
+}
+
+Timestamp TimeUtil::SecondsToTimestamp(int64 seconds) {
+ return CreateNormalized<Timestamp>(seconds, 0);
+}
+
+int64 TimeUtil::TimestampToNanoseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kNanosPerSecond + timestamp.nanos();
+}
+
+int64 TimeUtil::TimestampToMicroseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kMicrosPerSecond +
+ RoundTowardZero(timestamp.nanos(), kNanosPerMicrosecond);
+}
+
+int64 TimeUtil::TimestampToMilliseconds(const Timestamp& timestamp) {
+ return timestamp.seconds() * kMillisPerSecond +
+ RoundTowardZero(timestamp.nanos(), kNanosPerMillisecond);
+}
+
+int64 TimeUtil::TimestampToSeconds(const Timestamp& timestamp) {
+ return timestamp.seconds();
+}
+
+Timestamp TimeUtil::TimeTToTimestamp(time_t value) {
+ return CreateNormalized<Timestamp>(static_cast<int64>(value), 0);
+}
+
+time_t TimeUtil::TimestampToTimeT(const Timestamp& value) {
+ return static_cast<time_t>(value.seconds());
+}
+
+Timestamp TimeUtil::TimevalToTimestamp(const timeval& value) {
+ return CreateNormalized<Timestamp>(value.tv_sec,
+ value.tv_usec * kNanosPerMicrosecond);
+}
+
+timeval TimeUtil::TimestampToTimeval(const Timestamp& value) {
+ timeval result;
+ result.tv_sec = value.seconds();
+ result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
+ return result;
+}
+
+Duration TimeUtil::TimevalToDuration(const timeval& value) {
+ return CreateNormalized<Duration>(value.tv_sec,
+ value.tv_usec * kNanosPerMicrosecond);
+}
+
+timeval TimeUtil::DurationToTimeval(const Duration& value) {
+ timeval result;
+ result.tv_sec = value.seconds();
+ result.tv_usec = RoundTowardZero(value.nanos(), kNanosPerMicrosecond);
+ // timeval.tv_usec's range is [0, 1000000)
+ if (result.tv_usec < 0) {
+ result.tv_sec -= 1;
+ result.tv_usec += kMicrosPerSecond;
+ }
+ return result;
+}
+
+} // namespace util
+} // namespace protobuf
+
+
+namespace protobuf {
+namespace {
+using google::protobuf::util::kNanosPerSecond;
+using google::protobuf::util::CreateNormalized;
+
+// Convert a Timestamp to uint128.
+void ToUint128(const Timestamp& value, uint128* result, bool* negative) {
+ if (value.seconds() < 0) {
+ *negative = true;
+ *result = static_cast<uint64>(-value.seconds());
+ *result = *result * kNanosPerSecond - static_cast<uint32>(value.nanos());
+ } else {
+ *negative = false;
+ *result = static_cast<uint64>(value.seconds());
+ *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
+ }
+}
+
+// Convert a Duration to uint128.
+void ToUint128(const Duration& value, uint128* result, bool* negative) {
+ if (value.seconds() < 0 || value.nanos() < 0) {
+ *negative = true;
+ *result = static_cast<uint64>(-value.seconds());
+ *result = *result * kNanosPerSecond + static_cast<uint32>(-value.nanos());
+ } else {
+ *negative = false;
+ *result = static_cast<uint64>(value.seconds());
+ *result = *result * kNanosPerSecond + static_cast<uint32>(value.nanos());
+ }
+}
+
+void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) {
+ int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
+ int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
+ if (negative) {
+ seconds = -seconds;
+ nanos = -nanos;
+ if (nanos < 0) {
+ nanos += kNanosPerSecond;
+ seconds -= 1;
+ }
+ }
+ timestamp->set_seconds(seconds);
+ timestamp->set_nanos(nanos);
+}
+
+void ToDuration(const uint128& value, bool negative, Duration* duration) {
+ int64 seconds = static_cast<int64>(Uint128Low64(value / kNanosPerSecond));
+ int32 nanos = static_cast<int32>(Uint128Low64(value % kNanosPerSecond));
+ if (negative) {
+ seconds = -seconds;
+ nanos = -nanos;
+ }
+ duration->set_seconds(seconds);
+ duration->set_nanos(nanos);
+}
+} // namespace
+
+Duration& operator+=(Duration& d1, const Duration& d2) {
+ d1 = CreateNormalized<Duration>(d1.seconds() + d2.seconds(),
+ d1.nanos() + d2.nanos());
+ return d1;
+}
+
+Duration& operator-=(Duration& d1, const Duration& d2) { // NOLINT
+ d1 = CreateNormalized<Duration>(d1.seconds() - d2.seconds(),
+ d1.nanos() - d2.nanos());
+ return d1;
+}
+
+Duration& operator*=(Duration& d, int64 r) { // NOLINT
+ bool negative;
+ uint128 value;
+ ToUint128(d, &value, &negative);
+ if (r > 0) {
+ value *= static_cast<uint64>(r);
+ } else {
+ negative = !negative;
+ value *= static_cast<uint64>(-r);
+ }
+ ToDuration(value, negative, &d);
+ return d;
+}
+
+Duration& operator*=(Duration& d, double r) { // NOLINT
+ double result = (d.seconds() * 1.0 + 1.0 * d.nanos() / kNanosPerSecond) * r;
+ int64 seconds = static_cast<int64>(result);
+ int32 nanos = static_cast<int32>((result - seconds) * kNanosPerSecond);
+ // Note that we normalize here not just because nanos can have a different
+ // sign from seconds but also that nanos can be any arbitrary value when
+ // overflow happens (i.e., the result is a much larger value than what
+ // int64 can represent).
+ d = CreateNormalized<Duration>(seconds, nanos);
+ return d;
+}
+
+Duration& operator/=(Duration& d, int64 r) { // NOLINT
+ bool negative;
+ uint128 value;
+ ToUint128(d, &value, &negative);
+ if (r > 0) {
+ value /= static_cast<uint64>(r);
+ } else {
+ negative = !negative;
+ value /= static_cast<uint64>(-r);
+ }
+ ToDuration(value, negative, &d);
+ return d;
+}
+
+Duration& operator/=(Duration& d, double r) { // NOLINT
+ return d *= 1.0 / r;
+}
+
+Duration& operator%=(Duration& d1, const Duration& d2) { // NOLINT
+ bool negative1, negative2;
+ uint128 value1, value2;
+ ToUint128(d1, &value1, &negative1);
+ ToUint128(d2, &value2, &negative2);
+ uint128 result = value1 % value2;
+ // When negative values are involved in division, we round the division
+ // result towards zero. With this semantics, sign of the remainder is the
+ // same as the dividend. For example:
+ // -5 / 10 = 0, -5 % 10 = -5
+ // -5 / (-10) = 0, -5 % (-10) = -5
+ // 5 / (-10) = 0, 5 % (-10) = 5
+ ToDuration(result, negative1, &d1);
+ return d1;
+}
+
+int64 operator/(const Duration& d1, const Duration& d2) {
+ bool negative1, negative2;
+ uint128 value1, value2;
+ ToUint128(d1, &value1, &negative1);
+ ToUint128(d2, &value2, &negative2);
+ int64 result = Uint128Low64(value1 / value2);
+ if (negative1 != negative2) {
+ result = -result;
+ }
+ return result;
+}
+
+Timestamp& operator+=(Timestamp& t, const Duration& d) { // NOLINT
+ t = CreateNormalized<Timestamp>(t.seconds() + d.seconds(),
+ t.nanos() + d.nanos());
+ return t;
+}
+
+Timestamp& operator-=(Timestamp& t, const Duration& d) { // NOLINT
+ t = CreateNormalized<Timestamp>(t.seconds() - d.seconds(),
+ t.nanos() - d.nanos());
+ return t;
+}
+
+Duration operator-(const Timestamp& t1, const Timestamp& t2) {
+ return CreateNormalized<Duration>(t1.seconds() - t2.seconds(),
+ t1.nanos() - t2.nanos());
+}
+} // namespace protobuf
+
+} // namespace google
diff --git a/src/google/protobuf/util/time_util.h b/src/google/protobuf/util/time_util.h
new file mode 100644
index 00000000..58dbf8e6
--- /dev/null
+++ b/src/google/protobuf/util/time_util.h
@@ -0,0 +1,296 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+#define GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
+
+#include <ctime>
+#include <ostream>
+#include <string>
+#ifdef _MSC_VER
+#include <winsock2.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/timestamp.pb.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+class LIBPROTOBUF_EXPORT TimeUtil {
+ typedef google::protobuf::Timestamp Timestamp;
+ typedef google::protobuf::Duration Duration;
+
+ public:
+ // The min/max Timestamp/Duration values we support.
+ //
+ // For "0001-01-01T00:00:00Z".
+ static const int64 kTimestampMinSeconds = -62135596800LL;
+ // For "9999-12-31T23:59:59.999999999Z".
+ static const int64 kTimestampMaxSeconds = 253402300799LL;
+ static const int64 kDurationMinSeconds = -315576000000LL;
+ static const int64 kDurationMaxSeconds = 315576000000LL;
+
+ // Converts Timestamp to/from RFC 3339 date string format.
+ // Generated output will always be Z-normalized and uses 3, 6 or 9
+ // fractional digits as required to represent the exact time. When
+ // parsing, any fractional digits (or none) and any offset are
+ // accepted as long as they fit into nano-seconds precision.
+ // Note that Timestamp can only represent time from
+ // 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. Converting
+ // a Timestamp outside of this range is undefined behavior.
+ // See https://www.ietf.org/rfc/rfc3339.txt
+ //
+ // Example of generated format:
+ // "1972-01-01T10:00:20.021Z"
+ //
+ // Example of accepted format:
+ // "1972-01-01T10:00:20.021-05:00"
+ static string ToString(const Timestamp& timestamp);
+ static bool FromString(const string& value, Timestamp* timestamp);
+
+ // Converts Duration to/from string format. The string format will contains
+ // 3, 6, or 9 fractional digits depending on the precision required to
+ // represent the exact Duration value. For example:
+ // "1s", "1.010s", "1.000000100s", "-3.100s"
+ // The range that can be represented by Duration is from -315,576,000,000
+ // to +315,576,000,000 inclusive (in seconds).
+ static string ToString(const Duration& duration);
+ static bool FromString(const string& value, Duration* timestamp);
+
+#ifdef GetCurrentTime
+#undef GetCurrentTime // Visual Studio has macro GetCurrentTime
+#endif
+ // Gets the current UTC time.
+ static Timestamp GetCurrentTime();
+ // Returns the Time representing "1970-01-01 00:00:00".
+ static Timestamp GetEpoch();
+
+ // Converts between Duration and integer types. The behavior is undefined if
+ // the input value is not in the valid range of Duration.
+ static Duration NanosecondsToDuration(int64 nanos);
+ static Duration MicrosecondsToDuration(int64 micros);
+ static Duration MillisecondsToDuration(int64 millis);
+ static Duration SecondsToDuration(int64 seconds);
+ static Duration MinutesToDuration(int64 minutes);
+ static Duration HoursToDuration(int64 hours);
+ // Result will be truncated towards zero. For example, "-1.5s" will be
+ // truncated to "-1s", and "1.5s" to "1s" when converting to seconds.
+ // It's undefined behavior if the input duration is not valid or the result
+ // exceeds the range of int64. A duration is not valid if it's not in the
+ // valid range of Duration, or have an invalid nanos value (i.e., larger
+ // than 999999999, less than -999999999, or have a different sign from the
+ // seconds part).
+ static int64 DurationToNanoseconds(const Duration& duration);
+ static int64 DurationToMicroseconds(const Duration& duration);
+ static int64 DurationToMilliseconds(const Duration& duration);
+ static int64 DurationToSeconds(const Duration& duration);
+ static int64 DurationToMinutes(const Duration& duration);
+ static int64 DurationToHours(const Duration& duration);
+ // Creates Timestamp from integer types. The integer value indicates the
+ // time elapsed from Epoch time. The behavior is undefined if the input
+ // value is not in the valid range of Timestamp.
+ static Timestamp NanosecondsToTimestamp(int64 nanos);
+ static Timestamp MicrosecondsToTimestamp(int64 micros);
+ static Timestamp MillisecondsToTimestamp(int64 millis);
+ static Timestamp SecondsToTimestamp(int64 seconds);
+ // Result will be truncated down to the nearest integer value. For example,
+ // with "1969-12-31T23:59:59.9Z", TimestampToMilliseconds() returns -100
+ // and TimestampToSeconds() returns -1. It's undefined behavior if the input
+ // Timestamp is not valid (i.e., its seconds part or nanos part does not fall
+ // in the valid range) or the return value doesn't fit into int64.
+ static int64 TimestampToNanoseconds(const Timestamp& timestamp);
+ static int64 TimestampToMicroseconds(const Timestamp& timestamp);
+ static int64 TimestampToMilliseconds(const Timestamp& timestamp);
+ static int64 TimestampToSeconds(const Timestamp& timestamp);
+
+ // Conversion to/from other time/date types. Note that these types may
+ // have a different precision and time range from Timestamp/Duration.
+ // When converting to a lower precision type, the value will be truncated
+ // to the nearest value that can be represented. If the value is
+ // out of the range of the result type, the return value is undefined.
+ //
+ // Conversion to/from time_t
+ static Timestamp TimeTToTimestamp(time_t value);
+ static time_t TimestampToTimeT(const Timestamp& value);
+
+ // Conversion to/from timeval
+ static Timestamp TimevalToTimestamp(const timeval& value);
+ static timeval TimestampToTimeval(const Timestamp& value);
+ static Duration TimevalToDuration(const timeval& value);
+ static timeval DurationToTimeval(const Duration& value);
+};
+
+} // namespace util
+} // namespace protobuf
+
+
+namespace protobuf {
+// Overloaded operators for Duration.
+//
+// Assignment operators.
+LIBPROTOBUF_EXPORT Duration& operator+=(Duration& d1, const Duration& d2); // NOLINT
+LIBPROTOBUF_EXPORT Duration& operator-=(Duration& d1, const Duration& d2); // NOLINT
+LIBPROTOBUF_EXPORT Duration& operator*=(Duration& d, int64 r); // NOLINT
+LIBPROTOBUF_EXPORT Duration& operator*=(Duration& d, double r); // NOLINT
+LIBPROTOBUF_EXPORT Duration& operator/=(Duration& d, int64 r); // NOLINT
+LIBPROTOBUF_EXPORT Duration& operator/=(Duration& d, double r); // NOLINT
+// Overload for other integer types.
+template <typename T>
+Duration& operator*=(Duration& d, T r) { // NOLINT
+ int64 x = r;
+ return d *= x;
+}
+template <typename T>
+Duration& operator/=(Duration& d, T r) { // NOLINT
+ int64 x = r;
+ return d /= x;
+}
+LIBPROTOBUF_EXPORT Duration& operator%=(Duration& d1, const Duration& d2); // NOLINT
+// Relational operators.
+inline bool operator<(const Duration& d1, const Duration& d2) {
+ if (d1.seconds() == d2.seconds()) {
+ return d1.nanos() < d2.nanos();
+ }
+ return d1.seconds() < d2.seconds();
+}
+inline bool operator>(const Duration& d1, const Duration& d2) {
+ return d2 < d1;
+}
+inline bool operator>=(const Duration& d1, const Duration& d2) {
+ return !(d1 < d2);
+}
+inline bool operator<=(const Duration& d1, const Duration& d2) {
+ return !(d2 < d1);
+}
+inline bool operator==(const Duration& d1, const Duration& d2) {
+ return d1.seconds() == d2.seconds() && d1.nanos() == d2.nanos();
+}
+inline bool operator!=(const Duration& d1, const Duration& d2) {
+ return !(d1 == d2);
+}
+// Additive operators
+inline Duration operator-(const Duration& d) {
+ Duration result;
+ result.set_seconds(-d.seconds());
+ result.set_nanos(-d.nanos());
+ return result;
+}
+inline Duration operator+(const Duration& d1, const Duration& d2) {
+ Duration result = d1;
+ return result += d2;
+}
+inline Duration operator-(const Duration& d1, const Duration& d2) {
+ Duration result = d1;
+ return result -= d2;
+}
+// Multiplicative operators
+template<typename T>
+inline Duration operator*(Duration d, T r) {
+ return d *= r;
+}
+template<typename T>
+inline Duration operator*(T r, Duration d) {
+ return d *= r;
+}
+template<typename T>
+inline Duration operator/(Duration d, T r) {
+ return d /= r;
+}
+LIBPROTOBUF_EXPORT int64 operator/(const Duration& d1, const Duration& d2);
+
+inline Duration operator%(const Duration& d1, const Duration& d2) {
+ Duration result = d1;
+ return result %= d2;
+}
+
+inline ostream& operator<<(ostream& out, const Duration& d) {
+ out << google::protobuf::util::TimeUtil::ToString(d);
+ return out;
+}
+
+// Overloaded operators for Timestamp
+//
+// Assignement operators.
+LIBPROTOBUF_EXPORT
+Timestamp& operator+=(Timestamp& t, const Duration& d); // NOLINT
+LIBPROTOBUF_EXPORT
+Timestamp& operator-=(Timestamp& t, const Duration& d); // NOLINT
+// Relational operators.
+inline bool operator<(const Timestamp& t1, const Timestamp& t2) {
+ if (t1.seconds() == t2.seconds()) {
+ return t1.nanos() < t2.nanos();
+ }
+ return t1.seconds() < t2.seconds();
+}
+inline bool operator>(const Timestamp& t1, const Timestamp& t2) {
+ return t2 < t1;
+}
+inline bool operator>=(const Timestamp& t1, const Timestamp& t2) {
+ return !(t1 < t2);
+}
+inline bool operator<=(const Timestamp& t1, const Timestamp& t2) {
+ return !(t2 < t1);
+}
+inline bool operator==(const Timestamp& t1, const Timestamp& t2) {
+ return t1.seconds() == t2.seconds() && t1.nanos() == t2.nanos();
+}
+inline bool operator!=(const Timestamp& t1, const Timestamp& t2) {
+ return !(t1 == t2);
+}
+// Additive operators.
+inline Timestamp operator+(const Timestamp& t, const Duration& d) {
+ Timestamp result = t;
+ return result += d;
+}
+inline Timestamp operator+(const Duration& d, const Timestamp& t) {
+ Timestamp result = t;
+ return result += d;
+}
+inline Timestamp operator-(const Timestamp& t, const Duration& d) {
+ Timestamp result = t;
+ return result -= d;
+}
+LIBPROTOBUF_EXPORT Duration operator-(const Timestamp& t1, const Timestamp& t2);
+
+inline ostream& operator<<(ostream& out, const Timestamp& t) {
+ out << google::protobuf::util::TimeUtil::ToString(t);
+ return out;
+}
+
+} // namespace protobuf
+
+
+} // namespace google
+#endif // GOOGLE_PROTOBUF_UTIL_TIME_UTIL_H__
diff --git a/src/google/protobuf/util/time_util_test.cc b/src/google/protobuf/util/time_util_test.cc
new file mode 100644
index 00000000..285740ab
--- /dev/null
+++ b/src/google/protobuf/util/time_util_test.cc
@@ -0,0 +1,380 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <google/protobuf/util/time_util.h>
+
+#include <ctime>
+
+#include <google/protobuf/timestamp.pb.h>
+#include <google/protobuf/duration.pb.h>
+#include <google/protobuf/testing/googletest.h>
+#include <gtest/gtest.h>
+
+namespace google {
+namespace protobuf {
+namespace util {
+
+using google::protobuf::Timestamp;
+using google::protobuf::Duration;
+
+namespace {
+
+TEST(TimeUtilTest, TimestampStringFormat) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_EQ(TimeUtil::kTimestampMinSeconds, begin.seconds());
+ EXPECT_EQ(0, begin.nanos());
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+ EXPECT_EQ(TimeUtil::kTimestampMaxSeconds, end.seconds());
+ EXPECT_EQ(999999999, end.nanos());
+ EXPECT_EQ("0001-01-01T00:00:00Z", TimeUtil::ToString(begin));
+ EXPECT_EQ("9999-12-31T23:59:59.999999999Z", TimeUtil::ToString(end));
+
+ // Test negative timestamps.
+ Timestamp time = TimeUtil::NanosecondsToTimestamp(-1);
+ EXPECT_EQ(-1, time.seconds());
+ // Timestamp's nano part is always non-negative.
+ EXPECT_EQ(999999999, time.nanos());
+ EXPECT_EQ("1969-12-31T23:59:59.999999999Z", TimeUtil::ToString(time));
+
+ // Generated output should contain 3, 6, or 9 fractional digits.
+ EXPECT_EQ("1970-01-01T00:00:00Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(0)));
+ EXPECT_EQ("1970-01-01T00:00:00.010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000000)));
+ EXPECT_EQ("1970-01-01T00:00:00.000010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10000)));
+ EXPECT_EQ("1970-01-01T00:00:00.000000010Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(10)));
+
+ // Parsing accepts an fractional digits as long as they fit into nano
+ // precision.
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.1Z", &time));
+ EXPECT_EQ(100000000, TimeUtil::TimestampToNanoseconds(time));
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0001Z", &time));
+ EXPECT_EQ(100000, TimeUtil::TimestampToNanoseconds(time));
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00.0000001Z", &time));
+ EXPECT_EQ(100, TimeUtil::TimestampToNanoseconds(time));
+
+ // Also accpets offsets.
+ EXPECT_TRUE(TimeUtil::FromString("1970-01-01T00:00:00-08:00", &time));
+ EXPECT_EQ(8 * 3600, TimeUtil::TimestampToSeconds(time));
+}
+
+TEST(TimeUtilTest, DurationStringFormat) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+
+ EXPECT_EQ("315537897599.999999999s", TimeUtil::ToString(end - begin));
+ EXPECT_EQ(999999999, (end - begin).nanos());
+ EXPECT_EQ("-315537897599.999999999s", TimeUtil::ToString(begin - end));
+ EXPECT_EQ(-999999999, (begin - end).nanos());
+
+ // Generated output should contain 3, 6, or 9 fractional digits.
+ EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ("0.010s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(10)));
+ EXPECT_EQ("0.000010s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(10)));
+ EXPECT_EQ("0.000000010s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(10)));
+
+ // Parsing accepts an fractional digits as long as they fit into nano
+ // precision.
+ Duration d;
+ EXPECT_TRUE(TimeUtil::FromString("0.1s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToMilliseconds(d));
+ EXPECT_TRUE(TimeUtil::FromString("0.0001s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToMicroseconds(d));
+ EXPECT_TRUE(TimeUtil::FromString("0.0000001s", &d));
+ EXPECT_EQ(100, TimeUtil::DurationToNanoseconds(d));
+
+ // Duration must support range from -315,576,000,000s to +315576000000s
+ // which includes negative values.
+ EXPECT_TRUE(TimeUtil::FromString("315576000000.999999999s", &d));
+ EXPECT_EQ(315576000000LL, d.seconds());
+ EXPECT_EQ(999999999, d.nanos());
+ EXPECT_TRUE(TimeUtil::FromString("-315576000000.999999999s", &d));
+ EXPECT_EQ(-315576000000LL, d.seconds());
+ EXPECT_EQ(-999999999, d.nanos());
+}
+
+TEST(TimeUtilTest, GetEpoch) {
+ EXPECT_EQ(0, TimeUtil::TimestampToNanoseconds(TimeUtil::GetEpoch()));
+}
+
+TEST(TimeUtilTest, DurationIntegerConversion) {
+ EXPECT_EQ("0.000000001s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(1)));
+ EXPECT_EQ("-0.000000001s",
+ TimeUtil::ToString(TimeUtil::NanosecondsToDuration(-1)));
+ EXPECT_EQ("0.000001s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(1)));
+ EXPECT_EQ("-0.000001s",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToDuration(-1)));
+ EXPECT_EQ("0.001s", TimeUtil::ToString(TimeUtil::MillisecondsToDuration(1)));
+ EXPECT_EQ("-0.001s",
+ TimeUtil::ToString(TimeUtil::MillisecondsToDuration(-1)));
+ EXPECT_EQ("1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ("-1s", TimeUtil::ToString(TimeUtil::SecondsToDuration(-1)));
+ EXPECT_EQ("60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(1)));
+ EXPECT_EQ("-60s", TimeUtil::ToString(TimeUtil::MinutesToDuration(-1)));
+ EXPECT_EQ("3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(1)));
+ EXPECT_EQ("-3600s", TimeUtil::ToString(TimeUtil::HoursToDuration(-1)));
+
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(1)));
+ EXPECT_EQ(
+ -1, TimeUtil::DurationToNanoseconds(TimeUtil::NanosecondsToDuration(-1)));
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToMicroseconds(TimeUtil::MicrosecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::MicrosecondsToDuration(-1)));
+ EXPECT_EQ(
+ 1, TimeUtil::DurationToMilliseconds(TimeUtil::MillisecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMilliseconds(
+ TimeUtil::MillisecondsToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToSeconds(TimeUtil::SecondsToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToMinutes(TimeUtil::MinutesToDuration(-1)));
+ EXPECT_EQ(1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(1)));
+ EXPECT_EQ(-1, TimeUtil::DurationToHours(TimeUtil::HoursToDuration(-1)));
+
+ // Test truncation behavior.
+ EXPECT_EQ(1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::NanosecondsToDuration(1999)));
+ // For negative values, Duration will be rounded towards 0.
+ EXPECT_EQ(-1, TimeUtil::DurationToMicroseconds(
+ TimeUtil::NanosecondsToDuration(-1999)));
+}
+
+TEST(TestUtilTest, TimestampIntegerConversion) {
+ EXPECT_EQ("1970-01-01T00:00:00.000000001Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999999999Z",
+ TimeUtil::ToString(TimeUtil::NanosecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:00.000001Z",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999999Z",
+ TimeUtil::ToString(TimeUtil::MicrosecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:00.001Z",
+ TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59.999Z",
+ TimeUtil::ToString(TimeUtil::MillisecondsToTimestamp(-1)));
+ EXPECT_EQ("1970-01-01T00:00:01Z",
+ TimeUtil::ToString(TimeUtil::SecondsToTimestamp(1)));
+ EXPECT_EQ("1969-12-31T23:59:59Z",
+ TimeUtil::ToString(TimeUtil::SecondsToTimestamp(-1)));
+
+ EXPECT_EQ(
+ 1, TimeUtil::TimestampToNanoseconds(TimeUtil::NanosecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToNanoseconds(
+ TimeUtil::NanosecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::MicrosecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::MicrosecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToMilliseconds(
+ TimeUtil::MillisecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToMilliseconds(
+ TimeUtil::MillisecondsToTimestamp(-1)));
+ EXPECT_EQ(1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(1)));
+ EXPECT_EQ(-1, TimeUtil::TimestampToSeconds(TimeUtil::SecondsToTimestamp(-1)));
+
+ // Test truncation behavior.
+ EXPECT_EQ(1, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::NanosecondsToTimestamp(1999)));
+ // For negative values, Timestamp will be rounded down.
+ // For example, "1969-12-31T23:59:59.5Z" (i.e., -0.5s) rounded to seconds
+ // will be "1969-12-31T23:59:59Z" (i.e., -1s) rather than
+ // "1970-01-01T00:00:00Z" (i.e., 0s).
+ EXPECT_EQ(-2, TimeUtil::TimestampToMicroseconds(
+ TimeUtil::NanosecondsToTimestamp(-1999)));
+}
+
+TEST(TimeUtilTest, TimeTConversion) {
+ time_t value = time(NULL);
+ EXPECT_EQ(value,
+ TimeUtil::TimestampToTimeT(TimeUtil::TimeTToTimestamp(value)));
+ EXPECT_EQ(
+ 1, TimeUtil::TimestampToTimeT(TimeUtil::MillisecondsToTimestamp(1999)));
+}
+
+TEST(TimeUtilTest, TimevalConversion) {
+ timeval value = TimeUtil::TimestampToTimeval(
+ TimeUtil::NanosecondsToTimestamp(1999999999));
+ EXPECT_EQ(1, value.tv_sec);
+ EXPECT_EQ(999999, value.tv_usec);
+ value = TimeUtil::TimestampToTimeval(
+ TimeUtil::NanosecondsToTimestamp(-1999999999));
+ EXPECT_EQ(-2, value.tv_sec);
+ EXPECT_EQ(0, value.tv_usec);
+
+ value =
+ TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(1999999999));
+ EXPECT_EQ(1, value.tv_sec);
+ EXPECT_EQ(999999, value.tv_usec);
+ value =
+ TimeUtil::DurationToTimeval(TimeUtil::NanosecondsToDuration(-1999999999));
+ EXPECT_EQ(-2, value.tv_sec);
+ EXPECT_EQ(1, value.tv_usec);
+}
+
+TEST(TimeUtilTest, DurationOperators) {
+ Duration one_second = TimeUtil::SecondsToDuration(1);
+ Duration one_nano = TimeUtil::NanosecondsToDuration(1);
+
+ // Test +/-
+ Duration a = one_second;
+ a += one_second;
+ a -= one_nano;
+ EXPECT_EQ("1.999999999s", TimeUtil::ToString(a));
+ Duration b = -a;
+ EXPECT_EQ("-1.999999999s", TimeUtil::ToString(b));
+ EXPECT_EQ("3.999999998s", TimeUtil::ToString(a + a));
+ EXPECT_EQ("0s", TimeUtil::ToString(a + b));
+ EXPECT_EQ("0s", TimeUtil::ToString(b + a));
+ EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b + b));
+ EXPECT_EQ("3.999999998s", TimeUtil::ToString(a - b));
+ EXPECT_EQ("0s", TimeUtil::ToString(a - a));
+ EXPECT_EQ("0s", TimeUtil::ToString(b - b));
+ EXPECT_EQ("-3.999999998s", TimeUtil::ToString(b - a));
+
+ // Test *
+ EXPECT_EQ(a + a, a * 2);
+ EXPECT_EQ(b + b, a * (-2));
+ EXPECT_EQ(b + b, b * 2);
+ EXPECT_EQ(a + a, b * (-2));
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(a * 0.5));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b * 0.5));
+ // Multiplication should not overflow if the result fits into the supported
+ // range of Duration (intermediate result may be larger than int64).
+ EXPECT_EQ("315575999684.424s",
+ TimeUtil::ToString((one_second - one_nano) * 315576000000LL));
+ EXPECT_EQ("-315575999684.424s",
+ TimeUtil::ToString((one_nano - one_second) * 315576000000LL));
+ EXPECT_EQ("-315575999684.424s",
+ TimeUtil::ToString((one_second - one_nano) * (-315576000000LL)));
+
+ // Test / and %
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(a / 2));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString(b / 2));
+ Duration large = TimeUtil::SecondsToDuration(315576000000LL) - one_nano;
+ // We have to handle division with values beyond 64 bits.
+ EXPECT_EQ("0.999999999s", TimeUtil::ToString(large / 315576000000LL));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString((-large) / 315576000000LL));
+ EXPECT_EQ("-0.999999999s", TimeUtil::ToString(large / (-315576000000LL)));
+ Duration large2 = large + one_nano;
+ EXPECT_EQ(large, large % large2);
+ EXPECT_EQ(-large, (-large) % large2);
+ EXPECT_EQ(large, large % (-large2));
+ EXPECT_EQ(one_nano, large2 % large);
+ EXPECT_EQ(-one_nano, (-large2) % large);
+ EXPECT_EQ(one_nano, large2 % (-large));
+ // Some corner cases about negative values.
+ //
+ // (-5) / 2 = -2, remainder = -1
+ // (-5) / (-2) = 2, remainder = -1
+ a = TimeUtil::NanosecondsToDuration(-5);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-2), a / 2);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(2), a / (-2));
+ b = TimeUtil::NanosecondsToDuration(2);
+ EXPECT_EQ(-2, a / b);
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % b);
+ EXPECT_EQ(2, a / (-b));
+ EXPECT_EQ(TimeUtil::NanosecondsToDuration(-1), a % (-b));
+
+ // Test relational operators.
+ EXPECT_TRUE(one_nano < one_second);
+ EXPECT_FALSE(one_second < one_second);
+ EXPECT_FALSE(one_second < one_nano);
+ EXPECT_FALSE(-one_nano < -one_second);
+ EXPECT_FALSE(-one_second < -one_second);
+ EXPECT_TRUE(-one_second < -one_nano);
+ EXPECT_TRUE(-one_nano < one_nano);
+ EXPECT_FALSE(one_nano < -one_nano);
+
+ EXPECT_FALSE(one_nano > one_second);
+ EXPECT_FALSE(one_nano > one_nano);
+ EXPECT_TRUE(one_second > one_nano);
+
+ EXPECT_FALSE(one_nano >= one_second);
+ EXPECT_TRUE(one_nano >= one_nano);
+ EXPECT_TRUE(one_second >= one_nano);
+
+ EXPECT_TRUE(one_nano <= one_second);
+ EXPECT_TRUE(one_nano <= one_nano);
+ EXPECT_FALSE(one_second <= one_nano);
+
+ EXPECT_TRUE(one_nano == one_nano);
+ EXPECT_FALSE(one_nano == one_second);
+
+ EXPECT_FALSE(one_nano != one_nano);
+ EXPECT_TRUE(one_nano != one_second);
+}
+
+TEST(TimeUtilTest, TimestampOperators) {
+ Timestamp begin, end;
+ EXPECT_TRUE(TimeUtil::FromString("0001-01-01T00:00:00Z", &begin));
+ EXPECT_TRUE(TimeUtil::FromString("9999-12-31T23:59:59.999999999Z", &end));
+ Duration d = end - begin;
+ EXPECT_TRUE(end == begin + d);
+ EXPECT_TRUE(end == d + begin);
+ EXPECT_TRUE(begin == end - d);
+
+ // Test relational operators
+ Timestamp t1 = begin + d / 4;
+ Timestamp t2 = end - d / 4;
+ EXPECT_TRUE(t1 < t2);
+ EXPECT_FALSE(t1 < t1);
+ EXPECT_FALSE(t2 < t1);
+ EXPECT_FALSE(t1 > t2);
+ EXPECT_FALSE(t1 > t1);
+ EXPECT_TRUE(t2 > t1);
+ EXPECT_FALSE(t1 >= t2);
+ EXPECT_TRUE(t1 >= t1);
+ EXPECT_TRUE(t2 >= t1);
+ EXPECT_TRUE(t1 <= t2);
+ EXPECT_TRUE(t1 <= t1);
+ EXPECT_FALSE(t2 <= t1);
+
+ EXPECT_FALSE(t1 == t2);
+ EXPECT_TRUE(t1 == t1);
+ EXPECT_FALSE(t2 == t1);
+ EXPECT_TRUE(t1 != t2);
+ EXPECT_FALSE(t1 != t1);
+ EXPECT_TRUE(t2 != t1);
+}
+
+} // namespace
+} // namespace util
+} // namespace protobuf
+} // namespace google
diff --git a/src/google/protobuf/util/type_resolver_util.cc b/src/google/protobuf/util/type_resolver_util.cc
index 053a4ed7..908634eb 100644
--- a/src/google/protobuf/util/type_resolver_util.cc
+++ b/src/google/protobuf/util/type_resolver_util.cc
@@ -35,6 +35,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/util/type_resolver.h>
+#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/status.h>
namespace google {
@@ -64,6 +65,47 @@ bool SplitTypeUrl(const string& type_url,
return true;
}
+// This code is originally defined in
+// //google/protobuf/util/converter/utility.h. Copied here due to component
+// dependency.
+// TODO(xiaofeng): Remove this when converter code is in components.
+string ToCamelCase(const StringPiece input) {
+ bool capitalize_next = false;
+ bool was_cap = true;
+ bool is_cap = false;
+ bool first_word = true;
+ string result;
+ result.reserve(input.size());
+
+ for (size_t i = 0; i < input.size(); ++i, was_cap = is_cap) {
+ is_cap = ascii_isupper(input[i]);
+ if (input[i] == '_') {
+ capitalize_next = true;
+ if (!result.empty()) first_word = false;
+ continue;
+ } else if (first_word) {
+ // Consider when the current character B is capitalized,
+ // first word ends when:
+ // 1) following a lowercase: "...aB..."
+ // 2) followed by a lowercase: "...ABc..."
+ if (!result.empty() && is_cap &&
+ (!was_cap || (i + 1 < input.size() && ascii_islower(input[i + 1])))) {
+ first_word = false;
+ } else {
+ result.push_back(ascii_tolower(input[i]));
+ continue;
+ }
+ } else if (capitalize_next) {
+ capitalize_next = false;
+ if (ascii_islower(input[i])) {
+ result.push_back(ascii_toupper(input[i]));
+ continue;
+ }
+ }
+ result.push_back(input[i]);
+ }
+ return result;
+}
class DescriptorPoolTypeResolver : public TypeResolver {
public:
@@ -155,6 +197,7 @@ class DescriptorPoolTypeResolver : public TypeResolver {
}
field->set_number(descriptor->number());
field->set_name(descriptor->name());
+ field->set_json_name(ToCamelCase(descriptor->name()));
if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
field->set_type_url(GetTypeUrl(descriptor->message_type()));
} else if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc
index c5db963b..5ee4e25d 100644
--- a/src/google/protobuf/wire_format.cc
+++ b/src/google/protobuf/wire_format.cc
@@ -38,6 +38,7 @@
#include <google/protobuf/wire_format.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/descriptor.h>
@@ -460,6 +461,10 @@ bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
}
}
+static bool StrictUtf8Check(const FieldDescriptor* field) {
+ return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
+}
+
bool WireFormat::ParseAndMergeField(
uint32 tag,
const FieldDescriptor* field, // May be NULL for unknown
@@ -632,10 +637,19 @@ bool WireFormat::ParseAndMergeField(
// Handle strings separately so that we can optimize the ctype=CORD case.
case FieldDescriptor::TYPE_STRING: {
+ bool strict_utf8_check = StrictUtf8Check(field);
string value;
if (!WireFormatLite::ReadString(input, &value)) return false;
- VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
- field->name().c_str());
+ if (strict_utf8_check) {
+ if (!WireFormatLite::VerifyUtf8String(
+ value.data(), value.length(), WireFormatLite::PARSE,
+ field->full_name().c_str())) {
+ return false;
+ }
+ } else {
+ VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
+ field->full_name().c_str());
+ }
if (field->is_repeated()) {
message_reflection->AddString(message, field, value);
} else {
@@ -893,13 +907,20 @@ void WireFormat::SerializeFieldWithCachedSizes(
// Handle strings separately so that we can get string references
// instead of copying.
case FieldDescriptor::TYPE_STRING: {
+ bool strict_utf8_check = StrictUtf8Check(field);
string scratch;
const string& value = field->is_repeated() ?
message_reflection->GetRepeatedStringReference(
message, field, j, &scratch) :
message_reflection->GetStringReference(message, field, &scratch);
- VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
- field->name().c_str());
+ if (strict_utf8_check) {
+ WireFormatLite::VerifyUtf8String(value.data(), value.length(),
+ WireFormatLite::SERIALIZE,
+ field->full_name().c_str());
+ } else {
+ VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
+ field->full_name().c_str());
+ }
WireFormatLite::WriteString(field->number(), value, output);
break;
}
@@ -1107,34 +1128,6 @@ int WireFormat::MessageSetItemByteSize(
return our_size;
}
-void WireFormat::VerifyUTF8StringFallback(const char* data,
- int size,
- Operation op,
- const char* field_name) {
- if (!IsStructurallyValidUTF8(data, size)) {
- const char* operation_str = NULL;
- switch (op) {
- case PARSE:
- operation_str = "parsing";
- break;
- case SERIALIZE:
- operation_str = "serializing";
- break;
- // no default case: have the compiler warn if a case is not covered.
- }
- string quoted_field_name = "";
- if (field_name != NULL) {
- quoted_field_name = StringPrintf(" '%s'", field_name);
- }
- // no space below to avoid double space when the field name is missing.
- GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
- << "UTF-8 data when " << operation_str << " a protocol "
- << "buffer. Use the 'bytes' type if you intend to send raw "
- << "bytes. ";
- }
-}
-
-
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/wire_format.h b/src/google/protobuf/wire_format.h
index 84270fee..941be75b 100644
--- a/src/google/protobuf/wire_format.h
+++ b/src/google/protobuf/wire_format.h
@@ -231,8 +231,8 @@ class LIBPROTOBUF_EXPORT WireFormat {
const Message& message);
enum Operation {
- PARSE,
- SERIALIZE,
+ PARSE = 0,
+ SERIALIZE = 1,
};
// Verifies that a string field is valid UTF8, logging an error if not.
@@ -247,13 +247,6 @@ class LIBPROTOBUF_EXPORT WireFormat {
const char* field_name);
private:
- // Verifies that a string field is valid UTF8, logging an error if not.
- static void VerifyUTF8StringFallback(
- const char* data,
- int size,
- Operation op,
- const char* field_name);
-
// Skip a MessageSet field.
static bool SkipMessageSetField(io::CodedInputStream* input,
uint32 field_number,
@@ -265,8 +258,6 @@ class LIBPROTOBUF_EXPORT WireFormat {
Message* message,
io::CodedInputStream* input);
-
-
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(WireFormat);
};
@@ -321,7 +312,8 @@ inline int WireFormat::TagSize(int field_number, FieldDescriptor::Type type) {
inline void WireFormat::VerifyUTF8String(const char* data, int size,
WireFormat::Operation op) {
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
- WireFormat::VerifyUTF8StringFallback(data, size, op, NULL);
+ WireFormatLite::VerifyUtf8String(
+ data, size, static_cast<WireFormatLite::Operation>(op), NULL);
#else
// Avoid the compiler warning about unsued variables.
(void)data; (void)size; (void)op;
@@ -332,7 +324,8 @@ inline void WireFormat::VerifyUTF8StringNamedField(
const char* data, int size, WireFormat::Operation op,
const char* field_name) {
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
- WireFormat::VerifyUTF8StringFallback(data, size, op, field_name);
+ WireFormatLite::VerifyUtf8String(
+ data, size, static_cast<WireFormatLite::Operation>(op), field_name);
#endif
}
diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc
index 2ce4920c..847e3500 100644
--- a/src/google/protobuf/wire_format_lite.cc
+++ b/src/google/protobuf/wire_format_lite.cc
@@ -37,11 +37,14 @@
#include <stack>
#include <string>
#include <vector>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/stringprintf.h>
#include <google/protobuf/io/coded_stream_inl.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+
namespace google {
namespace protobuf {
namespace internal {
@@ -484,9 +487,9 @@ void WireFormatLite::WriteMessageMaybeToArray(int field_number,
}
}
-static inline bool ReadBytesToString(io::CodedInputStream* input,
- string* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
-static inline bool ReadBytesToString(io::CodedInputStream* input,
+GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadBytesToString(
+ io::CodedInputStream* input, string* value);
+inline static bool ReadBytesToString(io::CodedInputStream* input,
string* value) {
uint32 length;
return input->ReadVarint32(&length) &&
@@ -504,6 +507,35 @@ bool WireFormatLite::ReadBytes(io::CodedInputStream* input, string** p) {
return ReadBytesToString(input, *p);
}
+bool WireFormatLite::VerifyUtf8String(const char* data,
+ int size,
+ Operation op,
+ const char* field_name) {
+ if (!IsStructurallyValidUTF8(data, size)) {
+ const char* operation_str = NULL;
+ switch (op) {
+ case PARSE:
+ operation_str = "parsing";
+ break;
+ case SERIALIZE:
+ operation_str = "serializing";
+ break;
+ // no default case: have the compiler warn if a case is not covered.
+ }
+ string quoted_field_name = "";
+ if (field_name != NULL) {
+ quoted_field_name = StringPrintf(" '%s'", field_name);
+ }
+ // no space below to avoid double space when the field name is missing.
+ GOOGLE_LOG(ERROR) << "String field" << quoted_field_name << " contains invalid "
+ << "UTF-8 data when " << operation_str << " a protocol "
+ << "buffer. Use the 'bytes' type if you intend to send raw "
+ << "bytes. ";
+ return false;
+ }
+ return true;
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h
index ac83abdc..55fc7ecd 100644
--- a/src/google/protobuf/wire_format_lite.h
+++ b/src/google/protobuf/wire_format_lite.h
@@ -250,17 +250,17 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
// For primitive fields, we just use a templatized routine parameterized by
// the represented type and the FieldType. These are specialized with the
// appropriate definition for each declared type.
- template <typename CType, enum FieldType DeclaredType>
- static inline bool ReadPrimitive(input, CType* value) INL;
+ template <typename CType, enum FieldType DeclaredType> INL
+ static bool ReadPrimitive(input, CType* value);
// Reads repeated primitive values, with optimizations for repeats.
// tag_size and tag should both be compile-time constants provided by the
// protocol compiler.
- template <typename CType, enum FieldType DeclaredType>
- static inline bool ReadRepeatedPrimitive(int tag_size,
- uint32 tag,
- input,
- RepeatedField<CType>* value) INL;
+ template <typename CType, enum FieldType DeclaredType> INL
+ static bool ReadRepeatedPrimitive(int tag_size,
+ uint32 tag,
+ input,
+ RepeatedField<CType>* value);
// Identical to ReadRepeatedPrimitive, except will not inline the
// implementation.
@@ -275,16 +275,14 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
//
// This is only implemented for the types with fixed wire size, e.g.
// float, double, and the (s)fixed* types.
- template <typename CType, enum FieldType DeclaredType>
- static inline const uint8* ReadPrimitiveFromArray(const uint8* buffer,
- CType* value) INL;
+ template <typename CType, enum FieldType DeclaredType> INL
+ static const uint8* ReadPrimitiveFromArray(const uint8* buffer, CType* value);
// Reads a primitive packed field.
//
// This is only implemented for packable types.
- template <typename CType, enum FieldType DeclaredType>
- static inline bool ReadPackedPrimitive(input,
- RepeatedField<CType>* value) INL;
+ template <typename CType, enum FieldType DeclaredType> INL
+ static bool ReadPackedPrimitive(input, RepeatedField<CType>* value);
// Identical to ReadPackedPrimitive, except will not inline the
// implementation.
@@ -318,6 +316,16 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
static bool ReadBytes(input, string** p);
+ enum Operation {
+ PARSE = 0,
+ SERIALIZE = 1,
+ };
+
+ // Returns true if the data is valid UTF-8.
+ static bool VerifyUtf8String(const char* data, int size,
+ Operation op,
+ const char* field_name);
+
static inline bool ReadGroup (field_number, input, MessageLite* value);
static inline bool ReadMessage(input, MessageLite* value);
@@ -344,23 +352,23 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
// Write a tag. The Write*() functions typically include the tag, so
// normally there's no need to call this unless using the Write*NoTag()
// variants.
- static inline void WriteTag(field_number, WireType type, output) INL;
+ INL static void WriteTag(field_number, WireType type, output);
// Write fields, without tags.
- static inline void WriteInt32NoTag (int32 value, output) INL;
- static inline void WriteInt64NoTag (int64 value, output) INL;
- static inline void WriteUInt32NoTag (uint32 value, output) INL;
- static inline void WriteUInt64NoTag (uint64 value, output) INL;
- static inline void WriteSInt32NoTag (int32 value, output) INL;
- static inline void WriteSInt64NoTag (int64 value, output) INL;
- static inline void WriteFixed32NoTag (uint32 value, output) INL;
- static inline void WriteFixed64NoTag (uint64 value, output) INL;
- static inline void WriteSFixed32NoTag(int32 value, output) INL;
- static inline void WriteSFixed64NoTag(int64 value, output) INL;
- static inline void WriteFloatNoTag (float value, output) INL;
- static inline void WriteDoubleNoTag (double value, output) INL;
- static inline void WriteBoolNoTag (bool value, output) INL;
- static inline void WriteEnumNoTag (int value, output) INL;
+ INL static void WriteInt32NoTag (int32 value, output);
+ INL static void WriteInt64NoTag (int64 value, output);
+ INL static void WriteUInt32NoTag (uint32 value, output);
+ INL static void WriteUInt64NoTag (uint64 value, output);
+ INL static void WriteSInt32NoTag (int32 value, output);
+ INL static void WriteSInt64NoTag (int64 value, output);
+ INL static void WriteFixed32NoTag (uint32 value, output);
+ INL static void WriteFixed64NoTag (uint64 value, output);
+ INL static void WriteSFixed32NoTag(int32 value, output);
+ INL static void WriteSFixed64NoTag(int64 value, output);
+ INL static void WriteFloatNoTag (float value, output);
+ INL static void WriteDoubleNoTag (double value, output);
+ INL static void WriteBoolNoTag (bool value, output);
+ INL static void WriteEnumNoTag (int value, output);
// Write fields, including tags.
static void WriteInt32 (field_number, int32 value, output);
@@ -410,73 +418,59 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
#define output uint8* target
// Like above, but use only *ToArray methods of CodedOutputStream.
- static inline uint8* WriteTagToArray(field_number, WireType type, output) INL;
+ INL static uint8* WriteTagToArray(field_number, WireType type, output);
// Write fields, without tags.
- static inline uint8* WriteInt32NoTagToArray (int32 value, output) INL;
- static inline uint8* WriteInt64NoTagToArray (int64 value, output) INL;
- static inline uint8* WriteUInt32NoTagToArray (uint32 value, output) INL;
- static inline uint8* WriteUInt64NoTagToArray (uint64 value, output) INL;
- static inline uint8* WriteSInt32NoTagToArray (int32 value, output) INL;
- static inline uint8* WriteSInt64NoTagToArray (int64 value, output) INL;
- static inline uint8* WriteFixed32NoTagToArray (uint32 value, output) INL;
- static inline uint8* WriteFixed64NoTagToArray (uint64 value, output) INL;
- static inline uint8* WriteSFixed32NoTagToArray(int32 value, output) INL;
- static inline uint8* WriteSFixed64NoTagToArray(int64 value, output) INL;
- static inline uint8* WriteFloatNoTagToArray (float value, output) INL;
- static inline uint8* WriteDoubleNoTagToArray (double value, output) INL;
- static inline uint8* WriteBoolNoTagToArray (bool value, output) INL;
- static inline uint8* WriteEnumNoTagToArray (int value, output) INL;
+ INL static uint8* WriteInt32NoTagToArray (int32 value, output);
+ INL static uint8* WriteInt64NoTagToArray (int64 value, output);
+ INL static uint8* WriteUInt32NoTagToArray (uint32 value, output);
+ INL static uint8* WriteUInt64NoTagToArray (uint64 value, output);
+ INL static uint8* WriteSInt32NoTagToArray (int32 value, output);
+ INL static uint8* WriteSInt64NoTagToArray (int64 value, output);
+ INL static uint8* WriteFixed32NoTagToArray (uint32 value, output);
+ INL static uint8* WriteFixed64NoTagToArray (uint64 value, output);
+ INL static uint8* WriteSFixed32NoTagToArray(int32 value, output);
+ INL static uint8* WriteSFixed64NoTagToArray(int64 value, output);
+ INL static uint8* WriteFloatNoTagToArray (float value, output);
+ INL static uint8* WriteDoubleNoTagToArray (double value, output);
+ INL static uint8* WriteBoolNoTagToArray (bool value, output);
+ INL static uint8* WriteEnumNoTagToArray (int value, output);
// Write fields, including tags.
- static inline uint8* WriteInt32ToArray(
- field_number, int32 value, output) INL;
- static inline uint8* WriteInt64ToArray(
- field_number, int64 value, output) INL;
- static inline uint8* WriteUInt32ToArray(
- field_number, uint32 value, output) INL;
- static inline uint8* WriteUInt64ToArray(
- field_number, uint64 value, output) INL;
- static inline uint8* WriteSInt32ToArray(
- field_number, int32 value, output) INL;
- static inline uint8* WriteSInt64ToArray(
- field_number, int64 value, output) INL;
- static inline uint8* WriteFixed32ToArray(
- field_number, uint32 value, output) INL;
- static inline uint8* WriteFixed64ToArray(
- field_number, uint64 value, output) INL;
- static inline uint8* WriteSFixed32ToArray(
- field_number, int32 value, output) INL;
- static inline uint8* WriteSFixed64ToArray(
- field_number, int64 value, output) INL;
- static inline uint8* WriteFloatToArray(
- field_number, float value, output) INL;
- static inline uint8* WriteDoubleToArray(
- field_number, double value, output) INL;
- static inline uint8* WriteBoolToArray(
- field_number, bool value, output) INL;
- static inline uint8* WriteEnumToArray(
- field_number, int value, output) INL;
-
- static inline uint8* WriteStringToArray(
- field_number, const string& value, output) INL;
- static inline uint8* WriteBytesToArray(
- field_number, const string& value, output) INL;
-
- static inline uint8* WriteGroupToArray(
- field_number, const MessageLite& value, output) INL;
- static inline uint8* WriteMessageToArray(
- field_number, const MessageLite& value, output) INL;
+ INL static uint8* WriteInt32ToArray(field_number, int32 value, output);
+ INL static uint8* WriteInt64ToArray(field_number, int64 value, output);
+ INL static uint8* WriteUInt32ToArray(field_number, uint32 value, output);
+ INL static uint8* WriteUInt64ToArray(field_number, uint64 value, output);
+ INL static uint8* WriteSInt32ToArray(field_number, int32 value, output);
+ INL static uint8* WriteSInt64ToArray(field_number, int64 value, output);
+ INL static uint8* WriteFixed32ToArray(field_number, uint32 value, output);
+ INL static uint8* WriteFixed64ToArray(field_number, uint64 value, output);
+ INL static uint8* WriteSFixed32ToArray(field_number, int32 value, output);
+ INL static uint8* WriteSFixed64ToArray(field_number, int64 value, output);
+ INL static uint8* WriteFloatToArray(field_number, float value, output);
+ INL static uint8* WriteDoubleToArray(field_number, double value, output);
+ INL static uint8* WriteBoolToArray(field_number, bool value, output);
+ INL static uint8* WriteEnumToArray(field_number, int value, output);
+
+ INL static uint8* WriteStringToArray(
+ field_number, const string& value, output);
+ INL static uint8* WriteBytesToArray(
+ field_number, const string& value, output);
+
+ INL static uint8* WriteGroupToArray(
+ field_number, const MessageLite& value, output);
+ INL static uint8* WriteMessageToArray(
+ field_number, const MessageLite& value, output);
// Like above, but de-virtualize the call to SerializeWithCachedSizes(). The
// pointer must point at an instance of MessageType, *not* a subclass (or
// the subclass must not override SerializeWithCachedSizes()).
template<typename MessageType>
- static inline uint8* WriteGroupNoVirtualToArray(
- field_number, const MessageType& value, output) INL;
+ INL static uint8* WriteGroupNoVirtualToArray(
+ field_number, const MessageType& value, output);
template<typename MessageType>
- static inline uint8* WriteMessageNoVirtualToArray(
- field_number, const MessageType& value, output) INL;
+ INL static uint8* WriteMessageNoVirtualToArray(
+ field_number, const MessageType& value, output);
#undef output
#undef input
@@ -527,18 +521,17 @@ class LIBPROTOBUF_EXPORT WireFormatLite {
// A helper method for the repeated primitive reader. This method has
// optimizations for primitive types that have fixed size on the wire, and
// can be read using potentially faster paths.
- template <typename CType, enum FieldType DeclaredType>
- static inline bool ReadRepeatedFixedSizePrimitive(
+ template <typename CType, enum FieldType DeclaredType> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+ static bool ReadRepeatedFixedSizePrimitive(
int tag_size,
uint32 tag,
google::protobuf::io::CodedInputStream* input,
- RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ RepeatedField<CType>* value);
// Like ReadRepeatedFixedSizePrimitive but for packed primitive fields.
- template <typename CType, enum FieldType DeclaredType>
- static inline bool ReadPackedFixedSizePrimitive(
- google::protobuf::io::CodedInputStream* input,
- RepeatedField<CType>* value) GOOGLE_ATTRIBUTE_ALWAYS_INLINE;
+ template <typename CType, enum FieldType DeclaredType> GOOGLE_ATTRIBUTE_ALWAYS_INLINE
+ static bool ReadPackedFixedSizePrimitive(google::protobuf::io::CodedInputStream* input,
+ RepeatedField<CType>* value);
static const CppType kFieldTypeToCppTypeMap[];
static const WireFormatLite::WireType kWireTypeForFieldType[];
diff --git a/src/google/protobuf/wire_format_lite_inl.h b/src/google/protobuf/wire_format_lite_inl.h
index d073ff92..991c3d04 100644
--- a/src/google/protobuf/wire_format_lite_inl.h
+++ b/src/google/protobuf/wire_format_lite_inl.h
@@ -43,6 +43,7 @@
#include <string>
#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/message_lite.h>
#include <google/protobuf/repeated_field.h>
#include <google/protobuf/wire_format_lite.h>
diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc
index aef22b29..15c37556 100644
--- a/src/google/protobuf/wire_format_unittest.cc
+++ b/src/google/protobuf/wire_format_unittest.cc
@@ -40,8 +40,10 @@
#include <google/protobuf/unittest.pb.h>
#include <google/protobuf/unittest_proto3_arena.pb.h>
#include <google/protobuf/unittest_mset.pb.h>
+#include <google/protobuf/unittest_mset_wire_format.pb.h>
#include <google/protobuf/test_util.h>
+#include <google/protobuf/stubs/logging.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
@@ -419,7 +421,7 @@ const int kUnknownTypeId = 1550055;
TEST(WireFormatTest, SerializeMessageSet) {
// Set up a TestMessageSet with two known messages and an unknown one.
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
message_set.MutableExtension(
unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
message_set.MutableExtension(
@@ -462,7 +464,7 @@ TEST(WireFormatTest, SerializeMessageSetVariousWaysAreEqual) {
// Set up a TestMessageSet with two known messages and an unknown one, as
// above.
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
message_set.MutableExtension(
unittest::TestMessageSetExtension1::message_set_extension)->set_i(123);
message_set.MutableExtension(
@@ -539,7 +541,7 @@ TEST(WireFormatTest, ParseMessageSet) {
ASSERT_TRUE(raw.SerializeToString(&data));
// Parse as a TestMessageSet and check the contents.
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
ASSERT_TRUE(message_set.ParseFromString(data));
EXPECT_EQ(123, message_set.GetExtension(
@@ -553,7 +555,7 @@ TEST(WireFormatTest, ParseMessageSet) {
EXPECT_EQ("bar", message_set.unknown_fields().field(0).length_delimited());
// Also parse using WireFormat.
- unittest::TestMessageSet dynamic_message_set;
+ proto2_wireformat_unittest::TestMessageSet dynamic_message_set;
io::CodedInputStream input(reinterpret_cast<const uint8*>(data.data()),
data.size());
ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &dynamic_message_set));
@@ -583,7 +585,7 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
coded_output.WriteTag(WireFormatLite::kMessageSetItemEndTag);
}
{
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
ASSERT_TRUE(message_set.ParseFromString(data));
EXPECT_EQ(123, message_set.GetExtension(
@@ -591,7 +593,7 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
}
{
// Test parse the message via Reflection.
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
io::CodedInputStream input(
reinterpret_cast<const uint8*>(data.data()), data.size());
EXPECT_TRUE(WireFormat::ParseAndMergePartial(&input, &message_set));
@@ -603,7 +605,7 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
}
TEST(WireFormatTest, ParseBrokenMessageSet) {
- unittest::TestMessageSet message_set;
+ proto2_wireformat_unittest::TestMessageSet message_set;
string input("goodbye"); // Invalid wire format data.
EXPECT_FALSE(message_set.ParseFromString(input));
}
diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc
index db75db15..b2a7e970 100644
--- a/src/google/protobuf/wrappers.pb.cc
+++ b/src/google/protobuf/wrappers.pb.cc
@@ -262,9 +262,10 @@ void protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto() {
"e\030\001 \001(\004\"\033\n\nInt32Value\022\r\n\005value\030\001 \001(\005\"\034\n\013"
"UInt32Value\022\r\n\005value\030\001 \001(\r\"\032\n\tBoolValue\022"
"\r\n\005value\030\001 \001(\010\"\034\n\013StringValue\022\r\n\005value\030\001"
- " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BM\n\023com"
- ".google.protobufB\rWrappersProtoP\001\242\002\003GPB\252"
- "\002\036Google.Protobuf.WellKnownTypesb\006proto3", 400);
+ " \001(\t\"\033\n\nBytesValue\022\r\n\005value\030\001 \001(\014BP\n\023com"
+ ".google.protobufB\rWrappersProtoP\001\240\001\001\242\002\003G"
+ "PB\252\002\036Google.Protobuf.WellKnownTypesb\006pro"
+ "to3", 403);
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
"google/protobuf/wrappers.proto", &protobuf_RegisterTypes);
DoubleValue::default_instance_ = new DoubleValue();
@@ -1967,10 +1968,10 @@ bool StringValue::MergePartialFromCodedStream(
if (tag == 10) {
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
input, this->mutable_value()));
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->value().data(), this->value().length(),
- ::google::protobuf::internal::WireFormat::PARSE,
- "google.protobuf.StringValue.value");
+ ::google::protobuf::internal::WireFormatLite::PARSE,
+ "google.protobuf.StringValue.value"));
} else {
goto handle_unusual;
}
@@ -2004,9 +2005,9 @@ void StringValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_start:google.protobuf.StringValue)
// optional string value = 1;
if (this->value().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->value().data(), this->value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.StringValue.value");
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
1, this->value(), output);
@@ -2020,9 +2021,9 @@ void StringValue::SerializeWithCachedSizes(
// @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue)
// optional string value = 1;
if (this->value().size() > 0) {
- ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+ ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
this->value().data(), this->value().length(),
- ::google::protobuf::internal::WireFormat::SERIALIZE,
+ ::google::protobuf::internal::WireFormatLite::SERIALIZE,
"google.protobuf.StringValue.value");
target =
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h
index 387ebd7c..15bcc7a2 100644
--- a/src/google/protobuf/wrappers.pb.h
+++ b/src/google/protobuf/wrappers.pb.h
@@ -37,15 +37,15 @@ void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fwrappers_2eproto();
void protobuf_AssignDesc_google_2fprotobuf_2fwrappers_2eproto();
void protobuf_ShutdownFile_google_2fprotobuf_2fwrappers_2eproto();
+class BoolValue;
+class BytesValue;
class DoubleValue;
class FloatValue;
-class Int64Value;
-class UInt64Value;
class Int32Value;
-class UInt32Value;
-class BoolValue;
+class Int64Value;
class StringValue;
-class BytesValue;
+class UInt32Value;
+class UInt64Value;
// ===================================================================
diff --git a/src/google/protobuf/wrappers.proto b/src/google/protobuf/wrappers.proto
index 6d3181bf..a1d6e446 100644
--- a/src/google/protobuf/wrappers.proto
+++ b/src/google/protobuf/wrappers.proto
@@ -37,62 +37,80 @@ syntax = "proto3";
package google.protobuf;
+option java_generate_equals_and_hash = true;
option java_multiple_files = true;
option java_outer_classname = "WrappersProto";
option java_package = "com.google.protobuf";
option csharp_namespace = "Google.Protobuf.WellKnownTypes";
option objc_class_prefix = "GPB";
-
-// Wrapper message for double.
+// Wrapper message for `double`.
+//
+// The JSON representation for `DoubleValue` is JSON number.
message DoubleValue {
// The double value.
double value = 1;
}
-// Wrapper message for float.
+// Wrapper message for `float`.
+//
+// The JSON representation for `FloatValue` is JSON number.
message FloatValue {
// The float value.
float value = 1;
}
-// Wrapper message for int64.
+// Wrapper message for `int64`.
+//
+// The JSON representation for `Int64Value` is JSON string.
message Int64Value {
// The int64 value.
int64 value = 1;
}
-// Wrapper message for uint64.
+// Wrapper message for `uint64`.
+//
+// The JSON representation for `UInt64Value` is JSON string.
message UInt64Value {
// The uint64 value.
uint64 value = 1;
}
-// Wrapper message for int32.
+// Wrapper message for `int32`.
+//
+// The JSON representation for `Int32Value` is JSON number.
message Int32Value {
// The int32 value.
int32 value = 1;
}
-// Wrapper message for uint32.
+// Wrapper message for `uint32`.
+//
+// The JSON representation for `UInt32Value` is JSON number.
message UInt32Value {
// The uint32 value.
uint32 value = 1;
}
-// Wrapper message for bool.
+// Wrapper message for `bool`.
+//
+// The JSON representation for `BoolValue` is JSON `true` and `false`.
message BoolValue {
// The bool value.
bool value = 1;
}
-// Wrapper message for string.
+// Wrapper message for `string`.
+//
+// The JSON representation for `StringValue` is JSON string.
message StringValue {
// The string value.
string value = 1;
}
-// Wrapper message for bytes.
+// Wrapper message for `bytes`.
+//
+// The JSON representation for `BytesValue` is JSON string.
message BytesValue {
// The bytes value.
bytes value = 1;