From d36c0c538a545fac5d9db6ba65c525246d4efa95 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:32:48 -0700 Subject: Down-integrate from google3. --- Makefile.am | 4 +- cmake/libprotoc.cmake | 1 + cmake/tests.cmake | 5 +- conformance/conformance_test.cc | 17 + conformance/conformance_test.h | 1 + conformance/failure_list_cpp.txt | 2 - conformance/failure_list_java.txt | 1 + conformance/failure_list_python.txt | 602 +++++++ conformance/failure_list_python_cpp.txt | 586 +++++++ generate_descriptor_proto.sh | 21 +- .../java/com/google/protobuf/AbstractMessage.java | 4 +- .../com/google/protobuf/AbstractMessageLite.java | 21 +- .../java/com/google/protobuf/AbstractParser.java | 26 +- .../java/com/google/protobuf/BooleanArrayList.java | 12 +- .../java/com/google/protobuf/CodedInputStream.java | 4 +- .../com/google/protobuf/CodedOutputStream.java | 4 +- .../main/java/com/google/protobuf/Descriptors.java | 7 +- .../java/com/google/protobuf/DoubleArrayList.java | 12 +- .../java/com/google/protobuf/DynamicMessage.java | 7 +- .../main/java/com/google/protobuf/FieldSet.java | 7 +- .../java/com/google/protobuf/FloatArrayList.java | 12 +- .../com/google/protobuf/GeneratedMessageLite.java | 22 +- .../com/google/protobuf/GeneratedMessageV3.java | 2 +- .../java/com/google/protobuf/IntArrayList.java | 12 +- .../main/java/com/google/protobuf/Internal.java | 15 + .../java/com/google/protobuf/LazyFieldLite.java | 1 + .../java/com/google/protobuf/LongArrayList.java | 12 +- .../main/java/com/google/protobuf/MapEntry.java | 24 +- .../java/com/google/protobuf/MapEntryLite.java | 5 + .../main/java/com/google/protobuf/MapField.java | 8 + .../java/com/google/protobuf/MapFieldLite.java | 14 +- .../src/main/java/com/google/protobuf/Parser.java | 13 + .../protobuf/PrimitiveNonBoxingCollection.java | 34 + .../google/protobuf/RepeatedFieldBuilderV3.java | 18 +- .../com/google/protobuf/SingleFieldBuilderV3.java | 12 +- .../main/java/com/google/protobuf/TextFormat.java | 4 +- .../java/com/google/protobuf/UnknownFieldSet.java | 4 +- .../main/java/com/google/protobuf/UnsafeUtil.java | 401 +++-- .../src/main/java/com/google/protobuf/Utf8.java | 2 +- .../java/com/google/protobuf/LazyFieldTest.java | 2 +- .../test/java/com/google/protobuf/LiteTest.java | 108 ++ .../java/com/google/protobuf/MapForProto2Test.java | 1 + .../src/test/java/com/google/protobuf/MapTest.java | 39 +- .../test/java/com/google/protobuf/ParserTest.java | 27 +- .../test/java/com/google/protobuf/TestUtil.java | 2 + .../java/com/google/protobuf/TextFormatTest.java | 92 ++ .../com/google/protobuf/lite_equals_and_hash.proto | 8 + java/lite/pom.xml | 1 + .../java/com/google/protobuf/util/JsonFormat.java | 175 +- .../java/com/google/protobuf/util/Timestamps.java | 2 +- .../com/google/protobuf/util/JsonFormatTest.java | 137 +- js/binary/decoder.js | 17 +- js/binary/decoder_test.js | 19 + js/binary/encoder.js | 4 +- js/binary/reader.js | 2 +- js/binary/utils.js | 2 +- js/binary/writer.js | 4 +- js/binary/writer_test.js | 2 +- js/map.js | 10 +- js/message.js | 31 +- js/message_test.js | 1 + python/google/protobuf/descriptor_database.py | 11 +- python/google/protobuf/descriptor_pool.py | 99 +- python/google/protobuf/internal/containers.py | 2 +- .../protobuf/internal/descriptor_pool_test.py | 36 + python/google/protobuf/internal/encoder.py | 7 +- python/google/protobuf/internal/message_test.py | 27 +- python/google/protobuf/internal/python_message.py | 5 +- python/google/protobuf/internal/python_protobuf.cc | 63 + python/google/protobuf/internal/reflection_test.py | 9 +- .../protobuf/internal/symbol_database_test.py | 9 +- .../google/protobuf/internal/text_format_test.py | 51 + python/google/protobuf/pyext/descriptor.cc | 19 + python/google/protobuf/pyext/descriptor.h | 2 + python/google/protobuf/pyext/descriptor_pool.cc | 20 +- python/google/protobuf/pyext/descriptor_pool.h | 1 + python/google/protobuf/pyext/python_protobuf.h | 57 - .../protobuf/pyext/repeated_composite_container.cc | 29 + python/google/protobuf/pyext/scoped_pyobject_ptr.h | 59 +- python/google/protobuf/python_protobuf.h | 57 + python/google/protobuf/reflection.py | 6 +- python/google/protobuf/symbol_database.py | 11 + python/google/protobuf/text_format.py | 35 +- src/Makefile.am | 43 +- src/google/protobuf/any.h | 6 +- src/google/protobuf/any.pb.cc | 31 +- src/google/protobuf/any.pb.h | 15 +- src/google/protobuf/api.pb.cc | 106 +- src/google/protobuf/api.pb.h | 38 +- src/google/protobuf/arena.h | 55 +- src/google/protobuf/arena_unittest.cc | 52 + src/google/protobuf/arenastring.cc | 10 - src/google/protobuf/arenastring.h | 16 + src/google/protobuf/compiler/code_generator.h | 2 +- .../protobuf/compiler/command_line_interface.cc | 57 +- .../protobuf/compiler/command_line_interface.h | 7 +- .../compiler/command_line_interface_unittest.cc | 40 +- .../compiler/cpp/cpp_bootstrap_unittest.cc | 14 +- src/google/protobuf/compiler/cpp/cpp_enum_field.cc | 16 +- src/google/protobuf/compiler/cpp/cpp_file.cc | 154 +- src/google/protobuf/compiler/cpp/cpp_file.h | 3 + src/google/protobuf/compiler/cpp/cpp_generator.cc | 2 + src/google/protobuf/compiler/cpp/cpp_helpers.cc | 103 ++ src/google/protobuf/compiler/cpp/cpp_helpers.h | 67 + src/google/protobuf/compiler/cpp/cpp_map_field.cc | 79 +- src/google/protobuf/compiler/cpp/cpp_map_field.h | 2 +- src/google/protobuf/compiler/cpp/cpp_message.cc | 911 +++++++--- src/google/protobuf/compiler/cpp/cpp_message.h | 33 +- .../protobuf/compiler/cpp/cpp_message_field.cc | 20 +- .../protobuf/compiler/cpp/cpp_message_field.h | 2 +- src/google/protobuf/compiler/cpp/cpp_options.h | 8 +- .../protobuf/compiler/cpp/cpp_primitive_field.cc | 19 +- .../protobuf/compiler/cpp/cpp_string_field.cc | 14 +- src/google/protobuf/compiler/cpp/cpp_unittest.cc | 56 +- src/google/protobuf/compiler/importer.cc | 1 + src/google/protobuf/compiler/importer.h | 1 + src/google/protobuf/compiler/importer_unittest.cc | 2 +- .../protobuf/compiler/java/java_enum_field_lite.cc | 3 + .../protobuf/compiler/java/java_enum_lite.cc | 51 +- src/google/protobuf/compiler/java/java_field.h | 1 + src/google/protobuf/compiler/java/java_file.cc | 6 - .../protobuf/compiler/java/java_generator.cc | 1 + src/google/protobuf/compiler/java/java_helpers.cc | 2 + .../compiler/java/java_lazy_message_field_lite.cc | 3 + .../compiler/java/java_lazy_message_field_lite.h | 3 + .../protobuf/compiler/java/java_map_field_lite.cc | 1 + .../protobuf/compiler/java/java_map_field_lite.h | 1 + src/google/protobuf/compiler/java/java_message.cc | 11 + .../compiler/java/java_message_builder_lite.cc | 7 - .../compiler/java/java_message_field_lite.cc | 2 + .../compiler/java/java_message_field_lite.h | 2 + .../protobuf/compiler/java/java_message_lite.cc | 29 +- .../compiler/java/java_primitive_field_lite.cc | 2 + .../compiler/java/java_primitive_field_lite.h | 3 + .../compiler/java/java_string_field_lite.cc | 3 + .../compiler/java/java_string_field_lite.h | 3 + src/google/protobuf/compiler/js/embed.cc | 2 +- src/google/protobuf/compiler/js/js_generator.cc | 177 +- .../compiler/js/well_known_types/timestamp.js | 1 - .../protobuf/compiler/mock_code_generator.cc | 12 +- src/google/protobuf/compiler/parser_unittest.cc | 7 +- src/google/protobuf/compiler/plugin.pb.cc | 197 ++- src/google/protobuf/compiler/plugin.pb.h | 42 +- src/google/protobuf/compiler/plugin.proto | 3 + src/google/protobuf/compiler/profile.pb.cc | 1442 ++++++++++++++++ src/google/protobuf/compiler/profile.pb.h | 728 ++++++++ src/google/protobuf/compiler/profile.proto | 68 + src/google/protobuf/compiler/test_plugin.cc | 1 - src/google/protobuf/compiler/zip_writer.cc | 30 + src/google/protobuf/compiler/zip_writer.h | 30 + src/google/protobuf/descriptor.cc | 679 +++++--- src/google/protobuf/descriptor.h | 153 +- src/google/protobuf/descriptor.pb.cc | 1743 ++++++++++++-------- src/google/protobuf/descriptor.pb.h | 389 ++--- src/google/protobuf/descriptor.proto | 3 +- src/google/protobuf/descriptor_database.cc | 4 +- src/google/protobuf/descriptor_database.h | 12 + .../protobuf/descriptor_database_unittest.cc | 1 - src/google/protobuf/descriptor_unittest.cc | 359 +++- src/google/protobuf/duration.pb.cc | 29 +- src/google/protobuf/duration.pb.h | 13 +- src/google/protobuf/duration.proto | 15 +- src/google/protobuf/dynamic_message.cc | 24 +- src/google/protobuf/empty.pb.cc | 29 +- src/google/protobuf/empty.pb.h | 13 +- src/google/protobuf/extension_set.h | 17 +- src/google/protobuf/extension_set_heavy.cc | 41 +- src/google/protobuf/extension_set_unittest.cc | 2 +- src/google/protobuf/field_mask.pb.cc | 35 +- src/google/protobuf/field_mask.pb.h | 17 +- .../protobuf/generated_message_reflection.cc | 67 +- src/google/protobuf/generated_message_reflection.h | 81 +- .../protobuf/generated_message_table_driven.cc | 676 ++++++++ .../protobuf/generated_message_table_driven.h | 173 ++ src/google/protobuf/generated_message_util.cc | 2 +- src/google/protobuf/generated_message_util.h | 56 +- src/google/protobuf/io/coded_stream.cc | 46 +- src/google/protobuf/io/coded_stream.h | 39 +- src/google/protobuf/io/coded_stream_unittest.cc | 33 +- src/google/protobuf/io/gzip_stream.h | 2 +- src/google/protobuf/lite_unittest.cc | 199 ++- src/google/protobuf/map.h | 708 +------- src/google/protobuf/map_entry.h | 231 +-- src/google/protobuf/map_entry_lite.h | 191 ++- src/google/protobuf/map_field.cc | 49 +- src/google/protobuf/map_field.h | 529 +++++- src/google/protobuf/map_field_inl.h | 290 +--- src/google/protobuf/map_field_lite.h | 226 +-- src/google/protobuf/map_field_test.cc | 51 +- src/google/protobuf/map_proto2_unittest.proto | 5 + src/google/protobuf/map_test.cc | 176 +- src/google/protobuf/map_test_util_impl.h | 41 +- src/google/protobuf/map_type_handler.h | 70 +- src/google/protobuf/message.cc | 4 +- src/google/protobuf/message.h | 10 +- src/google/protobuf/message_lite.cc | 5 + src/google/protobuf/message_lite.h | 33 +- src/google/protobuf/message_unittest.cc | 11 + src/google/protobuf/metadata.h | 153 +- src/google/protobuf/metadata_lite.h | 193 +++ src/google/protobuf/reflection.h | 4 +- src/google/protobuf/reflection_ops_unittest.cc | 1 + src/google/protobuf/repeated_field.h | 168 +- .../protobuf/repeated_field_reflection_unittest.cc | 39 +- src/google/protobuf/repeated_field_unittest.cc | 2 +- src/google/protobuf/source_context.pb.cc | 30 +- src/google/protobuf/source_context.pb.h | 14 +- src/google/protobuf/struct.pb.cc | 135 +- src/google/protobuf/struct.pb.h | 58 +- src/google/protobuf/test_util_lite.cc | 7 +- src/google/protobuf/text_format.cc | 15 +- src/google/protobuf/text_format.h | 4 +- src/google/protobuf/text_format_unittest.cc | 2 +- src/google/protobuf/timestamp.pb.cc | 29 +- src/google/protobuf/timestamp.pb.h | 13 +- src/google/protobuf/timestamp.proto | 25 + src/google/protobuf/type.pb.cc | 169 +- src/google/protobuf/type.pb.h | 61 +- src/google/protobuf/unittest.proto | 16 + .../protobuf/unittest_lazy_dependencies.proto | 75 + .../unittest_lazy_dependencies_custom_option.proto | 67 + .../protobuf/unittest_lazy_dependencies_enum.proto | 61 + src/google/protobuf/unittest_proto3_arena.proto | 2 + src/google/protobuf/unknown_field_set.cc | 48 +- src/google/protobuf/unknown_field_set.h | 43 +- .../util/internal/default_value_objectwriter.cc | 82 +- .../util/internal/default_value_objectwriter.h | 44 +- .../protobuf/util/internal/field_mask_utility.cc | 7 +- src/google/protobuf/util/internal/json_escaping.cc | 48 - .../protobuf/util/internal/json_stream_parser.cc | 58 +- src/google/protobuf/util/internal/proto_writer.h | 28 +- .../util/internal/protostream_objectsource.cc | 44 +- .../util/internal/protostream_objectsource.h | 4 +- .../util/internal/protostream_objectsource_test.cc | 6 +- .../util/internal/protostream_objectwriter.cc | 35 +- .../util/internal/protostream_objectwriter.h | 11 +- .../util/internal/protostream_objectwriter_test.cc | 10 +- src/google/protobuf/util/internal/type_info.cc | 18 +- src/google/protobuf/util/internal/utility.cc | 10 - src/google/protobuf/util/json_util.cc | 6 +- src/google/protobuf/util/json_util.h | 10 +- src/google/protobuf/util/json_util_test.cc | 20 +- src/google/protobuf/util/message_differencer.cc | 11 +- .../protobuf/util/message_differencer_unittest.cc | 41 +- src/google/protobuf/util/time_util.cc | 30 - src/google/protobuf/wire_format.cc | 2 + src/google/protobuf/wire_format_lite.cc | 10 +- src/google/protobuf/wire_format_lite.h | 445 +++-- src/google/protobuf/wire_format_lite_inl.h | 184 ++- src/google/protobuf/wire_format_unittest.cc | 23 + src/google/protobuf/wrappers.pb.cc | 175 +- src/google/protobuf/wrappers.pb.h | 87 +- 252 files changed, 13346 insertions(+), 5238 deletions(-) create mode 100644 java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java create mode 100644 python/google/protobuf/internal/python_protobuf.cc delete mode 100644 python/google/protobuf/pyext/python_protobuf.h create mode 100644 python/google/protobuf/python_protobuf.h create mode 100644 src/google/protobuf/compiler/profile.pb.cc create mode 100644 src/google/protobuf/compiler/profile.pb.h create mode 100644 src/google/protobuf/compiler/profile.proto create mode 100644 src/google/protobuf/generated_message_table_driven.cc create mode 100644 src/google/protobuf/generated_message_table_driven.h create mode 100644 src/google/protobuf/metadata_lite.h create mode 100644 src/google/protobuf/unittest_lazy_dependencies.proto create mode 100644 src/google/protobuf/unittest_lazy_dependencies_custom_option.proto create mode 100644 src/google/protobuf/unittest_lazy_dependencies_enum.proto diff --git a/Makefile.am b/Makefile.am index 0b2511f9..564bff48 100644 --- a/Makefile.am +++ b/Makefile.am @@ -247,6 +247,7 @@ java_EXTRA_DIST= java/core/src/main/java/com/google/protobuf/MutabilityOracle.java \ java/core/src/main/java/com/google/protobuf/NioByteString.java \ java/core/src/main/java/com/google/protobuf/Parser.java \ + java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java \ java/core/src/main/java/com/google/protobuf/ProtobufArrayList.java \ java/core/src/main/java/com/google/protobuf/ProtocolMessageEnum.java \ java/core/src/main/java/com/google/protobuf/ProtocolStringList.java \ @@ -710,6 +711,7 @@ python_EXTRA_DIST= \ python/google/protobuf/internal/packed_field_test.proto \ python/google/protobuf/internal/proto_builder_test.py \ python/google/protobuf/internal/python_message.py \ + python/google/protobuf/internal/python_protobuf.cc \ python/google/protobuf/internal/reflection_test.py \ python/google/protobuf/internal/service_reflection_test.py \ python/google/protobuf/internal/symbol_database_test.py \ @@ -752,13 +754,13 @@ python_EXTRA_DIST= \ python/google/protobuf/pyext/message_module.cc \ python/google/protobuf/pyext/proto2_api_test.proto \ python/google/protobuf/pyext/python.proto \ - python/google/protobuf/pyext/python_protobuf.h \ python/google/protobuf/pyext/repeated_composite_container.cc \ python/google/protobuf/pyext/repeated_composite_container.h \ python/google/protobuf/pyext/repeated_scalar_container.cc \ python/google/protobuf/pyext/repeated_scalar_container.h \ python/google/protobuf/pyext/safe_numerics.h \ python/google/protobuf/pyext/scoped_pyobject_ptr.h \ + python/google/protobuf/python_protobuf.h \ python/google/protobuf/reflection.py \ python/google/protobuf/service.py \ python/google/protobuf/service_reflection.py \ diff --git a/cmake/libprotoc.cmake b/cmake/libprotoc.cmake index 29b32538..b663e354 100644 --- a/cmake/libprotoc.cmake +++ b/cmake/libprotoc.cmake @@ -88,6 +88,7 @@ set(libprotoc_files ${protobuf_source_dir}/src/google/protobuf/compiler/php/php_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.cc ${protobuf_source_dir}/src/google/protobuf/compiler/plugin.pb.cc + ${protobuf_source_dir}/src/google/protobuf/compiler/profile.pb.cc ${protobuf_source_dir}/src/google/protobuf/compiler/python/python_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/ruby/ruby_generator.cc ${protobuf_source_dir}/src/google/protobuf/compiler/subprocess.cc diff --git a/cmake/tests.cmake b/cmake/tests.cmake index 1470e4b0..38dc0b52 100644 --- a/cmake/tests.cmake +++ b/cmake/tests.cmake @@ -43,6 +43,9 @@ set(tests_protos google/protobuf/unittest_empty.proto google/protobuf/unittest_import.proto google/protobuf/unittest_import_public.proto + google/protobuf/unittest_lazy_dependencies.proto + google/protobuf/unittest_lazy_dependencies_custom_option.proto + google/protobuf/unittest_lazy_dependencies_enum.proto google/protobuf/unittest_lite_imports_nonlite.proto google/protobuf/unittest_mset.proto google/protobuf/unittest_mset_wire_format.proto @@ -207,7 +210,7 @@ set(lite_test_files ${protobuf_source_dir}/src/google/protobuf/lite_unittest.cc ) add_executable(lite-test ${lite_test_files} ${common_lite_test_files} ${lite_test_proto_files}) -target_link_libraries(lite-test libprotobuf-lite) +target_link_libraries(lite-test libprotobuf-lite gmock_main) set(lite_arena_test_files ${protobuf_source_dir}/src/google/protobuf/lite_arena_unittest.cc diff --git a/conformance/conformance_test.cc b/conformance/conformance_test.cc index 1e5387a5..0dd7787c 100644 --- a/conformance/conformance_test.cc +++ b/conformance/conformance_test.cc @@ -708,6 +708,21 @@ bool ConformanceTestSuite::CheckSetEmpty(const set& set_to_check, } } +void ConformanceTestSuite::TestIllegalTags() { + // field num 0 is illegal + string nullfield[] = { + "\1DEADBEEF", + "\2\1\1", + "\3\4", + "\5DEAD" + }; + for (int i = 0; i < 4; i++) { + string name = "IllegalZeroFieldNum_Case_0"; + name.back() += i; + ExpectParseFailureForProto(nullfield[i], name, REQUIRED); + } +} + bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, std::string* output) { runner_ = runner; @@ -728,6 +743,8 @@ bool ConformanceTestSuite::RunSuite(ConformanceTestRunner* runner, TestPrematureEOFForType(static_cast(i)); } + TestIllegalTags(); + int64 kInt64Min = -9223372036854775808ULL; int64 kInt64Max = 9223372036854775807ULL; uint64 kUint64Max = 18446744073709551615ULL; diff --git a/conformance/conformance_test.h b/conformance/conformance_test.h index 5f05a25b..4e40a6ac 100644 --- a/conformance/conformance_test.h +++ b/conformance/conformance_test.h @@ -201,6 +201,7 @@ class ConformanceTestSuite { const std::string& test_name, ConformanceLevel level); void TestPrematureEOFForType(google::protobuf::FieldDescriptor::Type type); + void TestIllegalTags(); void TestValidDataForType( google::protobuf::FieldDescriptor::Type, std::vector> values); diff --git a/conformance/failure_list_cpp.txt b/conformance/failure_list_cpp.txt index 8cfd74da..8a4fa7eb 100644 --- a/conformance/failure_list_cpp.txt +++ b/conformance/failure_list_cpp.txt @@ -32,7 +32,6 @@ Recommended.JsonInput.TrailingCommaInAnObject Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines Recommended.JsonInput.TrailingCommaInAnObjectWithSpace Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE Required.ProtobufInput.PrematureEofInPackedField.BOOL @@ -43,4 +42,3 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32 Required.ProtobufInput.PrematureEofInPackedField.SINT64 Required.ProtobufInput.PrematureEofInPackedField.UINT32 Required.ProtobufInput.PrematureEofInPackedField.UINT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index 632940ef..a4f0f102 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -32,6 +32,7 @@ Recommended.JsonInput.StringFieldSingleQuoteValue Recommended.JsonInput.StringFieldSurrogateInWrongOrder Recommended.JsonInput.StringFieldUnpairedHighSurrogate Recommended.JsonInput.StringFieldUnpairedLowSurrogate +Recommended.JsonInput.StringFieldUppercaseEscapeLetter Recommended.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.JsonInput.Uint64MapFieldKeyNotQuoted Required.JsonInput.EnumFieldNotQuoted diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 9d556a03..0e907fe1 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,13 +1,615 @@ +Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.JsonInput.BoolFieldAllCapitalFalse +Recommended.JsonInput.BoolFieldAllCapitalTrue +Recommended.JsonInput.BoolFieldCamelCaseFalse +Recommended.JsonInput.BoolFieldCamelCaseTrue +Recommended.JsonInput.BoolFieldDoubleQuotedFalse +Recommended.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.JsonInput.BoolFieldIntegerOne +Recommended.JsonInput.BoolFieldIntegerZero +Recommended.JsonInput.BoolMapFieldKeyNotQuoted Recommended.JsonInput.DoubleFieldInfinityNotQuoted Recommended.JsonInput.DoubleFieldNanNotQuoted Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted +Recommended.JsonInput.DurationHas3FractionalDigits.Validator +Recommended.JsonInput.DurationHas6FractionalDigits.Validator +Recommended.JsonInput.DurationHas9FractionalDigits.Validator +Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator +Recommended.JsonInput.FieldMaskInvalidCharacter +Recommended.JsonInput.FieldNameDuplicate +Recommended.JsonInput.FieldNameDuplicateDifferentCasing1 +Recommended.JsonInput.FieldNameDuplicateDifferentCasing2 +Recommended.JsonInput.FieldNameNotQuoted +Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator Recommended.JsonInput.FloatFieldInfinityNotQuoted Recommended.JsonInput.FloatFieldNanNotQuoted Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted +Recommended.JsonInput.Int32MapFieldKeyNotQuoted +Recommended.JsonInput.Int64FieldBeString.Validator +Recommended.JsonInput.Int64MapFieldKeyNotQuoted +Recommended.JsonInput.JsonWithComments +Recommended.JsonInput.MapFieldKeyIsNull +Recommended.JsonInput.MapFieldValueIsNull +Recommended.JsonInput.MissingCommaMultiline +Recommended.JsonInput.MissingCommaOneLine +Recommended.JsonInput.MultilineNoSpaces.JsonOutput +Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput +Recommended.JsonInput.MultilineWithSpaces.JsonOutput +Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput +Recommended.JsonInput.OneLineNoSpaces.JsonOutput +Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput +Recommended.JsonInput.OneLineWithSpaces.JsonOutput +Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput +Recommended.JsonInput.OneofZeroBool.JsonOutput +Recommended.JsonInput.OneofZeroBool.ProtobufOutput +Recommended.JsonInput.OneofZeroBytes.JsonOutput +Recommended.JsonInput.OneofZeroBytes.ProtobufOutput +Recommended.JsonInput.OneofZeroDouble.JsonOutput +Recommended.JsonInput.OneofZeroDouble.ProtobufOutput +Recommended.JsonInput.OneofZeroEnum.JsonOutput +Recommended.JsonInput.OneofZeroEnum.ProtobufOutput +Recommended.JsonInput.OneofZeroFloat.JsonOutput +Recommended.JsonInput.OneofZeroFloat.ProtobufOutput +Recommended.JsonInput.OneofZeroMessage.JsonOutput +Recommended.JsonInput.OneofZeroMessage.ProtobufOutput +Recommended.JsonInput.OneofZeroString.JsonOutput +Recommended.JsonInput.OneofZeroString.ProtobufOutput +Recommended.JsonInput.OneofZeroUint32.JsonOutput +Recommended.JsonInput.OneofZeroUint32.ProtobufOutput +Recommended.JsonInput.OneofZeroUint64.JsonOutput +Recommended.JsonInput.OneofZeroUint64.ProtobufOutput +Recommended.JsonInput.RepeatedFieldMessageElementIsNull +Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull +Recommended.JsonInput.RepeatedFieldTrailingComma +Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace +Recommended.JsonInput.StringEndsWithEscapeChar +Recommended.JsonInput.StringFieldInvalidEscape +Recommended.JsonInput.StringFieldSingleQuoteBoth +Recommended.JsonInput.StringFieldSingleQuoteKey +Recommended.JsonInput.StringFieldSingleQuoteValue +Recommended.JsonInput.StringFieldSurrogateInWrongOrder +Recommended.JsonInput.StringFieldUnpairedHighSurrogate +Recommended.JsonInput.StringFieldUnpairedLowSurrogate +Recommended.JsonInput.StringFieldUnterminatedEscape +Recommended.JsonInput.StringFieldUppercaseEscapeLetter +Recommended.JsonInput.TimestampHas3FractionalDigits.Validator +Recommended.JsonInput.TimestampHas6FractionalDigits.Validator +Recommended.JsonInput.TimestampHas9FractionalDigits.Validator +Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator +Recommended.JsonInput.TimestampZeroNormalized.Validator +Recommended.JsonInput.TrailingCommaInAnObject +Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines +Recommended.JsonInput.TrailingCommaInAnObjectWithSpace +Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace +Recommended.JsonInput.Uint32MapFieldKeyNotQuoted +Recommended.JsonInput.Uint64FieldBeString.Validator +Recommended.JsonInput.Uint64MapFieldKeyNotQuoted +Recommended.ProtobufInput.OneofZeroBool.JsonOutput +Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput +Recommended.ProtobufInput.OneofZeroBytes.JsonOutput +Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput +Recommended.ProtobufInput.OneofZeroDouble.JsonOutput +Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput +Recommended.ProtobufInput.OneofZeroEnum.JsonOutput +Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput +Recommended.ProtobufInput.OneofZeroFloat.JsonOutput +Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput +Recommended.ProtobufInput.OneofZeroMessage.JsonOutput +Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput +Recommended.ProtobufInput.OneofZeroString.JsonOutput +Recommended.ProtobufInput.OneofZeroString.ProtobufOutput +Recommended.ProtobufInput.OneofZeroUint32.JsonOutput +Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput +Recommended.ProtobufInput.OneofZeroUint64.JsonOutput +Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput +Required.DurationProtoInputTooLarge.JsonOutput +Required.DurationProtoInputTooSmall.JsonOutput +Required.JsonInput.AllFieldAcceptNull.JsonOutput +Required.JsonInput.AllFieldAcceptNull.ProtobufOutput +Required.JsonInput.Any.JsonOutput +Required.JsonInput.Any.ProtobufOutput +Required.JsonInput.AnyNested.JsonOutput +Required.JsonInput.AnyNested.ProtobufOutput +Required.JsonInput.AnyUnorderedTypeTag.JsonOutput +Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput +Required.JsonInput.AnyWithDuration.JsonOutput +Required.JsonInput.AnyWithDuration.ProtobufOutput +Required.JsonInput.AnyWithFieldMask.JsonOutput +Required.JsonInput.AnyWithFieldMask.ProtobufOutput +Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput +Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput +Required.JsonInput.AnyWithStruct.JsonOutput +Required.JsonInput.AnyWithStruct.ProtobufOutput +Required.JsonInput.AnyWithTimestamp.JsonOutput +Required.JsonInput.AnyWithTimestamp.ProtobufOutput +Required.JsonInput.AnyWithValueForInteger.JsonOutput +Required.JsonInput.AnyWithValueForInteger.ProtobufOutput +Required.JsonInput.AnyWithValueForJsonObject.JsonOutput +Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput +Required.JsonInput.BoolFieldFalse.JsonOutput +Required.JsonInput.BoolFieldFalse.ProtobufOutput +Required.JsonInput.BoolFieldTrue.JsonOutput +Required.JsonInput.BoolFieldTrue.ProtobufOutput +Required.JsonInput.BoolMapEscapedKey.JsonOutput +Required.JsonInput.BoolMapEscapedKey.ProtobufOutput +Required.JsonInput.BoolMapField.JsonOutput +Required.JsonInput.BoolMapField.ProtobufOutput +Required.JsonInput.BytesField.JsonOutput +Required.JsonInput.BytesField.ProtobufOutput Required.JsonInput.BytesFieldInvalidBase64Characters +Required.JsonInput.BytesRepeatedField.JsonOutput +Required.JsonInput.BytesRepeatedField.ProtobufOutput +Required.JsonInput.DoubleFieldInfinity.JsonOutput +Required.JsonInput.DoubleFieldInfinity.ProtobufOutput +Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput +Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput +Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput +Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput +Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput +Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput +Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput +Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput +Required.JsonInput.DoubleFieldNan.JsonOutput +Required.JsonInput.DoubleFieldNan.ProtobufOutput +Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput +Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput +Required.JsonInput.DoubleFieldQuotedValue.JsonOutput +Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput +Required.JsonInput.DoubleFieldTooLarge Required.JsonInput.DoubleFieldTooSmall +Required.JsonInput.DurationJsonInputTooLarge +Required.JsonInput.DurationJsonInputTooSmall +Required.JsonInput.DurationMaxValue.JsonOutput +Required.JsonInput.DurationMaxValue.ProtobufOutput +Required.JsonInput.DurationMinValue.JsonOutput +Required.JsonInput.DurationMinValue.ProtobufOutput +Required.JsonInput.DurationMissingS +Required.JsonInput.DurationRepeatedValue.JsonOutput +Required.JsonInput.DurationRepeatedValue.ProtobufOutput +Required.JsonInput.EnumField.JsonOutput +Required.JsonInput.EnumField.ProtobufOutput +Required.JsonInput.EnumFieldNotQuoted +Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput +Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput +Required.JsonInput.EnumFieldNumericValueZero.JsonOutput +Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput Required.JsonInput.EnumFieldUnknownValue.Validator +Required.JsonInput.EnumRepeatedField.JsonOutput +Required.JsonInput.EnumRepeatedField.ProtobufOutput +Required.JsonInput.FieldMask.JsonOutput +Required.JsonInput.FieldMask.ProtobufOutput +Required.JsonInput.FieldNameEscaped.JsonOutput +Required.JsonInput.FieldNameEscaped.ProtobufOutput +Required.JsonInput.FieldNameInLowerCamelCase.Validator +Required.JsonInput.FieldNameInSnakeCase.JsonOutput +Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput +Required.JsonInput.FieldNameWithMixedCases.JsonOutput +Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput +Required.JsonInput.FieldNameWithMixedCases.Validator +Required.JsonInput.FieldNameWithNumbers.JsonOutput +Required.JsonInput.FieldNameWithNumbers.ProtobufOutput +Required.JsonInput.FieldNameWithNumbers.Validator +Required.JsonInput.FloatFieldInfinity.JsonOutput +Required.JsonInput.FloatFieldInfinity.ProtobufOutput +Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput +Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput +Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput +Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput +Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput +Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput +Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput +Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput +Required.JsonInput.FloatFieldNan.JsonOutput +Required.JsonInput.FloatFieldNan.ProtobufOutput +Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput +Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput +Required.JsonInput.FloatFieldQuotedValue.JsonOutput +Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput Required.JsonInput.FloatFieldTooLarge Required.JsonInput.FloatFieldTooSmall +Required.JsonInput.HelloWorld.JsonOutput +Required.JsonInput.HelloWorld.ProtobufOutput +Required.JsonInput.Int32FieldExponentialFormat.JsonOutput +Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput +Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput +Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput +Required.JsonInput.Int32FieldLeadingSpace +Required.JsonInput.Int32FieldLeadingZero +Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput +Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput +Required.JsonInput.Int32FieldMaxValue.JsonOutput +Required.JsonInput.Int32FieldMaxValue.ProtobufOutput +Required.JsonInput.Int32FieldMinFloatValue.JsonOutput +Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput +Required.JsonInput.Int32FieldMinValue.JsonOutput +Required.JsonInput.Int32FieldMinValue.ProtobufOutput +Required.JsonInput.Int32FieldNegativeWithLeadingZero +Required.JsonInput.Int32FieldNotInteger +Required.JsonInput.Int32FieldNotNumber +Required.JsonInput.Int32FieldPlusSign +Required.JsonInput.Int32FieldStringValue.JsonOutput +Required.JsonInput.Int32FieldStringValue.ProtobufOutput +Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput +Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput +Required.JsonInput.Int32FieldTooLarge +Required.JsonInput.Int32FieldTooSmall +Required.JsonInput.Int32FieldTrailingSpace +Required.JsonInput.Int32MapEscapedKey.JsonOutput +Required.JsonInput.Int32MapEscapedKey.ProtobufOutput +Required.JsonInput.Int32MapField.JsonOutput +Required.JsonInput.Int32MapField.ProtobufOutput +Required.JsonInput.Int64FieldMaxValue.JsonOutput +Required.JsonInput.Int64FieldMaxValue.ProtobufOutput +Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput +Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput +Required.JsonInput.Int64FieldMinValue.JsonOutput +Required.JsonInput.Int64FieldMinValue.ProtobufOutput +Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput +Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput +Required.JsonInput.Int64FieldNotInteger +Required.JsonInput.Int64FieldNotNumber +Required.JsonInput.Int64FieldTooLarge +Required.JsonInput.Int64FieldTooSmall +Required.JsonInput.Int64MapEscapedKey.JsonOutput +Required.JsonInput.Int64MapEscapedKey.ProtobufOutput +Required.JsonInput.Int64MapField.JsonOutput +Required.JsonInput.Int64MapField.ProtobufOutput +Required.JsonInput.MessageField.JsonOutput +Required.JsonInput.MessageField.ProtobufOutput +Required.JsonInput.MessageMapField.JsonOutput +Required.JsonInput.MessageMapField.ProtobufOutput +Required.JsonInput.MessageRepeatedField.JsonOutput +Required.JsonInput.MessageRepeatedField.ProtobufOutput +Required.JsonInput.OneofFieldDuplicate +Required.JsonInput.OptionalBoolWrapper.JsonOutput +Required.JsonInput.OptionalBoolWrapper.ProtobufOutput +Required.JsonInput.OptionalBytesWrapper.JsonOutput +Required.JsonInput.OptionalBytesWrapper.ProtobufOutput +Required.JsonInput.OptionalDoubleWrapper.JsonOutput +Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput +Required.JsonInput.OptionalFloatWrapper.JsonOutput +Required.JsonInput.OptionalFloatWrapper.ProtobufOutput +Required.JsonInput.OptionalInt32Wrapper.JsonOutput +Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput +Required.JsonInput.OptionalInt64Wrapper.JsonOutput +Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput +Required.JsonInput.OptionalStringWrapper.JsonOutput +Required.JsonInput.OptionalStringWrapper.ProtobufOutput +Required.JsonInput.OptionalUint32Wrapper.JsonOutput +Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput +Required.JsonInput.OptionalUint64Wrapper.JsonOutput +Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput +Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput +Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput +Required.JsonInput.OriginalProtoFieldName.JsonOutput +Required.JsonInput.OriginalProtoFieldName.ProtobufOutput +Required.JsonInput.PrimitiveRepeatedField.JsonOutput +Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput +Required.JsonInput.RepeatedBoolWrapper.JsonOutput +Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput +Required.JsonInput.RepeatedBytesWrapper.JsonOutput +Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput +Required.JsonInput.RepeatedDoubleWrapper.JsonOutput +Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage +Required.JsonInput.RepeatedFloatWrapper.JsonOutput +Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput +Required.JsonInput.RepeatedInt32Wrapper.JsonOutput +Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput +Required.JsonInput.RepeatedInt64Wrapper.JsonOutput +Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput +Required.JsonInput.RepeatedStringWrapper.JsonOutput +Required.JsonInput.RepeatedStringWrapper.ProtobufOutput +Required.JsonInput.RepeatedUint32Wrapper.JsonOutput +Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput +Required.JsonInput.RepeatedUint64Wrapper.JsonOutput +Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput +Required.JsonInput.StringField.JsonOutput +Required.JsonInput.StringField.ProtobufOutput +Required.JsonInput.StringFieldEscape.JsonOutput +Required.JsonInput.StringFieldEscape.ProtobufOutput +Required.JsonInput.StringFieldNotAString +Required.JsonInput.StringFieldSurrogatePair.JsonOutput +Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput +Required.JsonInput.StringFieldUnicode.JsonOutput +Required.JsonInput.StringFieldUnicode.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscape.JsonOutput +Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput +Required.JsonInput.StringRepeatedField.JsonOutput +Required.JsonInput.StringRepeatedField.ProtobufOutput +Required.JsonInput.Struct.JsonOutput +Required.JsonInput.Struct.ProtobufOutput Required.JsonInput.TimestampJsonInputLowercaseT +Required.JsonInput.TimestampJsonInputLowercaseZ +Required.JsonInput.TimestampJsonInputMissingT +Required.JsonInput.TimestampJsonInputMissingZ +Required.JsonInput.TimestampJsonInputTooLarge +Required.JsonInput.TimestampJsonInputTooSmall +Required.JsonInput.TimestampMaxValue.JsonOutput +Required.JsonInput.TimestampMaxValue.ProtobufOutput +Required.JsonInput.TimestampMinValue.JsonOutput +Required.JsonInput.TimestampMinValue.ProtobufOutput +Required.JsonInput.TimestampRepeatedValue.JsonOutput +Required.JsonInput.TimestampRepeatedValue.ProtobufOutput +Required.JsonInput.TimestampWithNegativeOffset.JsonOutput +Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput +Required.JsonInput.TimestampWithPositiveOffset.JsonOutput +Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput +Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput +Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput +Required.JsonInput.Uint32FieldMaxValue.JsonOutput +Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput +Required.JsonInput.Uint32FieldNotInteger +Required.JsonInput.Uint32FieldNotNumber +Required.JsonInput.Uint32FieldTooLarge +Required.JsonInput.Uint32MapField.JsonOutput +Required.JsonInput.Uint32MapField.ProtobufOutput +Required.JsonInput.Uint64FieldMaxValue.JsonOutput +Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput +Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput +Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput +Required.JsonInput.Uint64FieldNotInteger +Required.JsonInput.Uint64FieldNotNumber +Required.JsonInput.Uint64FieldTooLarge +Required.JsonInput.Uint64MapField.JsonOutput +Required.JsonInput.Uint64MapField.ProtobufOutput +Required.JsonInput.ValueAcceptBool.JsonOutput +Required.JsonInput.ValueAcceptBool.ProtobufOutput +Required.JsonInput.ValueAcceptFloat.JsonOutput +Required.JsonInput.ValueAcceptFloat.ProtobufOutput +Required.JsonInput.ValueAcceptInteger.JsonOutput +Required.JsonInput.ValueAcceptInteger.ProtobufOutput +Required.JsonInput.ValueAcceptList.JsonOutput +Required.JsonInput.ValueAcceptList.ProtobufOutput +Required.JsonInput.ValueAcceptNull.JsonOutput +Required.JsonInput.ValueAcceptNull.ProtobufOutput +Required.JsonInput.ValueAcceptObject.JsonOutput +Required.JsonInput.ValueAcceptObject.ProtobufOutput +Required.JsonInput.ValueAcceptString.JsonOutput +Required.JsonInput.ValueAcceptString.ProtobufOutput +Required.JsonInput.WrapperTypesWithNullValue.JsonOutput +Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput +Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput +Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput +Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput +Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput +Required.ProtobufInput.IllegalZeroFieldNum_Case_0 +Required.ProtobufInput.IllegalZeroFieldNum_Case_1 +Required.ProtobufInput.IllegalZeroFieldNum_Case_2 +Required.ProtobufInput.IllegalZeroFieldNum_Case_3 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL +Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES +Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING +Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64 +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING +Required.ProtobufInput.PrematureEofInPackedField.BOOL +Required.ProtobufInput.PrematureEofInPackedField.DOUBLE +Required.ProtobufInput.PrematureEofInPackedField.ENUM +Required.ProtobufInput.PrematureEofInPackedField.FIXED32 +Required.ProtobufInput.PrematureEofInPackedField.FIXED64 +Required.ProtobufInput.PrematureEofInPackedField.FLOAT +Required.ProtobufInput.PrematureEofInPackedField.INT32 +Required.ProtobufInput.PrematureEofInPackedField.INT64 +Required.ProtobufInput.PrematureEofInPackedField.SFIXED32 +Required.ProtobufInput.PrematureEofInPackedField.SFIXED64 +Required.ProtobufInput.PrematureEofInPackedField.SINT32 +Required.ProtobufInput.PrematureEofInPackedField.SINT64 +Required.ProtobufInput.PrematureEofInPackedField.UINT32 +Required.ProtobufInput.PrematureEofInPackedField.UINT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL +Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE +Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM +Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT +Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64 +Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL +Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES +Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM +Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT +Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING +Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64 +Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput +Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput +Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput +Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput +Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput +Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput +Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput +Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput +Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput +Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput +Required.TimestampProtoInputTooLarge.JsonOutput +Required.TimestampProtoInputTooSmall.JsonOutput diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index 92404d2f..d72d79cd 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -7,21 +7,461 @@ # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? +Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput +Recommended.FieldMaskPathsDontRoundTrip.JsonOutput +Recommended.FieldMaskTooManyUnderscore.JsonOutput +Recommended.JsonInput.BoolFieldAllCapitalFalse +Recommended.JsonInput.BoolFieldAllCapitalTrue +Recommended.JsonInput.BoolFieldCamelCaseFalse +Recommended.JsonInput.BoolFieldCamelCaseTrue +Recommended.JsonInput.BoolFieldDoubleQuotedFalse +Recommended.JsonInput.BoolFieldDoubleQuotedTrue +Recommended.JsonInput.BoolFieldIntegerOne +Recommended.JsonInput.BoolFieldIntegerZero +Recommended.JsonInput.BoolMapFieldKeyNotQuoted Recommended.JsonInput.DoubleFieldInfinityNotQuoted Recommended.JsonInput.DoubleFieldNanNotQuoted Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted +Recommended.JsonInput.DurationHas3FractionalDigits.Validator +Recommended.JsonInput.DurationHas6FractionalDigits.Validator +Recommended.JsonInput.DurationHas9FractionalDigits.Validator +Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator +Recommended.JsonInput.FieldMaskInvalidCharacter +Recommended.JsonInput.FieldNameDuplicate +Recommended.JsonInput.FieldNameDuplicateDifferentCasing1 +Recommended.JsonInput.FieldNameDuplicateDifferentCasing2 +Recommended.JsonInput.FieldNameNotQuoted +Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput +Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator Recommended.JsonInput.FloatFieldInfinityNotQuoted Recommended.JsonInput.FloatFieldNanNotQuoted Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted +Recommended.JsonInput.Int32MapFieldKeyNotQuoted +Recommended.JsonInput.Int64FieldBeString.Validator +Recommended.JsonInput.Int64MapFieldKeyNotQuoted +Recommended.JsonInput.JsonWithComments +Recommended.JsonInput.MapFieldKeyIsNull +Recommended.JsonInput.MapFieldValueIsNull +Recommended.JsonInput.MissingCommaMultiline +Recommended.JsonInput.MissingCommaOneLine +Recommended.JsonInput.MultilineNoSpaces.JsonOutput +Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput +Recommended.JsonInput.MultilineWithSpaces.JsonOutput +Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput +Recommended.JsonInput.OneLineNoSpaces.JsonOutput +Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput +Recommended.JsonInput.OneLineWithSpaces.JsonOutput +Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput +Recommended.JsonInput.OneofZeroBool.JsonOutput +Recommended.JsonInput.OneofZeroBool.ProtobufOutput +Recommended.JsonInput.OneofZeroBytes.JsonOutput +Recommended.JsonInput.OneofZeroBytes.ProtobufOutput +Recommended.JsonInput.OneofZeroDouble.JsonOutput +Recommended.JsonInput.OneofZeroDouble.ProtobufOutput +Recommended.JsonInput.OneofZeroEnum.JsonOutput +Recommended.JsonInput.OneofZeroEnum.ProtobufOutput +Recommended.JsonInput.OneofZeroFloat.JsonOutput +Recommended.JsonInput.OneofZeroFloat.ProtobufOutput +Recommended.JsonInput.OneofZeroMessage.JsonOutput +Recommended.JsonInput.OneofZeroMessage.ProtobufOutput +Recommended.JsonInput.OneofZeroString.JsonOutput +Recommended.JsonInput.OneofZeroString.ProtobufOutput +Recommended.JsonInput.OneofZeroUint32.JsonOutput +Recommended.JsonInput.OneofZeroUint32.ProtobufOutput +Recommended.JsonInput.OneofZeroUint64.JsonOutput +Recommended.JsonInput.OneofZeroUint64.ProtobufOutput +Recommended.JsonInput.RepeatedFieldMessageElementIsNull +Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull +Recommended.JsonInput.RepeatedFieldTrailingComma +Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace +Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace +Recommended.JsonInput.StringEndsWithEscapeChar +Recommended.JsonInput.StringFieldInvalidEscape +Recommended.JsonInput.StringFieldSingleQuoteBoth +Recommended.JsonInput.StringFieldSingleQuoteKey +Recommended.JsonInput.StringFieldSingleQuoteValue +Recommended.JsonInput.StringFieldSurrogateInWrongOrder +Recommended.JsonInput.StringFieldUnpairedHighSurrogate +Recommended.JsonInput.StringFieldUnpairedLowSurrogate +Recommended.JsonInput.StringFieldUnterminatedEscape +Recommended.JsonInput.StringFieldUppercaseEscapeLetter +Recommended.JsonInput.TimestampHas3FractionalDigits.Validator +Recommended.JsonInput.TimestampHas6FractionalDigits.Validator +Recommended.JsonInput.TimestampHas9FractionalDigits.Validator +Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator +Recommended.JsonInput.TimestampZeroNormalized.Validator +Recommended.JsonInput.TrailingCommaInAnObject +Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines +Recommended.JsonInput.TrailingCommaInAnObjectWithSpace +Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace +Recommended.JsonInput.Uint32MapFieldKeyNotQuoted +Recommended.JsonInput.Uint64FieldBeString.Validator +Recommended.JsonInput.Uint64MapFieldKeyNotQuoted +Recommended.ProtobufInput.OneofZeroBool.JsonOutput +Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput +Recommended.ProtobufInput.OneofZeroBytes.JsonOutput +Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput +Recommended.ProtobufInput.OneofZeroDouble.JsonOutput +Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput +Recommended.ProtobufInput.OneofZeroEnum.JsonOutput +Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput +Recommended.ProtobufInput.OneofZeroFloat.JsonOutput +Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput +Recommended.ProtobufInput.OneofZeroMessage.JsonOutput +Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput +Recommended.ProtobufInput.OneofZeroString.JsonOutput +Recommended.ProtobufInput.OneofZeroString.ProtobufOutput +Recommended.ProtobufInput.OneofZeroUint32.JsonOutput +Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput +Recommended.ProtobufInput.OneofZeroUint64.JsonOutput +Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput +Required.DurationProtoInputTooLarge.JsonOutput +Required.DurationProtoInputTooSmall.JsonOutput +Required.JsonInput.AllFieldAcceptNull.JsonOutput +Required.JsonInput.AllFieldAcceptNull.ProtobufOutput +Required.JsonInput.Any.JsonOutput +Required.JsonInput.Any.ProtobufOutput +Required.JsonInput.AnyNested.JsonOutput +Required.JsonInput.AnyNested.ProtobufOutput +Required.JsonInput.AnyUnorderedTypeTag.JsonOutput +Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput +Required.JsonInput.AnyWithDuration.JsonOutput +Required.JsonInput.AnyWithDuration.ProtobufOutput +Required.JsonInput.AnyWithFieldMask.JsonOutput +Required.JsonInput.AnyWithFieldMask.ProtobufOutput +Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput +Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput +Required.JsonInput.AnyWithStruct.JsonOutput +Required.JsonInput.AnyWithStruct.ProtobufOutput +Required.JsonInput.AnyWithTimestamp.JsonOutput +Required.JsonInput.AnyWithTimestamp.ProtobufOutput +Required.JsonInput.AnyWithValueForInteger.JsonOutput +Required.JsonInput.AnyWithValueForInteger.ProtobufOutput +Required.JsonInput.AnyWithValueForJsonObject.JsonOutput +Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput +Required.JsonInput.BoolFieldFalse.JsonOutput +Required.JsonInput.BoolFieldFalse.ProtobufOutput +Required.JsonInput.BoolFieldTrue.JsonOutput +Required.JsonInput.BoolFieldTrue.ProtobufOutput +Required.JsonInput.BoolMapEscapedKey.JsonOutput +Required.JsonInput.BoolMapEscapedKey.ProtobufOutput +Required.JsonInput.BoolMapField.JsonOutput +Required.JsonInput.BoolMapField.ProtobufOutput +Required.JsonInput.BytesField.JsonOutput +Required.JsonInput.BytesField.ProtobufOutput Required.JsonInput.BytesFieldInvalidBase64Characters +Required.JsonInput.BytesRepeatedField.JsonOutput +Required.JsonInput.BytesRepeatedField.ProtobufOutput +Required.JsonInput.DoubleFieldInfinity.JsonOutput +Required.JsonInput.DoubleFieldInfinity.ProtobufOutput +Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput +Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput +Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput +Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput +Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput +Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput +Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput +Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput +Required.JsonInput.DoubleFieldNan.JsonOutput +Required.JsonInput.DoubleFieldNan.ProtobufOutput +Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput +Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput +Required.JsonInput.DoubleFieldQuotedValue.JsonOutput +Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput +Required.JsonInput.DoubleFieldTooLarge Required.JsonInput.DoubleFieldTooSmall +Required.JsonInput.DurationJsonInputTooLarge +Required.JsonInput.DurationJsonInputTooSmall +Required.JsonInput.DurationMaxValue.JsonOutput +Required.JsonInput.DurationMaxValue.ProtobufOutput +Required.JsonInput.DurationMinValue.JsonOutput +Required.JsonInput.DurationMinValue.ProtobufOutput +Required.JsonInput.DurationMissingS +Required.JsonInput.DurationRepeatedValue.JsonOutput +Required.JsonInput.DurationRepeatedValue.ProtobufOutput +Required.JsonInput.EnumField.JsonOutput +Required.JsonInput.EnumField.ProtobufOutput +Required.JsonInput.EnumFieldNotQuoted +Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput +Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput +Required.JsonInput.EnumFieldNumericValueZero.JsonOutput +Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput Required.JsonInput.EnumFieldUnknownValue.Validator +Required.JsonInput.EnumRepeatedField.JsonOutput +Required.JsonInput.EnumRepeatedField.ProtobufOutput +Required.JsonInput.FieldMask.JsonOutput +Required.JsonInput.FieldMask.ProtobufOutput +Required.JsonInput.FieldNameEscaped.JsonOutput +Required.JsonInput.FieldNameEscaped.ProtobufOutput +Required.JsonInput.FieldNameInLowerCamelCase.Validator +Required.JsonInput.FieldNameInSnakeCase.JsonOutput +Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput +Required.JsonInput.FieldNameWithMixedCases.JsonOutput +Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput +Required.JsonInput.FieldNameWithMixedCases.Validator +Required.JsonInput.FieldNameWithNumbers.JsonOutput +Required.JsonInput.FieldNameWithNumbers.ProtobufOutput +Required.JsonInput.FieldNameWithNumbers.Validator +Required.JsonInput.FloatFieldInfinity.JsonOutput +Required.JsonInput.FloatFieldInfinity.ProtobufOutput +Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput +Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput +Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput +Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput +Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput +Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput +Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput +Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput +Required.JsonInput.FloatFieldNan.JsonOutput +Required.JsonInput.FloatFieldNan.ProtobufOutput +Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput +Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput +Required.JsonInput.FloatFieldQuotedValue.JsonOutput +Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput Required.JsonInput.FloatFieldTooLarge Required.JsonInput.FloatFieldTooSmall +Required.JsonInput.HelloWorld.JsonOutput +Required.JsonInput.HelloWorld.ProtobufOutput +Required.JsonInput.Int32FieldExponentialFormat.JsonOutput +Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput +Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput +Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput +Required.JsonInput.Int32FieldLeadingSpace +Required.JsonInput.Int32FieldLeadingZero +Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput +Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput +Required.JsonInput.Int32FieldMaxValue.JsonOutput +Required.JsonInput.Int32FieldMaxValue.ProtobufOutput +Required.JsonInput.Int32FieldMinFloatValue.JsonOutput +Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput +Required.JsonInput.Int32FieldMinValue.JsonOutput +Required.JsonInput.Int32FieldMinValue.ProtobufOutput +Required.JsonInput.Int32FieldNegativeWithLeadingZero +Required.JsonInput.Int32FieldNotInteger +Required.JsonInput.Int32FieldNotNumber +Required.JsonInput.Int32FieldPlusSign +Required.JsonInput.Int32FieldStringValue.JsonOutput +Required.JsonInput.Int32FieldStringValue.ProtobufOutput +Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput +Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput +Required.JsonInput.Int32FieldTooLarge +Required.JsonInput.Int32FieldTooSmall +Required.JsonInput.Int32FieldTrailingSpace +Required.JsonInput.Int32MapEscapedKey.JsonOutput +Required.JsonInput.Int32MapEscapedKey.ProtobufOutput +Required.JsonInput.Int32MapField.JsonOutput +Required.JsonInput.Int32MapField.ProtobufOutput +Required.JsonInput.Int64FieldMaxValue.JsonOutput +Required.JsonInput.Int64FieldMaxValue.ProtobufOutput +Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput +Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput +Required.JsonInput.Int64FieldMinValue.JsonOutput +Required.JsonInput.Int64FieldMinValue.ProtobufOutput +Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput +Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput +Required.JsonInput.Int64FieldNotInteger +Required.JsonInput.Int64FieldNotNumber +Required.JsonInput.Int64FieldTooLarge +Required.JsonInput.Int64FieldTooSmall +Required.JsonInput.Int64MapEscapedKey.JsonOutput +Required.JsonInput.Int64MapEscapedKey.ProtobufOutput +Required.JsonInput.Int64MapField.JsonOutput +Required.JsonInput.Int64MapField.ProtobufOutput +Required.JsonInput.MessageField.JsonOutput +Required.JsonInput.MessageField.ProtobufOutput +Required.JsonInput.MessageMapField.JsonOutput +Required.JsonInput.MessageMapField.ProtobufOutput +Required.JsonInput.MessageRepeatedField.JsonOutput +Required.JsonInput.MessageRepeatedField.ProtobufOutput +Required.JsonInput.OneofFieldDuplicate +Required.JsonInput.OptionalBoolWrapper.JsonOutput +Required.JsonInput.OptionalBoolWrapper.ProtobufOutput +Required.JsonInput.OptionalBytesWrapper.JsonOutput +Required.JsonInput.OptionalBytesWrapper.ProtobufOutput +Required.JsonInput.OptionalDoubleWrapper.JsonOutput +Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput +Required.JsonInput.OptionalFloatWrapper.JsonOutput +Required.JsonInput.OptionalFloatWrapper.ProtobufOutput +Required.JsonInput.OptionalInt32Wrapper.JsonOutput +Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput +Required.JsonInput.OptionalInt64Wrapper.JsonOutput +Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput +Required.JsonInput.OptionalStringWrapper.JsonOutput +Required.JsonInput.OptionalStringWrapper.ProtobufOutput +Required.JsonInput.OptionalUint32Wrapper.JsonOutput +Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput +Required.JsonInput.OptionalUint64Wrapper.JsonOutput +Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput +Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput +Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput +Required.JsonInput.OriginalProtoFieldName.JsonOutput +Required.JsonInput.OriginalProtoFieldName.ProtobufOutput +Required.JsonInput.PrimitiveRepeatedField.JsonOutput +Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput +Required.JsonInput.RepeatedBoolWrapper.JsonOutput +Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput +Required.JsonInput.RepeatedBytesWrapper.JsonOutput +Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput +Required.JsonInput.RepeatedDoubleWrapper.JsonOutput +Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage +Required.JsonInput.RepeatedFloatWrapper.JsonOutput +Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput +Required.JsonInput.RepeatedInt32Wrapper.JsonOutput +Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput +Required.JsonInput.RepeatedInt64Wrapper.JsonOutput +Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput +Required.JsonInput.RepeatedStringWrapper.JsonOutput +Required.JsonInput.RepeatedStringWrapper.ProtobufOutput +Required.JsonInput.RepeatedUint32Wrapper.JsonOutput +Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput +Required.JsonInput.RepeatedUint64Wrapper.JsonOutput +Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput +Required.JsonInput.StringField.JsonOutput +Required.JsonInput.StringField.ProtobufOutput +Required.JsonInput.StringFieldEscape.JsonOutput +Required.JsonInput.StringFieldEscape.ProtobufOutput +Required.JsonInput.StringFieldNotAString +Required.JsonInput.StringFieldSurrogatePair.JsonOutput +Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput +Required.JsonInput.StringFieldUnicode.JsonOutput +Required.JsonInput.StringFieldUnicode.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscape.JsonOutput +Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput +Required.JsonInput.StringRepeatedField.JsonOutput +Required.JsonInput.StringRepeatedField.ProtobufOutput +Required.JsonInput.Struct.JsonOutput +Required.JsonInput.Struct.ProtobufOutput Required.JsonInput.TimestampJsonInputLowercaseT +Required.JsonInput.TimestampJsonInputLowercaseZ +Required.JsonInput.TimestampJsonInputMissingT +Required.JsonInput.TimestampJsonInputMissingZ +Required.JsonInput.TimestampJsonInputTooLarge +Required.JsonInput.TimestampJsonInputTooSmall +Required.JsonInput.TimestampMaxValue.JsonOutput +Required.JsonInput.TimestampMaxValue.ProtobufOutput +Required.JsonInput.TimestampMinValue.JsonOutput +Required.JsonInput.TimestampMinValue.ProtobufOutput +Required.JsonInput.TimestampRepeatedValue.JsonOutput +Required.JsonInput.TimestampRepeatedValue.ProtobufOutput +Required.JsonInput.TimestampWithNegativeOffset.JsonOutput +Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput +Required.JsonInput.TimestampWithPositiveOffset.JsonOutput +Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput +Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput +Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput +Required.JsonInput.Uint32FieldMaxValue.JsonOutput +Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput +Required.JsonInput.Uint32FieldNotInteger +Required.JsonInput.Uint32FieldNotNumber +Required.JsonInput.Uint32FieldTooLarge +Required.JsonInput.Uint32MapField.JsonOutput +Required.JsonInput.Uint32MapField.ProtobufOutput +Required.JsonInput.Uint64FieldMaxValue.JsonOutput +Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput +Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput +Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput +Required.JsonInput.Uint64FieldNotInteger +Required.JsonInput.Uint64FieldNotNumber +Required.JsonInput.Uint64FieldTooLarge +Required.JsonInput.Uint64MapField.JsonOutput +Required.JsonInput.Uint64MapField.ProtobufOutput +Required.JsonInput.ValueAcceptBool.JsonOutput +Required.JsonInput.ValueAcceptBool.ProtobufOutput +Required.JsonInput.ValueAcceptFloat.JsonOutput +Required.JsonInput.ValueAcceptFloat.ProtobufOutput +Required.JsonInput.ValueAcceptInteger.JsonOutput +Required.JsonInput.ValueAcceptInteger.ProtobufOutput +Required.JsonInput.ValueAcceptList.JsonOutput +Required.JsonInput.ValueAcceptList.ProtobufOutput +Required.JsonInput.ValueAcceptNull.JsonOutput +Required.JsonInput.ValueAcceptNull.ProtobufOutput +Required.JsonInput.ValueAcceptObject.JsonOutput +Required.JsonInput.ValueAcceptObject.ProtobufOutput +Required.JsonInput.ValueAcceptString.JsonOutput +Required.JsonInput.ValueAcceptString.ProtobufOutput +Required.JsonInput.WrapperTypesWithNullValue.JsonOutput +Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput +Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput +Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput +Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput +Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput +Required.ProtobufInput.IllegalZeroFieldNum_Case_0 +Required.ProtobufInput.IllegalZeroFieldNum_Case_1 +Required.ProtobufInput.IllegalZeroFieldNum_Case_2 +Required.ProtobufInput.IllegalZeroFieldNum_Case_3 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL +Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES +Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE +Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT +Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING +Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32 +Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64 +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING Required.ProtobufInput.PrematureEofInPackedField.BOOL Required.ProtobufInput.PrematureEofInPackedField.DOUBLE Required.ProtobufInput.PrematureEofInPackedField.ENUM @@ -36,3 +476,149 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32 Required.ProtobufInput.PrematureEofInPackedField.SINT64 Required.ProtobufInput.PrematureEofInPackedField.UINT32 Required.ProtobufInput.PrematureEofInPackedField.UINT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL +Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE +Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM +Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT +Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64 +Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32 +Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64 +Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32 +Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL +Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES +Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE +Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM +Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT +Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE +Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64 +Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING +Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32 +Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64 +Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput +Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput +Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput +Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput +Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput +Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput +Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput +Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput +Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput +Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput +Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput +Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput +Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput +Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput +Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput +Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput +Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput +Required.TimestampProtoInputTooLarge.JsonOutput +Required.TimestampProtoInputTooSmall.JsonOutput diff --git a/generate_descriptor_proto.sh b/generate_descriptor_proto.sh index 809214ce..229bec43 100755 --- a/generate_descriptor_proto.sh +++ b/generate_descriptor_proto.sh @@ -41,6 +41,11 @@ declare -a RUNTIME_PROTO_FILES=(\ google/protobuf/type.proto \ google/protobuf/wrappers.proto) +declare -a COMPILER_PROTO_FILES=(\ + google/protobuf/compiler/plugin.proto \ + google/protobuf/compiler/profile.proto \ +) + CORE_PROTO_IS_CORRECT=0 PROCESS_ROUND=1 TMP=$(mktemp -d) @@ -57,9 +62,9 @@ do fi ./protoc --cpp_out=dllexport_decl=LIBPROTOBUF_EXPORT:$TMP ${RUNTIME_PROTO_FILES[@]} && \ - ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP google/protobuf/compiler/plugin.proto + ./protoc --cpp_out=dllexport_decl=LIBPROTOC_EXPORT:$TMP ${COMPILER_PROTO_FILES[@]} - for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do + for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do BASE_NAME=${PROTO_FILE%.*} diff ${BASE_NAME}.pb.h $TMP/${BASE_NAME}.pb.h > /dev/null if test $? -ne 0; then @@ -71,24 +76,14 @@ do fi done - diff google/protobuf/compiler/plugin.pb.h $TMP/google/protobuf/compiler/plugin.pb.h > /dev/null - if test $? -ne 0; then - CORE_PROTO_IS_CORRECT=0 - fi - diff google/protobuf/compiler/plugin.pb.cc $TMP/google/protobuf/compiler/plugin.pb.cc > /dev/null - if test $? -ne 0; then - CORE_PROTO_IS_CORRECT=0 - fi - # Only override the output if the files are different to avoid re-compilation # of the protoc. if [ $CORE_PROTO_IS_CORRECT -ne 1 ]; then - for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]}; do + for PROTO_FILE in ${RUNTIME_PROTO_FILES[@]} ${COMPILER_PROTO_FILES[@]}; do BASE_NAME=${PROTO_FILE%.*} mv $TMP/${BASE_NAME}.pb.h ${BASE_NAME}.pb.h mv $TMP/${BASE_NAME}.pb.cc ${BASE_NAME}.pb.cc done - mv $TMP/google/protobuf/compiler/plugin.pb.* google/protobuf/compiler/ fi PROCESS_ROUND=$((PROCESS_ROUND + 1)) diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java index 37180da8..b5043eb5 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java @@ -34,7 +34,6 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; import com.google.protobuf.Internal.EnumLite; - import java.io.IOException; import java.io.InputStream; import java.util.Arrays; @@ -328,7 +327,8 @@ public abstract class AbstractMessage extends AbstractMessageLite.Builder implements Message.Builder { // The compiler produces an error if this is not declared explicitly. - // Method isn't abstract to bypass Java 1.6 compiler issue http://bugs.java.com/view_bug.do?bug_id=6908259 + // Method isn't abstract to bypass Java 1.6 compiler issue: + // http://bugs.java.com/view_bug.do?bug_id=6908259 @Override public BuilderType clone() { throw new UnsupportedOperationException("clone() should be implemented in subclasses."); diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java index 4f691dfd..99787fcc 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractMessageLite.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; @@ -351,22 +353,23 @@ public abstract class AbstractMessageLite< */ protected static void addAll(final Iterable values, final Collection list) { - if (values == null) { - throw new NullPointerException(); - } + checkNotNull(values); if (values instanceof LazyStringList) { // For StringOrByteStringLists, check the underlying elements to avoid // forcing conversions of ByteStrings to Strings. + // TODO(dweis): Could we just prohibit nulls in all protobuf lists and get rid of this? Is + // if even possible to hit this condition as all protobuf methods check for null first, + // right? checkForNullValues(((LazyStringList) values).getUnderlyingElements()); list.addAll((Collection) values); } else if (values instanceof Collection) { - checkForNullValues(values); + if (!(values instanceof PrimitiveNonBoxingCollection)) { + checkForNullValues(values); + } list.addAll((Collection) values); } else { for (final T value : values) { - if (value == null) { - throw new NullPointerException(); - } + checkNotNull(value); list.add(value); } } @@ -374,9 +377,7 @@ public abstract class AbstractMessageLite< private static void checkForNullValues(final Iterable values) { for (final Object value : values) { - if (value == null) { - throw new NullPointerException(); - } + checkNotNull(value); } } } diff --git a/java/core/src/main/java/com/google/protobuf/AbstractParser.java b/java/core/src/main/java/com/google/protobuf/AbstractParser.java index 7ff73ba4..ba570e3d 100644 --- a/java/core/src/main/java/com/google/protobuf/AbstractParser.java +++ b/java/core/src/main/java/com/google/protobuf/AbstractParser.java @@ -31,9 +31,9 @@ package com.google.protobuf; import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; - import java.io.IOException; import java.io.InputStream; +import java.nio.ByteBuffer; /** * A partial implementation of the {@link Parser} interface which implements @@ -130,6 +130,30 @@ public abstract class AbstractParser return parseFrom(data, EMPTY_REGISTRY); } + @Override + public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + MessageType message; + try { + CodedInputStream input = CodedInputStream.newInstance(data); + message = parsePartialFrom(input, extensionRegistry); + try { + input.checkLastTagWas(0); + } catch (InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(message); + } + } catch (InvalidProtocolBufferException e) { + throw e; + } + + return checkMessageInitialized(message); + } + + @Override + public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException { + return parseFrom(data, EMPTY_REGISTRY); + } + @Override public MessageType parsePartialFrom( byte[] data, int off, int len, ExtensionRegistryLite extensionRegistry) diff --git a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java index 0d9f87ba..fd4c142b 100644 --- a/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/BooleanArrayList.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.Internal.BooleanList; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.Internal.BooleanList; import java.util.Arrays; import java.util.Collection; import java.util.RandomAccess; @@ -41,9 +42,8 @@ import java.util.RandomAccess; * * @author dweis@google.com (Daniel Weis) */ -final class BooleanArrayList - extends AbstractProtobufList - implements BooleanList, RandomAccess { +final class BooleanArrayList extends AbstractProtobufList + implements BooleanList, RandomAccess, PrimitiveNonBoxingCollection { private static final BooleanArrayList EMPTY_LIST = new BooleanArrayList(); static { @@ -198,9 +198,7 @@ final class BooleanArrayList public boolean addAll(Collection collection) { ensureIsMutable(); - if (collection == null) { - throw new NullPointerException(); - } + checkNotNull(collection); // We specialize when adding another BooleanArrayList to avoid boxing elements. if (!(collection instanceof BooleanArrayList)) { diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java index 239798e4..3dfbcb0a 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java @@ -355,8 +355,8 @@ public abstract class CodedInputStream { *

Set the maximum message size. In order to prevent malicious messages from exhausting memory * or causing integer overflows, {@code CodedInputStream} limits how large a message may be. The * default limit is {@code Integer.MAX_INT}. You should set this limit as small as you can without - * harming your app's functionality. Note that size limits only apply when reading from an - * {@code InputStream}, not when constructed around a raw byte array. + * harming your app's functionality. Note that size limits only apply when reading from an {@code + * InputStream}, not when constructed around a raw byte array. * *

If you want to read several messages from a single CodedInputStream, you could call {@link * #resetSizeCounter()} after each one to avoid hitting the size limit. diff --git a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java index 3e32c2c5..da0e9b12 100644 --- a/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java +++ b/java/core/src/main/java/com/google/protobuf/CodedOutputStream.java @@ -184,7 +184,7 @@ public abstract class CodedOutputStream extends ByteOutput { * maps are sorted on the lexicographical order of the UTF8 encoded keys. * */ - void useDeterministicSerialization() { + public void useDeterministicSerialization() { serializationDeterministic = true; } @@ -1854,7 +1854,7 @@ public abstract class CodedOutputStream extends ByteOutput { } static boolean isSupported() { - return UnsafeUtil.hasUnsafeByteBufferOperations(); + return UnsafeUtil.hasUnsafeByteBufferOperations() && UnsafeUtil.hasUnsafeCopyMemory(); } @Override diff --git a/java/core/src/main/java/com/google/protobuf/Descriptors.java b/java/core/src/main/java/com/google/protobuf/Descriptors.java index 38346f15..75b16fe3 100644 --- a/java/core/src/main/java/com/google/protobuf/Descriptors.java +++ b/java/core/src/main/java/com/google/protobuf/Descriptors.java @@ -30,9 +30,10 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import com.google.protobuf.DescriptorProtos.*; import com.google.protobuf.Descriptors.FileDescriptor.Syntax; - import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; @@ -682,9 +683,7 @@ public final class Descriptors { /** Determines if the given field name is reserved. */ public boolean isReservedName(final String name) { - if (name == null) { - throw new NullPointerException(); - } + checkNotNull(name); for (final String reservedName : proto.getReservedNameList()) { if (reservedName.equals(name)) { return true; diff --git a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java index 6177f3ca..867b85ce 100644 --- a/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/DoubleArrayList.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.Internal.DoubleList; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.Internal.DoubleList; import java.util.Arrays; import java.util.Collection; import java.util.RandomAccess; @@ -41,9 +42,8 @@ import java.util.RandomAccess; * * @author dweis@google.com (Daniel Weis) */ -final class DoubleArrayList - extends AbstractProtobufList - implements DoubleList, RandomAccess { +final class DoubleArrayList extends AbstractProtobufList + implements DoubleList, RandomAccess, PrimitiveNonBoxingCollection { private static final DoubleArrayList EMPTY_LIST = new DoubleArrayList(); static { @@ -199,9 +199,7 @@ final class DoubleArrayList public boolean addAll(Collection collection) { ensureIsMutable(); - if (collection == null) { - throw new NullPointerException(); - } + checkNotNull(collection); // We specialize when adding another DoubleArrayList to avoid boxing elements. if (!(collection instanceof DoubleArrayList)) { diff --git a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java index e6358c3b..2631db74 100644 --- a/java/core/src/main/java/com/google/protobuf/DynamicMessage.java +++ b/java/core/src/main/java/com/google/protobuf/DynamicMessage.java @@ -30,11 +30,12 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.Descriptors.OneofDescriptor; - import java.io.IOException; import java.io.InputStream; import java.util.Collections; @@ -631,9 +632,7 @@ public final class DynamicMessage extends AbstractMessage { /** Verifies that the value is EnumValueDescriptor and matches Enum Type. */ private void ensureSingularEnumValueDescriptor( FieldDescriptor field, Object value) { - if (value == null) { - throw new NullPointerException(); - } + checkNotNull(value); if (!(value instanceof EnumValueDescriptor)) { throw new IllegalArgumentException( "DynamicMessage should use EnumValueDescriptor to set Enum Value."); diff --git a/java/core/src/main/java/com/google/protobuf/FieldSet.java b/java/core/src/main/java/com/google/protobuf/FieldSet.java index a828f30e..8a9239ed 100644 --- a/java/core/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/FieldSet.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.LazyField.LazyIterator; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.LazyField.LazyIterator; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -385,9 +386,7 @@ final class FieldSet - implements FloatList, RandomAccess { +final class FloatArrayList extends AbstractProtobufList + implements FloatList, RandomAccess, PrimitiveNonBoxingCollection { private static final FloatArrayList EMPTY_LIST = new FloatArrayList(); static { @@ -198,9 +198,7 @@ final class FloatArrayList public boolean addAll(Collection collection) { ensureIsMutable(); - if (collection == null) { - throw new NullPointerException(); - } + checkNotNull(collection); // We specialize when adding another FloatArrayList to avoid boxing elements. if (!(collection instanceof FloatArrayList)) { diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java index 2d7fd334..cf3486e1 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java @@ -34,6 +34,7 @@ import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream; import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException; import com.google.protobuf.Internal.BooleanList; import com.google.protobuf.Internal.DoubleList; +import com.google.protobuf.Internal.EnumLiteMap; import com.google.protobuf.Internal.FloatList; import com.google.protobuf.Internal.IntList; import com.google.protobuf.Internal.LongList; @@ -45,6 +46,7 @@ import java.io.ObjectStreamException; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -136,6 +138,7 @@ public abstract class GeneratedMessageLite< return false; } + try { visit(EqualsVisitor.INSTANCE, (MessageType) other); } catch (NotEqualsException e) { @@ -1154,6 +1157,7 @@ public abstract class GeneratedMessageLite< } } + /** * Lite equivalent to {@link GeneratedMessage.GeneratedExtension}. * @@ -1527,6 +1531,20 @@ public abstract class GeneratedMessageLite< return message; } + // Validates last tag. + protected static > T parseFrom( + T defaultInstance, ByteBuffer data, ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException { + return checkMessageInitialized( + parseFrom(defaultInstance, CodedInputStream.newInstance(data), extensionRegistry)); + } + + // Validates last tag. + protected static > T parseFrom( + T defaultInstance, ByteBuffer data) throws InvalidProtocolBufferException { + return parseFrom(defaultInstance, data, ExtensionRegistryLite.getEmptyRegistry()); + } + // Validates last tag. protected static > T parseFrom( T defaultInstance, ByteString data) @@ -1979,13 +1997,13 @@ public abstract class GeneratedMessageLite< /** * Implements hashCode by accumulating state. */ - private static class HashCodeVisitor implements Visitor { + static class HashCodeVisitor implements Visitor { // The caller must ensure that the visitor is invoked parameterized with this and this such that // other is this. This is required due to how oneof cases are handled. See the class comment // on Visitor for more information. - private int hashCode = 0; + int hashCode = 0; @Override public boolean visitBoolean( diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java index fd051e75..b949cd17 100644 --- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java +++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java @@ -41,7 +41,7 @@ import com.google.protobuf.Descriptors.OneofDescriptor; // class without breaking binary compatibility with old generated code that still subclasses // the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to // interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class -// type is GeneratedMessageV3V4), these classes still share a common parent class AbstarctMessage +// type is GeneratedMessageV3V4), these classes still share a common parent class AbstractMessage // and are using the same GeneratedMessage.GeneratedExtension class for extension definitions. // Since this class becomes GeneratedMessageV3V? in opensource, we have to add an import here // to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in diff --git a/java/core/src/main/java/com/google/protobuf/IntArrayList.java b/java/core/src/main/java/com/google/protobuf/IntArrayList.java index 2f526e3f..aff5c21b 100644 --- a/java/core/src/main/java/com/google/protobuf/IntArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/IntArrayList.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.Internal.IntList; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.Internal.IntList; import java.util.Arrays; import java.util.Collection; import java.util.RandomAccess; @@ -41,9 +42,8 @@ import java.util.RandomAccess; * * @author dweis@google.com (Daniel Weis) */ -final class IntArrayList - extends AbstractProtobufList - implements IntList, RandomAccess { +final class IntArrayList extends AbstractProtobufList + implements IntList, RandomAccess, PrimitiveNonBoxingCollection { private static final IntArrayList EMPTY_LIST = new IntArrayList(); static { @@ -198,9 +198,7 @@ final class IntArrayList public boolean addAll(Collection collection) { ensureIsMutable(); - if (collection == null) { - throw new NullPointerException(); - } + checkNotNull(collection); // We specialize when adding another IntArrayList to avoid boxing elements. if (!(collection instanceof IntArrayList)) { diff --git a/java/core/src/main/java/com/google/protobuf/Internal.java b/java/core/src/main/java/com/google/protobuf/Internal.java index c234559c..36bdece3 100644 --- a/java/core/src/main/java/com/google/protobuf/Internal.java +++ b/java/core/src/main/java/com/google/protobuf/Internal.java @@ -59,6 +59,16 @@ public final class Internal { static final Charset UTF_8 = Charset.forName("UTF-8"); static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); + /** + * Throws an appropriate {@link NullPointerException} if the given objects is {@code null}. + */ + static T checkNotNull(T obj) { + if (obj == null) { + throw new NullPointerException(); + } + return obj; + } + /** * Throws an appropriate {@link NullPointerException} if the given objects is {@code null}. */ @@ -420,6 +430,11 @@ public final class Internal { CodedInputStream.newInstance(EMPTY_BYTE_ARRAY); + /** Helper method to merge two MessageLite instances. */ + static Object mergeMessage(Object destination, Object source) { + return ((MessageLite) destination).toBuilder().mergeFrom((MessageLite) source).buildPartial(); + } + /** * Provides an immutable view of {@code List} around a {@code List}. * diff --git a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java index 4b0ba0fd..49ecfc0b 100644 --- a/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java +++ b/java/core/src/main/java/com/google/protobuf/LazyFieldLite.java @@ -394,6 +394,7 @@ public class LazyFieldLite { } } + /** * Might lazily parse the bytes that were previously passed in. Is thread-safe. */ diff --git a/java/core/src/main/java/com/google/protobuf/LongArrayList.java b/java/core/src/main/java/com/google/protobuf/LongArrayList.java index 5a772e3a..fc146e23 100644 --- a/java/core/src/main/java/com/google/protobuf/LongArrayList.java +++ b/java/core/src/main/java/com/google/protobuf/LongArrayList.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.Internal.LongList; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.Internal.LongList; import java.util.Arrays; import java.util.Collection; import java.util.RandomAccess; @@ -41,9 +42,8 @@ import java.util.RandomAccess; * * @author dweis@google.com (Daniel Weis) */ -final class LongArrayList - extends AbstractProtobufList - implements LongList, RandomAccess { +final class LongArrayList extends AbstractProtobufList + implements LongList, RandomAccess, PrimitiveNonBoxingCollection { private static final LongArrayList EMPTY_LIST = new LongArrayList(); static { @@ -198,9 +198,7 @@ final class LongArrayList public boolean addAll(Collection collection) { ensureIsMutable(); - if (collection == null) { - throw new NullPointerException(); - } + checkNotNull(collection); // We specialize when adding another LongArrayList to avoid boxing elements. if (!(collection instanceof LongArrayList)) { diff --git a/java/core/src/main/java/com/google/protobuf/MapEntry.java b/java/core/src/main/java/com/google/protobuf/MapEntry.java index 7e8e9aad..0849b821 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntry.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntry.java @@ -33,7 +33,6 @@ package com.google.protobuf; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; import com.google.protobuf.Descriptors.FieldDescriptor; - import java.io.IOException; import java.util.Collections; import java.util.Map; @@ -171,7 +170,7 @@ public final class MapEntry extends AbstractMessage { @Override public Builder toBuilder() { - return new Builder(metadata, key, value); + return new Builder(metadata, key, value, true, true); } @Override @@ -247,15 +246,19 @@ public final class MapEntry extends AbstractMessage { private final Metadata metadata; private K key; private V value; + private boolean hasKey; + private boolean hasValue; private Builder(Metadata metadata) { - this(metadata, metadata.defaultKey, metadata.defaultValue); + this(metadata, metadata.defaultKey, metadata.defaultValue, false, false); } - private Builder(Metadata metadata, K key, V value) { + private Builder(Metadata metadata, K key, V value, boolean hasKey, boolean hasValue) { this.metadata = metadata; this.key = key; this.value = value; + this.hasKey = hasKey; + this.hasValue = hasValue; } public K getKey() { @@ -268,21 +271,25 @@ public final class MapEntry extends AbstractMessage { public Builder setKey(K key) { this.key = key; + this.hasKey = true; return this; } public Builder clearKey() { this.key = metadata.defaultKey; + this.hasKey = false; return this; } public Builder setValue(V value) { this.value = value; + this.hasValue = true; return this; } public Builder clearValue() { this.value = metadata.defaultValue; + this.hasValue = false; return this; } @@ -404,7 +411,7 @@ public final class MapEntry extends AbstractMessage { @Override public boolean hasField(FieldDescriptor field) { checkFieldDescriptor(field); - return true; + return field.getNumber() == 1 ? hasKey : hasValue; } @Override @@ -438,7 +445,7 @@ public final class MapEntry extends AbstractMessage { @Override @SuppressWarnings("unchecked") public Builder clone() { - return new Builder(metadata, key, value); + return new Builder(metadata, key, value, hasKey, hasValue); } } @@ -448,4 +455,9 @@ public final class MapEntry extends AbstractMessage { } return true; } + + /** Returns the metadata only for experimental runtime. */ + final Metadata getMetadata() { + return metadata; + } } diff --git a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java index 22aef8f9..dcb5dfad 100644 --- a/java/core/src/main/java/com/google/protobuf/MapEntryLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapEntryLite.java @@ -223,4 +223,9 @@ public class MapEntryLite { input.popLimit(oldLimit); map.put(key, value); } + + /** For experimental runtime internal use only. */ + Metadata getMetadata() { + return metadata; + } } diff --git a/java/core/src/main/java/com/google/protobuf/MapField.java b/java/core/src/main/java/com/google/protobuf/MapField.java index 805defe2..ad8ceb02 100644 --- a/java/core/src/main/java/com/google/protobuf/MapField.java +++ b/java/core/src/main/java/com/google/protobuf/MapField.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -329,6 +331,8 @@ public class MapField implements MutabilityOracle { @Override public V put(K key, V value) { mutabilityOracle.ensureMutable(); + checkNotNull(key); + checkNotNull(value); return delegate.put(key, value); } @@ -341,6 +345,10 @@ public class MapField implements MutabilityOracle { @Override public void putAll(Map m) { mutabilityOracle.ensureMutable(); + for (K key : m.keySet()) { + checkNotNull(key); + checkNotNull(m.get(key)); + } delegate.putAll(m); } diff --git a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java index 42640279..a8b3dd88 100644 --- a/java/core/src/main/java/com/google/protobuf/MapFieldLite.java +++ b/java/core/src/main/java/com/google/protobuf/MapFieldLite.java @@ -30,8 +30,9 @@ package com.google.protobuf; -import com.google.protobuf.Internal.EnumLite; +import static com.google.protobuf.Internal.checkNotNull; +import com.google.protobuf.Internal.EnumLite; import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; @@ -88,6 +89,9 @@ public final class MapFieldLite extends LinkedHashMap { @Override public V put(K key, V value) { ensureMutable(); + checkNotNull(key); + + checkNotNull(value); return super.put(key, value); } @@ -97,6 +101,7 @@ public final class MapFieldLite extends LinkedHashMap { @Override public void putAll(Map m) { ensureMutable(); + checkForNullKeysAndValues(m); super.putAll(m); } @@ -105,6 +110,13 @@ public final class MapFieldLite extends LinkedHashMap { return super.remove(key); } + private static void checkForNullKeysAndValues(Map m) { + for (Object key : m.keySet()) { + checkNotNull(key); + checkNotNull(m.get(key)); + } + } + private static boolean equals(Object a, Object b) { if (a instanceof byte[] && b instanceof byte[]) { return Arrays.equals((byte[]) a, (byte[]) b); diff --git a/java/core/src/main/java/com/google/protobuf/Parser.java b/java/core/src/main/java/com/google/protobuf/Parser.java index cfbcb442..e07c6895 100644 --- a/java/core/src/main/java/com/google/protobuf/Parser.java +++ b/java/core/src/main/java/com/google/protobuf/Parser.java @@ -31,6 +31,7 @@ package com.google.protobuf; import java.io.InputStream; +import java.nio.ByteBuffer; /** * Abstract interface for parsing Protocol Messages. @@ -92,6 +93,18 @@ public interface Parser { // --------------------------------------------------------------- // Convenience methods. + /** + * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around + * {@link #parseFrom(CodedInputStream)}. + */ + public MessageType parseFrom(ByteBuffer data) throws InvalidProtocolBufferException; + + /** + * Parses {@code data} as a message of {@code MessageType}. This is just a small wrapper around + * {@link #parseFrom(CodedInputStream, ExtensionRegistryLite)}. + */ + public MessageType parseFrom(ByteBuffer data, ExtensionRegistryLite extensionRegistry) + throws InvalidProtocolBufferException; /** * Parses {@code data} as a message of {@code MessageType}. * This is just a small wrapper around {@link #parseFrom(CodedInputStream)}. diff --git a/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java b/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java new file mode 100644 index 00000000..79b5769d --- /dev/null +++ b/java/core/src/main/java/com/google/protobuf/PrimitiveNonBoxingCollection.java @@ -0,0 +1,34 @@ +// 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. + +package com.google.protobuf; + +/** A marker interface indicating that the collection supports primitives and is non-boxing. */ +interface PrimitiveNonBoxingCollection {} diff --git a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java index 77b61b5f..30c991d4 100644 --- a/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java +++ b/java/core/src/main/java/com/google/protobuf/RepeatedFieldBuilderV3.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + import java.util.AbstractList; import java.util.ArrayList; import java.util.Collection; @@ -290,9 +292,7 @@ public class RepeatedFieldBuilderV3 */ public RepeatedFieldBuilderV3 setMessage( int index, MType message) { - if (message == null) { - throw new NullPointerException(); - } + checkNotNull(message); ensureMutableMessageList(); messages.set(index, message); if (builders != null) { @@ -315,9 +315,7 @@ public class RepeatedFieldBuilderV3 */ public RepeatedFieldBuilderV3 addMessage( MType message) { - if (message == null) { - throw new NullPointerException(); - } + checkNotNull(message); ensureMutableMessageList(); messages.add(message); if (builders != null) { @@ -339,9 +337,7 @@ public class RepeatedFieldBuilderV3 */ public RepeatedFieldBuilderV3 addMessage( int index, MType message) { - if (message == null) { - throw new NullPointerException(); - } + checkNotNull(message); ensureMutableMessageList(); messages.add(index, message); if (builders != null) { @@ -363,9 +359,7 @@ public class RepeatedFieldBuilderV3 public RepeatedFieldBuilderV3 addAllMessages( Iterable values) { for (final MType value : values) { - if (value == null) { - throw new NullPointerException(); - } + checkNotNull(value); } // If we can inspect the size, we can more efficiently add messages. diff --git a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java index fb1f76a7..8ab0f26d 100644 --- a/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java +++ b/java/core/src/main/java/com/google/protobuf/SingleFieldBuilderV3.java @@ -30,6 +30,8 @@ package com.google.protobuf; +import static com.google.protobuf.Internal.checkNotNull; + /** * {@code SingleFieldBuilderV3} implements a structure that a protocol * message uses to hold a single field of another protocol message. It supports @@ -84,10 +86,7 @@ public class SingleFieldBuilderV3 MType message, AbstractMessage.BuilderParent parent, boolean isClean) { - if (message == null) { - throw new NullPointerException(); - } - this.message = message; + this.message = checkNotNull(message); this.parent = parent; this.isClean = isClean; } @@ -169,10 +168,7 @@ public class SingleFieldBuilderV3 */ public SingleFieldBuilderV3 setMessage( MType message) { - if (message == null) { - throw new NullPointerException(); - } - this.message = message; + this.message = checkNotNull(message); if (builder != null) { builder.dispose(); builder = null; diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index 49708242..53dead80 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -1442,7 +1442,7 @@ public final class TextFormat { /** * Parse a single field from {@code tokenizer} and merge it into - * {@code builder}. + * {@code target}. */ private void mergeField(final Tokenizer tokenizer, final ExtensionRegistry extensionRegistry, @@ -1712,6 +1712,8 @@ public final class TextFormat { } if (field.isRepeated()) { + // TODO(b/29122459): If field.isMapField() and FORBID_SINGULAR_OVERWRITES mode, + // check for duplicate map keys here. target.addRepeatedField(field, value); } else if ((singularOverwritePolicy == SingularOverwritePolicy.FORBID_SINGULAR_OVERWRITES) diff --git a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java index 2bef27e9..d9381135 100644 --- a/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java +++ b/java/core/src/main/java/com/google/protobuf/UnknownFieldSet.java @@ -91,7 +91,7 @@ public final class UnknownFieldSet implements MessageLite { * Construct an {@code UnknownFieldSet} around the given map. The map is * expected to be immutable. */ - private UnknownFieldSet(final Map fields, + UnknownFieldSet(final Map fields, final Map fieldsDescending) { this.fields = fields; } @@ -715,7 +715,7 @@ public final class UnknownFieldSet implements MessageLite { * @see UnknownFieldSet */ public static final class Field { - private Field() {} + Field() {} /** Construct a new {@link Builder}. */ public static Builder newBuilder() { diff --git a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java index 5f7bafd6..ca80d946 100644 --- a/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java +++ b/java/core/src/main/java/com/google/protobuf/UnsafeUtil.java @@ -33,19 +33,23 @@ package com.google.protobuf; import java.lang.reflect.Field; import java.nio.Buffer; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.security.AccessController; import java.security.PrivilegedExceptionAction; -import sun.misc.Unsafe; +import java.util.logging.Level; +import java.util.logging.Logger; /** Utility class for working with unsafe operations. */ -// TODO(nathanmittler): Add support for Android Memory/MemoryBlock final class UnsafeUtil { + private static final Logger logger = Logger.getLogger(UnsafeUtil.class.getName()); private static final sun.misc.Unsafe UNSAFE = getUnsafe(); + private static final MemoryAccessor MEMORY_ACCESSOR = getMemoryAccessor(); private static final boolean HAS_UNSAFE_BYTEBUFFER_OPERATIONS = supportsUnsafeByteBufferOperations(); private static final boolean HAS_UNSAFE_ARRAY_OPERATIONS = supportsUnsafeArrayOperations(); + private static final boolean HAS_UNSAFE_COPY_MEMORY = supportsUnsafeCopyMemory(); private static final long ARRAY_BASE_OFFSET = byteArrayBaseOffset(); - private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(field(Buffer.class, "address")); + private static final long BUFFER_ADDRESS_OFFSET = fieldOffset(bufferAddressField()); private UnsafeUtil() {} @@ -53,20 +57,16 @@ final class UnsafeUtil { return HAS_UNSAFE_ARRAY_OPERATIONS; } - static boolean hasUnsafeByteBufferOperations() { - return HAS_UNSAFE_BYTEBUFFER_OPERATIONS; + static boolean hasUnsafeCopyMemory() { + return HAS_UNSAFE_COPY_MEMORY; } - static Object allocateInstance(Class clazz) { - try { - return UNSAFE.allocateInstance(clazz); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } + static boolean hasUnsafeByteBufferOperations() { + return HAS_UNSAFE_BYTEBUFFER_OPERATIONS; } static long objectFieldOffset(Field field) { - return UNSAFE.objectFieldOffset(field); + return MEMORY_ACCESSOR.objectFieldOffset(field); } static long getArrayBaseOffset() { @@ -74,103 +74,103 @@ final class UnsafeUtil { } static byte getByte(Object target, long offset) { - return UNSAFE.getByte(target, offset); + return MEMORY_ACCESSOR.getByte(target, offset); } static void putByte(Object target, long offset, byte value) { - UNSAFE.putByte(target, offset, value); + MEMORY_ACCESSOR.putByte(target, offset, value); } static int getInt(Object target, long offset) { - return UNSAFE.getInt(target, offset); + return MEMORY_ACCESSOR.getInt(target, offset); } static void putInt(Object target, long offset, int value) { - UNSAFE.putInt(target, offset, value); + MEMORY_ACCESSOR.putInt(target, offset, value); } static long getLong(Object target, long offset) { - return UNSAFE.getLong(target, offset); + return MEMORY_ACCESSOR.getLong(target, offset); } static void putLong(Object target, long offset, long value) { - UNSAFE.putLong(target, offset, value); + MEMORY_ACCESSOR.putLong(target, offset, value); } static boolean getBoolean(Object target, long offset) { - return UNSAFE.getBoolean(target, offset); + return MEMORY_ACCESSOR.getBoolean(target, offset); } static void putBoolean(Object target, long offset, boolean value) { - UNSAFE.putBoolean(target, offset, value); + MEMORY_ACCESSOR.putBoolean(target, offset, value); } static float getFloat(Object target, long offset) { - return UNSAFE.getFloat(target, offset); + return MEMORY_ACCESSOR.getFloat(target, offset); } static void putFloat(Object target, long offset, float value) { - UNSAFE.putFloat(target, offset, value); + MEMORY_ACCESSOR.putFloat(target, offset, value); } static double getDouble(Object target, long offset) { - return UNSAFE.getDouble(target, offset); + return MEMORY_ACCESSOR.getDouble(target, offset); } static void putDouble(Object target, long offset, double value) { - UNSAFE.putDouble(target, offset, value); + MEMORY_ACCESSOR.putDouble(target, offset, value); } static Object getObject(Object target, long offset) { - return UNSAFE.getObject(target, offset); + return MEMORY_ACCESSOR.getObject(target, offset); } static void putObject(Object target, long offset, Object value) { - UNSAFE.putObject(target, offset, value); + MEMORY_ACCESSOR.putObject(target, offset, value); } static void copyMemory( Object src, long srcOffset, Object target, long targetOffset, long length) { - UNSAFE.copyMemory(src, srcOffset, target, targetOffset, length); + MEMORY_ACCESSOR.copyMemory(src, srcOffset, target, targetOffset, length); } static byte getByte(long address) { - return UNSAFE.getByte(address); + return MEMORY_ACCESSOR.getByte(address); } static void putByte(long address, byte value) { - UNSAFE.putByte(address, value); + MEMORY_ACCESSOR.putByte(address, value); } static int getInt(long address) { - return UNSAFE.getInt(address); + return MEMORY_ACCESSOR.getInt(address); } static void putInt(long address, int value) { - UNSAFE.putInt(address, value); + MEMORY_ACCESSOR.putInt(address, value); } static long getLong(long address) { - return UNSAFE.getLong(address); + return MEMORY_ACCESSOR.getLong(address); } static void putLong(long address, long value) { - UNSAFE.putLong(address, value); + MEMORY_ACCESSOR.putLong(address, value); } static void copyMemory(long srcAddress, long targetAddress, long length) { - UNSAFE.copyMemory(srcAddress, targetAddress, length); - } - - static void setMemory(long address, long numBytes, byte value) { - UNSAFE.setMemory(address, numBytes, value); + MEMORY_ACCESSOR.copyMemory(srcAddress, targetAddress, length); } /** * Gets the offset of the {@code address} field of the given direct {@link ByteBuffer}. */ static long addressOffset(ByteBuffer buffer) { - return UNSAFE.getLong(buffer, BUFFER_ADDRESS_OFFSET); + return MEMORY_ACCESSOR.getLong(buffer, BUFFER_ADDRESS_OFFSET); + } + + static Object getStaticObject(Field field) { + return MEMORY_ACCESSOR.getStaticObject(field); } /** @@ -181,7 +181,7 @@ final class UnsafeUtil { try { unsafe = AccessController.doPrivileged( - new PrivilegedExceptionAction() { + new PrivilegedExceptionAction() { @Override public sun.misc.Unsafe run() throws Exception { Class k = sun.misc.Unsafe.class; @@ -204,69 +204,114 @@ final class UnsafeUtil { return unsafe; } + /** Get a {@link MemoryAccessor} appropriate for the platform, or null if not supported. */ + private static MemoryAccessor getMemoryAccessor() { + if (UNSAFE == null) { + return null; + } + return new JvmMemoryAccessor(UNSAFE); + } + /** Indicates whether or not unsafe array operations are supported on this platform. */ private static boolean supportsUnsafeArrayOperations() { - boolean supported = false; - if (UNSAFE != null) { - try { - Class clazz = UNSAFE.getClass(); - clazz.getMethod("objectFieldOffset", Field.class); - clazz.getMethod("allocateInstance", Class.class); - clazz.getMethod("arrayBaseOffset", Class.class); - clazz.getMethod("getByte", Object.class, long.class); - clazz.getMethod("putByte", Object.class, long.class, byte.class); - clazz.getMethod("getBoolean", Object.class, long.class); - clazz.getMethod("putBoolean", Object.class, long.class, boolean.class); - clazz.getMethod("getInt", Object.class, long.class); - clazz.getMethod("putInt", Object.class, long.class, int.class); - clazz.getMethod("getLong", Object.class, long.class); - clazz.getMethod("putLong", Object.class, long.class, long.class); - clazz.getMethod("getFloat", Object.class, long.class); - clazz.getMethod("putFloat", Object.class, long.class, float.class); - clazz.getMethod("getDouble", Object.class, long.class); - clazz.getMethod("putDouble", Object.class, long.class, double.class); - clazz.getMethod("getObject", Object.class, long.class); - clazz.getMethod("putObject", Object.class, long.class, Object.class); - clazz.getMethod( - "copyMemory", Object.class, long.class, Object.class, long.class, long.class); - supported = true; - } catch (Throwable e) { - // Do nothing. - } - } - return supported; + if (UNSAFE == null) { + return false; + } + try { + Class clazz = UNSAFE.getClass(); + clazz.getMethod("objectFieldOffset", Field.class); + clazz.getMethod("arrayBaseOffset", Class.class); + clazz.getMethod("getInt", Object.class, long.class); + clazz.getMethod("putInt", Object.class, long.class, int.class); + clazz.getMethod("getLong", Object.class, long.class); + clazz.getMethod("putLong", Object.class, long.class, long.class); + clazz.getMethod("getObject", Object.class, long.class); + clazz.getMethod("putObject", Object.class, long.class, Object.class); + clazz.getMethod("getByte", Object.class, long.class); + clazz.getMethod("putByte", Object.class, long.class, byte.class); + clazz.getMethod("getBoolean", Object.class, long.class); + clazz.getMethod("putBoolean", Object.class, long.class, boolean.class); + clazz.getMethod("getFloat", Object.class, long.class); + clazz.getMethod("putFloat", Object.class, long.class, float.class); + clazz.getMethod("getDouble", Object.class, long.class); + clazz.getMethod("putDouble", Object.class, long.class, double.class); + + return true; + } catch (Throwable e) { + logger.log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); + } + return false; + } + + /** + * Indicates whether or not unsafe copyMemory(object, long, object, long, long) operations are + * supported on this platform. + */ + private static boolean supportsUnsafeCopyMemory() { + if (UNSAFE == null) { + return false; + } + try { + Class clazz = UNSAFE.getClass(); + clazz.getMethod("copyMemory", Object.class, long.class, Object.class, long.class, long.class); + + return true; + } catch (Throwable e) { + logger.log( + Level.WARNING, + "copyMemory is missing from platform - proto runtime falling back to safer methods."); + } + return false; } private static boolean supportsUnsafeByteBufferOperations() { - boolean supported = false; - if (UNSAFE != null) { - try { - Class clazz = UNSAFE.getClass(); - // Methods for getting direct buffer address. - clazz.getMethod("objectFieldOffset", Field.class); - clazz.getMethod("getLong", Object.class, long.class); - - clazz.getMethod("getByte", long.class); - clazz.getMethod("putByte", long.class, byte.class); - clazz.getMethod("getInt", long.class); - clazz.getMethod("putInt", long.class, int.class); - clazz.getMethod("getLong", long.class); - clazz.getMethod("putLong", long.class, long.class); - clazz.getMethod("setMemory", long.class, long.class, byte.class); - clazz.getMethod("copyMemory", long.class, long.class, long.class); - supported = true; - } catch (Throwable e) { - // Do nothing. - } - } - return supported; + if (UNSAFE == null) { + return false; + } + try { + Class clazz = UNSAFE.getClass(); + // Methods for getting direct buffer address. + clazz.getMethod("objectFieldOffset", Field.class); + clazz.getMethod("getLong", Object.class, long.class); + + clazz.getMethod("getByte", long.class); + clazz.getMethod("putByte", long.class, byte.class); + clazz.getMethod("getInt", long.class); + clazz.getMethod("putInt", long.class, int.class); + clazz.getMethod("getLong", long.class); + clazz.getMethod("putLong", long.class, long.class); + clazz.getMethod("copyMemory", long.class, long.class, long.class); + return true; + } catch (Throwable e) { + logger.log( + Level.WARNING, + "platform method missing - proto runtime falling back to safer methods: " + e); + } + return false; + } + + + @SuppressWarnings("unchecked") + private static Class getClassForName(String name) { + try { + return (Class) Class.forName(name); + } catch (Throwable e) { + return null; + } + } + + /** Finds the address field within a direct {@link Buffer}. */ + private static Field bufferAddressField() { + return field(Buffer.class, "address"); } /** * Get the base offset for byte arrays, or {@code -1} if {@code sun.misc.Unsafe} is not available. */ private static int byteArrayBaseOffset() { - return HAS_UNSAFE_ARRAY_OPERATIONS ? UNSAFE.arrayBaseOffset(byte[].class) : -1; + return HAS_UNSAFE_ARRAY_OPERATIONS ? MEMORY_ACCESSOR.arrayBaseOffset(byte[].class) : -1; } /** @@ -274,7 +319,7 @@ final class UnsafeUtil { * available. */ private static long fieldOffset(Field field) { - return field == null || UNSAFE == null ? -1 : UNSAFE.objectFieldOffset(field); + return field == null || MEMORY_ACCESSOR == null ? -1 : MEMORY_ACCESSOR.objectFieldOffset(field); } /** @@ -292,4 +337,174 @@ final class UnsafeUtil { } return field; } + + private abstract static class MemoryAccessor { + + sun.misc.Unsafe unsafe; + + MemoryAccessor(sun.misc.Unsafe unsafe) { + this.unsafe = unsafe; + } + + public final long objectFieldOffset(Field field) { + return unsafe.objectFieldOffset(field); + } + + public abstract byte getByte(Object target, long offset); + + public abstract void putByte(Object target, long offset, byte value); + + public final int getInt(Object target, long offset) { + return unsafe.getInt(target, offset); + } + + public final void putInt(Object target, long offset, int value) { + unsafe.putInt(target, offset, value); + } + + public final long getLong(Object target, long offset) { + return unsafe.getLong(target, offset); + } + + public final void putLong(Object target, long offset, long value) { + unsafe.putLong(target, offset, value); + } + + public abstract boolean getBoolean(Object target, long offset); + + public abstract void putBoolean(Object target, long offset, boolean value); + + public abstract float getFloat(Object target, long offset); + + public abstract void putFloat(Object target, long offset, float value); + + public abstract double getDouble(Object target, long offset); + + public abstract void putDouble(Object target, long offset, double value); + + public final Object getObject(Object target, long offset) { + return unsafe.getObject(target, offset); + } + + public final void putObject(Object target, long offset, Object value) { + unsafe.putObject(target, offset, value); + } + + public final int arrayBaseOffset(Class clazz) { + return unsafe.arrayBaseOffset(clazz); + } + + public abstract byte getByte(long address); + + public abstract void putByte(long address, byte value); + + public abstract int getInt(long address); + + public abstract void putInt(long address, int value); + + public abstract long getLong(long address); + + public abstract void putLong(long address, long value); + + public abstract void copyMemory(long srcAddress, long targetAddress, long length); + + public abstract void copyMemory( + Object src, long srcOffset, Object target, long targetOffset, long length); + + public abstract Object getStaticObject(Field field); + } + + private static final class JvmMemoryAccessor extends MemoryAccessor { + + JvmMemoryAccessor(sun.misc.Unsafe unsafe) { + super(unsafe); + } + + @Override + public byte getByte(long address) { + return unsafe.getByte(address); + } + + @Override + public void putByte(long address, byte value) { + unsafe.putByte(address, value); + } + + @Override + public int getInt(long address) { + return unsafe.getInt(address); + } + + @Override + public void putInt(long address, int value) { + unsafe.putInt(address, value); + } + + @Override + public long getLong(long address) { + return unsafe.getLong(address); + } + + @Override + public void putLong(long address, long value) { + unsafe.putLong(address, value); + } + + @Override + public byte getByte(Object target, long offset) { + return unsafe.getByte(target, offset); + } + + @Override + public void putByte(Object target, long offset, byte value) { + unsafe.putByte(target, offset, value); + } + + @Override + public boolean getBoolean(Object target, long offset) { + return unsafe.getBoolean(target, offset); + } + + @Override + public void putBoolean(Object target, long offset, boolean value) { + unsafe.putBoolean(target, offset, value); + } + + @Override + public float getFloat(Object target, long offset) { + return unsafe.getFloat(target, offset); + } + + @Override + public void putFloat(Object target, long offset, float value) { + unsafe.putFloat(target, offset, value); + } + + @Override + public double getDouble(Object target, long offset) { + return unsafe.getDouble(target, offset); + } + + @Override + public void putDouble(Object target, long offset, double value) { + unsafe.putDouble(target, offset, value); + } + + @Override + public void copyMemory( + Object src, long srcOffset, Object target, long targetOffset, long length) { + unsafe.copyMemory(src, srcOffset, target, targetOffset, length); + } + + @Override + public void copyMemory(long srcAddress, long targetAddress, long length) { + unsafe.copyMemory(srcAddress, targetAddress, length); + } + + @Override + public Object getStaticObject(Field field) { + return getObject(unsafe.staticFieldBase(field), unsafe.staticFieldOffset(field)); + } + } + } diff --git a/java/core/src/main/java/com/google/protobuf/Utf8.java b/java/core/src/main/java/com/google/protobuf/Utf8.java index 5b80d405..be7b746e 100644 --- a/java/core/src/main/java/com/google/protobuf/Utf8.java +++ b/java/core/src/main/java/com/google/protobuf/Utf8.java @@ -1332,7 +1332,7 @@ final class Utf8 { // the index (relative to the start of the array) is also 8-byte aligned. We do this by // ANDing the index with 7 to determine the number of bytes that need to be read before // we're 8-byte aligned. - final int unaligned = (int) offset & 7; + final int unaligned = 8 - ((int) offset & 7); for (int j = unaligned; j > 0; j--) { if (UnsafeUtil.getByte(bytes, offset++) < 0) { return unaligned - j; diff --git a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java index 5f013f3c..f27e8e51 100644 --- a/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java +++ b/java/core/src/test/java/com/google/protobuf/LazyFieldTest.java @@ -32,7 +32,6 @@ package com.google.protobuf; import protobuf_unittest.UnittestProto.TestAllExtensions; import protobuf_unittest.UnittestProto.TestAllTypes; -import java.io.IOException; import junit.framework.TestCase; /** @@ -89,6 +88,7 @@ public class LazyFieldTest extends TestCase { assertFalse(message.equals(lazyField.getValue())); } + @SuppressWarnings("EqualsIncompatibleType") // LazyField.equals() is not symmetric public void testEqualsObjectEx() throws Exception { TestAllExtensions message = TestUtil.getAllExtensionsSet(); LazyField lazyField = createLazyFieldFromMessage(message); diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java index 538432f7..98c637a9 100644 --- a/java/core/src/test/java/com/google/protobuf/LiteTest.java +++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java @@ -52,6 +52,7 @@ import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.BarPrime; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.Foo; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestOneofEquals; import protobuf_unittest.lite_equals_and_hash.LiteEqualsAndHash.TestRecursiveOneof; +import java.nio.ByteBuffer; import junit.framework.TestCase; /** @@ -2174,6 +2175,24 @@ public class LiteTest extends TestCase { assertFalse(bar.equals(barPrime)); } + public void testEqualsAndHashCodeForTrickySchemaTypes() { + Foo foo1 = Foo.newBuilder() + .build(); + Foo foo2 = Foo.newBuilder() + .setSint64(1) + .build(); + Foo foo3 = Foo.newBuilder() + .putMyMap("key", "value2") + .build(); + Foo foo4 = Foo.newBuilder() + .setMyGroup(Foo.MyGroup.newBuilder().setValue(4).build()) + .build(); + + assertEqualsAndHashCodeAreFalse(foo1, foo2); + assertEqualsAndHashCodeAreFalse(foo1, foo3); + assertEqualsAndHashCodeAreFalse(foo1, foo4); + } + public void testOneofEquals() throws Exception { TestOneofEquals.Builder builder = TestOneofEquals.newBuilder(); TestOneofEquals message1 = builder.build(); @@ -2270,4 +2289,93 @@ public class LiteTest extends TestCase { // This tests that we don't infinite loop. TestRecursiveOneof.getDefaultInstance().hashCode(); } + + public void testParseFromByteBuffer() throws Exception { + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .setOptionalNestedMessage(TestAllTypesLite.NestedMessage.newBuilder().setBb(7)) + .build(); + + TestAllTypesLite copy = + TestAllTypesLite.parseFrom(message.toByteString().asReadOnlyByteBuffer()); + + assertEquals(message, copy); + } + + public void testParseFromByteBufferThrows() { + try { + TestAllTypesLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 })); + fail(); + } catch (InvalidProtocolBufferException expected) { + } + + TestAllTypesLite message = + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .addRepeatedString("hello") + .build(); + + ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); + try { + TestAllTypesLite.parseFrom(buffer); + fail(); + } catch (InvalidProtocolBufferException expected) { + assertEquals( + TestAllTypesLite.newBuilder() + .setOptionalInt32(123) + .build(), + expected.getUnfinishedMessage()); + } + } + + public void testParseFromByteBuffer_extensions() throws Exception { + TestAllExtensionsLite message = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .addExtension(UnittestLite.repeatedStringExtensionLite, "hello") + .setExtension( + UnittestLite.optionalNestedEnumExtensionLite, TestAllTypesLite.NestedEnum.BAZ) + .setExtension( + UnittestLite.optionalNestedMessageExtensionLite, + TestAllTypesLite.NestedMessage.newBuilder().setBb(7).build()) + .build(); + + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + UnittestLite.registerAllExtensions(registry); + + TestAllExtensionsLite copy = + TestAllExtensionsLite.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry); + + assertEquals(message, copy); + } + + public void testParseFromByteBufferThrows_extensions() { + ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance(); + UnittestLite.registerAllExtensions(registry); + try { + TestAllExtensionsLite.parseFrom(ByteBuffer.wrap(new byte[] { 0x5 }), registry); + fail(); + } catch (InvalidProtocolBufferException expected) { + } + + TestAllExtensionsLite message = + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .addExtension(UnittestLite.repeatedStringExtensionLite, "hello") + .build(); + + ByteBuffer buffer = ByteBuffer.wrap(message.toByteArray(), 0, message.getSerializedSize() - 1); + try { + TestAllExtensionsLite.parseFrom(buffer, registry); + fail(); + } catch (InvalidProtocolBufferException expected) { + assertEquals( + TestAllExtensionsLite.newBuilder() + .setExtension(UnittestLite.optionalInt32ExtensionLite, 123) + .build(), + expected.getUnfinishedMessage()); + } + } } diff --git a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java index cfe4c453..453d3928 100644 --- a/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java +++ b/java/core/src/test/java/com/google/protobuf/MapForProto2Test.java @@ -759,6 +759,7 @@ public class MapForProto2Test extends TestCase { assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); } + // See additional coverage in TextFormatTest.java. public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 81e951cc..01b371a3 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -30,7 +30,7 @@ package com.google.protobuf; - +import static org.junit.Assert.assertArrayEquals; import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.EnumDescriptor; import com.google.protobuf.Descriptors.EnumValueDescriptor; @@ -870,6 +870,7 @@ public class MapTest extends TestCase { assertEquals(55, message.getInt32ToInt32Field().get(55).intValue()); } + // See additional coverage in TextFormatTest.java. public void testTextFormat() throws Exception { TestMap.Builder builder = TestMap.newBuilder(); setMapValuesUsingAccessors(builder); @@ -1492,4 +1493,40 @@ public class MapTest extends TestCase { map.put(key3, value3); return map; } + + public void testMap_withNulls() { + TestMap.Builder builder = TestMap.newBuilder(); + + try { + builder.putStringToInt32Field(null, 3); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllStringToInt32Field(newMap(null, 3, "hi", 4)); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putInt32ToMessageField(3, null); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllInt32ToMessageField(newMap(4, null, 5, null)); + fail(); + } catch (NullPointerException expected) { + } + + try { + builder.putAllInt32ToMessageField(null); + fail(); + } catch (NullPointerException expected) { + } + + assertArrayEquals(new byte[0], builder.build().toByteArray()); + } } diff --git a/java/core/src/test/java/com/google/protobuf/ParserTest.java b/java/core/src/test/java/com/google/protobuf/ParserTest.java index 8c2e4c26..4bd34112 100644 --- a/java/core/src/test/java/com/google/protobuf/ParserTest.java +++ b/java/core/src/test/java/com/google/protobuf/ParserTest.java @@ -79,6 +79,8 @@ public class ParserTest extends TestCase { new ByteArrayInputStream(data), registry)); assertMessageEquals(message, parser.parseFrom( CodedInputStream.newInstance(data), registry)); + assertMessageEquals( + message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer(), registry)); } @SuppressWarnings("unchecked") @@ -99,6 +101,7 @@ public class ParserTest extends TestCase { new ByteArrayInputStream(data))); assertMessageEquals(message, parser.parseFrom( CodedInputStream.newInstance(data))); + assertMessageEquals(message, parser.parseFrom(message.toByteString().asReadOnlyByteBuffer())); } private void assertMessageEquals( @@ -178,6 +181,9 @@ public class ParserTest extends TestCase { public void testParseExtensions() throws Exception { assertRoundTripEquals(TestUtil.getAllExtensionsSet(), TestUtil.getExtensionRegistry()); + } + + public void testParseExtensionsLite() throws Exception { assertRoundTripEquals( TestUtilLite.getAllLiteExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } @@ -186,6 +192,9 @@ public class ParserTest extends TestCase { assertRoundTripEquals(TestUtil.getPackedSet()); assertRoundTripEquals(TestUtil.getPackedExtensionsSet(), TestUtil.getExtensionRegistry()); + } + + public void testParsePackedLite() throws Exception { assertRoundTripEquals( TestUtilLite.getLitePackedExtensionsSet(), TestUtilLite.getExtensionRegistryLite()); } @@ -195,15 +204,26 @@ public class ParserTest extends TestCase { TestAllTypes normalMessage = TestUtil.getAllSet(); ByteArrayOutputStream output = new ByteArrayOutputStream(); normalMessage.writeDelimitedTo(output); + normalMessage.writeDelimitedTo(output); + InputStream input = new ByteArrayInputStream(output.toByteArray()); + assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input)); + assertMessageEquals(normalMessage, normalMessage.getParserForType().parseDelimitedFrom(input)); + } + + public void testParseDelimitedToLite() throws Exception { // Write MessageLite with packed extension fields. TestPackedExtensionsLite packedMessage = TestUtilLite.getLitePackedExtensionsSet(); + ByteArrayOutputStream output = new ByteArrayOutputStream(); + packedMessage.writeDelimitedTo(output); packedMessage.writeDelimitedTo(output); InputStream input = new ByteArrayInputStream(output.toByteArray()); assertMessageEquals( - normalMessage, - normalMessage.getParserForType().parseDelimitedFrom(input)); + packedMessage, + packedMessage + .getParserForType() + .parseDelimitedFrom(input, TestUtilLite.getExtensionRegistryLite())); assertMessageEquals( packedMessage, packedMessage @@ -314,8 +334,7 @@ public class ParserTest extends TestCase { public void testParsingMergeLite() throws Exception { // Build messages. - TestAllTypesLite.Builder builder = - TestAllTypesLite.newBuilder(); + TestAllTypesLite.Builder builder = TestAllTypesLite.newBuilder(); TestAllTypesLite msg1 = builder.setOptionalInt32(1).build(); builder.clear(); TestAllTypesLite msg2 = builder.setOptionalInt64(2).build(); diff --git a/java/core/src/test/java/com/google/protobuf/TestUtil.java b/java/core/src/test/java/com/google/protobuf/TestUtil.java index c1bd21db..e96adf07 100644 --- a/java/core/src/test/java/com/google/protobuf/TestUtil.java +++ b/java/core/src/test/java/com/google/protobuf/TestUtil.java @@ -2622,6 +2622,8 @@ public final class TestUtil { break; case FOO_NOT_SET: break; + default: + // TODO(b/18683919): go/enum-switch-lsc } } diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index 6a91b02f..249d7c5e 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -30,9 +30,12 @@ package com.google.protobuf; +import static com.google.common.truth.Truth.assertThat; + import com.google.protobuf.Descriptors.Descriptor; import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.TextFormat.Parser.SingularOverwritePolicy; +import map_test.MapTestProto.TestMap; import protobuf_unittest.UnittestMset.TestMessageSetExtension1; import protobuf_unittest.UnittestMset.TestMessageSetExtension2; import protobuf_unittest.UnittestProto.OneString; @@ -940,6 +943,7 @@ public class TextFormatTest extends TestCase { } + // See additional coverage in testOneofOverwriteForbidden and testMapOverwriteForbidden. public void testParseNonRepeatedFields() throws Exception { assertParseSuccessWithOverwriteForbidden( "repeated_int32: 1\n" + @@ -950,6 +954,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden( "repeated_nested_message { bb: 1 }\n" + "repeated_nested_message { bb: 2 }\n"); + assertParseErrorWithOverwriteForbidden( "3:17: Non-repeated field " + "\"protobuf_unittest.TestAllTypes.optional_int32\" " + @@ -988,6 +993,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden("repeated_int32: [ 1, 2 ]\n"); assertParseSuccessWithOverwriteForbidden("RepeatedGroup [{ a: 1 },{ a: 2 }]\n"); assertParseSuccessWithOverwriteForbidden("repeated_nested_message [{ bb: 1 }, { bb: 2 }]\n"); + // See also testMapShortForm. } public void testParseShortRepeatedFormOfEmptyRepeatedFields() throws Exception { @@ -995,6 +1001,7 @@ public class TextFormatTest extends TestCase { assertParseSuccessWithOverwriteForbidden("repeated_int32: []\n"); assertParseSuccessWithOverwriteForbidden("RepeatedGroup []\n"); assertParseSuccessWithOverwriteForbidden("repeated_nested_message []\n"); + // See also testMapShortFormEmpty. } public void testParseShortRepeatedFormWithTrailingComma() throws Exception { @@ -1010,6 +1017,7 @@ public class TextFormatTest extends TestCase { assertParseErrorWithOverwriteForbidden( "1:37: Expected \"{\".", "repeated_nested_message [{ bb: 1 }, ]\n"); + // See also testMapShortFormTrailingComma. } public void testParseShortRepeatedFormOfNonRepeatedFields() throws Exception { @@ -1057,6 +1065,90 @@ public class TextFormatTest extends TestCase { assertTrue(oneof.hasFooInt()); } + // ======================================================================= + // test map + + public void testMapTextFormat() throws Exception { + TestMap message = + TestMap.newBuilder() + .putInt32ToStringField(10, "apple") + .putInt32ToStringField(20, "banana") + .putInt32ToStringField(30, "cherry") + .build(); + String text = TextFormat.printToUnicodeString(message); + { + TestMap.Builder dest = TestMap.newBuilder(); + TextFormat.merge(text, dest); + assertThat(dest.build()).isEqualTo(message); + } + { + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + assertThat(dest.build()).isEqualTo(message); + } + } + + public void testMapShortForm() throws Exception { + String text = + "string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n" + + "int32_to_message_field " + + "[{ key: 1 value { value: 100 } }, { key: 2 value: { value: 200 } }]\n"; + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + TestMap message = dest.build(); + assertThat(message.getStringToInt32Field().size()).isEqualTo(2); + assertThat(message.getInt32ToMessageField().size()).isEqualTo(2); + assertThat(message.getStringToInt32Field().get("x")).isEqualTo(10); + assertThat(message.getInt32ToMessageField().get(2).getValue()).isEqualTo(200); + } + + public void testMapShortFormEmpty() throws Exception { + String text = "string_to_int32_field []\n" + + "int32_to_message_field: []\n"; + TestMap.Builder dest = TestMap.newBuilder(); + parserWithOverwriteForbidden.merge(text, dest); + TestMap message = dest.build(); + assertThat(message.getStringToInt32Field().size()).isEqualTo(0); + assertThat(message.getInt32ToMessageField().size()).isEqualTo(0); + } + + public void testMapShortFormTrailingComma() throws Exception { + String text = "string_to_int32_field [{ key: 'x' value: 10 }, ]\n"; + TestMap.Builder dest = TestMap.newBuilder(); + try { + parserWithOverwriteForbidden.merge(text, dest); + fail("Expected parse exception."); + } catch (TextFormat.ParseException e) { + assertThat(e).hasMessageThat().isEqualTo("1:48: Expected \"{\"."); + } + } + + public void testMapOverwrite() throws Exception { + String text = + "int32_to_int32_field { key: 1 value: 10 }\n" + + "int32_to_int32_field { key: 2 value: 20 }\n" + + "int32_to_int32_field { key: 1 value: 30 }\n"; + + { + // With default parser, last value set for the key holds. + TestMap.Builder builder = TestMap.newBuilder(); + defaultParser.merge(text, builder); + TestMap map = builder.build(); + assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2); + assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30); + } + + { + // With overwrite forbidden, same behavior. + // TODO(b/29122459): Expect parse exception here. + TestMap.Builder builder = TestMap.newBuilder(); + defaultParser.merge(text, builder); + TestMap map = builder.build(); + assertThat(map.getInt32ToInt32Field().size()).isEqualTo(2); + assertThat(map.getInt32ToInt32Field().get(1).intValue()).isEqualTo(30); + } + } + // ======================================================================= // test location information diff --git a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto index 6eef42c5..b18b0d79 100644 --- a/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto +++ b/java/core/src/test/proto/com/google/protobuf/lite_equals_and_hash.proto @@ -46,6 +46,14 @@ message TestOneofEquals { message Foo { optional int32 value = 1; repeated Bar bar = 2; + map my_map = 3; + oneof Single { + sint64 sint64 = 4; + // LINT: ALLOW_GROUPS + group MyGroup = 5 { + optional int32 value = 1; + } + } extensions 100 to max; } diff --git a/java/lite/pom.xml b/java/lite/pom.xml index d7b15097..c902f819 100644 --- a/java/lite/pom.xml +++ b/java/lite/pom.xml @@ -137,6 +137,7 @@ **/MutabilityOracle.java **/NioByteString.java **/Parser.java + **/PrimitiveNonBoxingCollection.java **/ProtobufArrayList.java **/ProtocolStringList.java **/RopeByteString.java diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index 838700f7..5e0f5fe3 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -30,6 +30,7 @@ package com.google.protobuf.util; +import com.google.common.base.Preconditions; import com.google.common.io.BaseEncoding; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -102,7 +103,8 @@ public class JsonFormat { * Creates a {@link Printer} with default configurations. */ public static Printer printer() { - return new Printer(TypeRegistry.getEmptyTypeRegistry(), false, false, false); + return new Printer( + TypeRegistry.getEmptyTypeRegistry(), false, Collections.emptySet(), false, false); } /** @@ -110,16 +112,27 @@ public class JsonFormat { */ public static class Printer { private final TypeRegistry registry; - private final boolean includingDefaultValueFields; + // NOTE: There are 3 states for these *defaultValueFields variables: + // 1) Default - alwaysOutput is false & including is empty set. Fields only output if they are + // set to non-default values. + // 2) No-args includingDefaultValueFields() called - alwaysOutput is true & including is + // irrelevant (but set to empty set). All fields are output regardless of their values. + // 3) includingDefaultValueFields(Set) called - alwaysOutput is false & + // including is set to the specified set. Fields in that set are always output & fields not + // in that set are only output if set to non-default values. + private boolean alwaysOutputDefaultValueFields; + private Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; private final boolean omittingInsignificantWhitespace; private Printer( TypeRegistry registry, - boolean includingDefaultValueFields, + boolean alwaysOutputDefaultValueFields, + Set includingDefaultValueFields, boolean preservingProtoFieldNames, boolean omittingInsignificantWhitespace) { this.registry = registry; + this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; this.omittingInsignificantWhitespace = omittingInsignificantWhitespace; @@ -137,6 +150,7 @@ public class JsonFormat { } return new Printer( registry, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, omittingInsignificantWhitespace); @@ -149,8 +163,41 @@ public class JsonFormat { * {@link Printer}. */ public Printer includingDefaultValueFields() { + checkUnsetIncludingDefaultValueFields(); return new Printer( - registry, true, preservingProtoFieldNames, omittingInsignificantWhitespace); + registry, + true, + Collections.emptySet(), + preservingProtoFieldNames, + omittingInsignificantWhitespace); + } + + /** + * Creates a new {@link Printer} that will also print default-valued fields if their + * FieldDescriptors are found in the supplied set. Empty repeated fields and map fields will be + * printed as well, if they match. The new Printer clones all other configurations from the + * current {@link Printer}. Call includingDefaultValueFields() with no args to unconditionally + * output all fields. + */ + public Printer includingDefaultValueFields(Set fieldsToAlwaysOutput) { + Preconditions.checkArgument( + null != fieldsToAlwaysOutput && !fieldsToAlwaysOutput.isEmpty(), + "Non-empty Set must be supplied for includingDefaultValueFields."); + + checkUnsetIncludingDefaultValueFields(); + return new Printer( + registry, + false, + fieldsToAlwaysOutput, + preservingProtoFieldNames, + omittingInsignificantWhitespace); + } + + private void checkUnsetIncludingDefaultValueFields() { + if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) { + throw new IllegalStateException( + "JsonFormat includingDefaultValueFields has already been set."); + } } /** @@ -161,15 +208,20 @@ public class JsonFormat { */ public Printer preservingProtoFieldNames() { return new Printer( - registry, includingDefaultValueFields, true, omittingInsignificantWhitespace); + registry, + alwaysOutputDefaultValueFields, + includingDefaultValueFields, + true, + omittingInsignificantWhitespace); } /** - * Create a new {@link Printer} that will omit all insignificant whitespace - * in the JSON output. This new Printer clones all other configurations from the - * current Printer. Insignificant whitespace is defined by the JSON spec as whitespace - * that appear between JSON structural elements: + * Create a new {@link Printer} that will omit all insignificant whitespace in the JSON output. + * This new Printer clones all other configurations from the current Printer. Insignificant + * whitespace is defined by the JSON spec as whitespace that appear between JSON structural + * elements: + * *

      * ws = *(
      * %x20 /              ; Space
@@ -177,18 +229,24 @@ public class JsonFormat {
      * %x0A /              ; Line feed or New line
      * %x0D )              ; Carriage return
      * 
+ * * See https://tools.ietf.org/html/rfc7159 * current {@link Printer}. */ public Printer omittingInsignificantWhitespace() { - return new Printer(registry, includingDefaultValueFields, preservingProtoFieldNames, true); + return new Printer( + registry, + alwaysOutputDefaultValueFields, + includingDefaultValueFields, + preservingProtoFieldNames, + true); } /** * Converts a protobuf message to JSON format. * - * @throws InvalidProtocolBufferException if the message contains Any types - * that can't be resolved. + * @throws InvalidProtocolBufferException if the message contains Any types that can't be + * resolved. * @throws IOException if writing to the output fails. */ public void appendTo(MessageOrBuilder message, Appendable output) throws IOException { @@ -196,6 +254,7 @@ public class JsonFormat { // mobile. new PrinterImpl( registry, + alwaysOutputDefaultValueFields, includingDefaultValueFields, preservingProtoFieldNames, output, @@ -428,19 +487,16 @@ public class JsonFormat { this.output = output; } - /** - * ignored by compact printer - */ + /** ignored by compact printer */ + @Override public void indent() {} - /** - * ignored by compact printer - */ + /** ignored by compact printer */ + @Override public void outdent() {} - /** - * Print text to the output stream. - */ + /** Print text to the output stream. */ + @Override public void print(final CharSequence text) throws IOException { output.append(text); } @@ -458,18 +514,17 @@ public class JsonFormat { } /** - * Indent text by two spaces. After calling Indent(), two spaces will be - * inserted at the beginning of each line of text. Indent() may be called - * multiple times to produce deeper indents. + * Indent text by two spaces. After calling Indent(), two spaces will be inserted at the + * beginning of each line of text. Indent() may be called multiple times to produce deeper + * indents. */ + @Override public void indent() { indent.append(" "); } - /** - * Reduces the current indent level by two spaces, or crashes if the indent - * level is zero. - */ + /** Reduces the current indent level by two spaces, or crashes if the indent level is zero. */ + @Override public void outdent() { final int length = indent.length(); if (length < 2) { @@ -478,9 +533,8 @@ public class JsonFormat { indent.delete(length - 2, length); } - /** - * Print text to the output stream. - */ + /** Print text to the output stream. */ + @Override public void print(final CharSequence text) throws IOException { final int size = text.length(); int pos = 0; @@ -512,7 +566,8 @@ public class JsonFormat { */ private static final class PrinterImpl { private final TypeRegistry registry; - private final boolean includingDefaultValueFields; + private final boolean alwaysOutputDefaultValueFields; + private final Set includingDefaultValueFields; private final boolean preservingProtoFieldNames; private final TextGenerator generator; // We use Gson to help handle string escapes. @@ -526,11 +581,13 @@ public class JsonFormat { PrinterImpl( TypeRegistry registry, - boolean includingDefaultValueFields, + boolean alwaysOutputDefaultValueFields, + Set includingDefaultValueFields, boolean preservingProtoFieldNames, Appendable jsonOutput, boolean omittingInsignificantWhitespace) { this.registry = registry; + this.alwaysOutputDefaultValueFields = alwaysOutputDefaultValueFields; this.includingDefaultValueFields = includingDefaultValueFields; this.preservingProtoFieldNames = preservingProtoFieldNames; this.gson = GsonHolder.DEFAULT_GSON; @@ -781,23 +838,26 @@ public class JsonFormat { printedField = true; } Map fieldsToPrint = null; - if (includingDefaultValueFields) { - fieldsToPrint = new TreeMap(); + if (alwaysOutputDefaultValueFields || !includingDefaultValueFields.isEmpty()) { + fieldsToPrint = new TreeMap(message.getAllFields()); for (FieldDescriptor field : message.getDescriptorForType().getFields()) { if (field.isOptional()) { if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE - && !message.hasField(field)){ + && !message.hasField(field)) { // Always skip empty optional message fields. If not we will recurse indefinitely if // a message has itself as a sub-field. continue; } OneofDescriptor oneof = field.getContainingOneof(); if (oneof != null && !message.hasField(field)) { - // Skip all oneof fields except the one that is actually set + // Skip all oneof fields except the one that is actually set continue; } } - fieldsToPrint.put(field, message.getField(field)); + if (!fieldsToPrint.containsKey(field) + && (alwaysOutputDefaultValueFields || includingDefaultValueFields.contains(field))) { + fieldsToPrint.put(field, message.getField(field)); + } } } else { fieldsToPrint = message.getAllFields(); @@ -1451,45 +1511,6 @@ public class JsonFormat { } } - /** - * Gets the default value for a field type. Note that we use proto3 - * language defaults and ignore any default values set through the - * proto "default" option. - */ - private Object getDefaultValue(FieldDescriptor field, Message.Builder builder) { - switch (field.getType()) { - case INT32: - case SINT32: - case SFIXED32: - case UINT32: - case FIXED32: - return 0; - case INT64: - case SINT64: - case SFIXED64: - case UINT64: - case FIXED64: - return 0L; - case FLOAT: - return 0.0f; - case DOUBLE: - return 0.0; - case BOOL: - return false; - case STRING: - return ""; - case BYTES: - return ByteString.EMPTY; - case ENUM: - return field.getEnumType().getValues().get(0); - case MESSAGE: - case GROUP: - return builder.newBuilderForField(field).getDefaultInstanceForType(); - default: - throw new IllegalStateException("Invalid field type: " + field.getType()); - } - } - private void mergeRepeatedField( FieldDescriptor field, JsonElement json, Message.Builder builder) throws InvalidProtocolBufferException { diff --git a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java index 1d631a2c..d0bac417 100644 --- a/java/util/src/main/java/com/google/protobuf/util/Timestamps.java +++ b/java/util/src/main/java/com/google/protobuf/util/Timestamps.java @@ -297,7 +297,7 @@ public final class Timestamps { * Convert a Timestamp to the number of microseconds elapsed from the epoch. * *

The result will be rounded down to the nearest microsecond. E.g., if the timestamp - * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 millisecond. + * represents "1969-12-31T23:59:59.999999999Z", it will be rounded to -1 microsecond. */ public static long toMicros(Timestamp timestamp) { checkValid(timestamp); diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index de02c117..6943093f 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -34,6 +34,7 @@ import com.google.protobuf.Any; import com.google.protobuf.BoolValue; import com.google.protobuf.ByteString; import com.google.protobuf.BytesValue; +import com.google.protobuf.Descriptors.FieldDescriptor; import com.google.protobuf.DoubleValue; import com.google.protobuf.FloatValue; import com.google.protobuf.Int32Value; @@ -68,9 +69,12 @@ import java.io.Reader; import java.io.StringReader; import java.math.BigDecimal; import java.math.BigInteger; +import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Locale; import java.util.Map; +import java.util.Set; import junit.framework.TestCase; public class JsonFormatTest extends TestCase { @@ -284,8 +288,8 @@ public class JsonFormatTest extends TestCase { assertEquals(9012, message.getOptionalSint32()); assertEquals(3456, message.getOptionalFixed32()); assertEquals(7890, message.getOptionalSfixed32()); - assertEquals(1.5f, message.getOptionalFloat()); - assertEquals(1.25, message.getOptionalDouble()); + assertEquals(1.5f, message.getOptionalFloat(), 0.0f); + assertEquals(1.25, message.getOptionalDouble(), 0.0); assertEquals(true, message.getOptionalBool()); } @@ -1215,6 +1219,115 @@ public class JsonFormatTest extends TestCase { + "}", JsonFormat.printer().includingDefaultValueFields().print(message)); + Set fixedFields = new HashSet(); + for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { + if (fieldDesc.getName().contains("_fixed")) { + fixedFields.add(fieldDesc); + } + } + + assertEquals( + "{\n" + + " \"optionalFixed32\": 0,\n" + + " \"optionalFixed64\": \"0\",\n" + + " \"repeatedFixed32\": [],\n" + + " \"repeatedFixed64\": []\n" + + "}", + JsonFormat.printer().includingDefaultValueFields(fixedFields).print(message)); + + TestAllTypes messageNonDefaults = + message.toBuilder().setOptionalInt64(1234).setOptionalFixed32(3232).build(); + assertEquals( + "{\n" + + " \"optionalInt64\": \"1234\",\n" + + " \"optionalFixed32\": 3232,\n" + + " \"optionalFixed64\": \"0\",\n" + + " \"repeatedFixed32\": [],\n" + + " \"repeatedFixed64\": []\n" + + "}", + JsonFormat.printer().includingDefaultValueFields(fixedFields).print(messageNonDefaults)); + + try { + JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(); + fail("IllegalStateException is expected."); + } catch (IllegalStateException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + try { + JsonFormat.printer().includingDefaultValueFields().includingDefaultValueFields(fixedFields); + fail("IllegalStateException is expected."); + } catch (IllegalStateException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + try { + JsonFormat.printer().includingDefaultValueFields(fixedFields).includingDefaultValueFields(); + fail("IllegalStateException is expected."); + } catch (IllegalStateException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + try { + JsonFormat.printer() + .includingDefaultValueFields(fixedFields) + .includingDefaultValueFields(fixedFields); + fail("IllegalStateException is expected."); + } catch (IllegalStateException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + Set intFields = new HashSet(); + for (FieldDescriptor fieldDesc : TestAllTypes.getDescriptor().getFields()) { + if (fieldDesc.getName().contains("_int")) { + intFields.add(fieldDesc); + } + } + + try { + JsonFormat.printer() + .includingDefaultValueFields(intFields) + .includingDefaultValueFields(fixedFields); + fail("IllegalStateException is expected."); + } catch (IllegalStateException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + try { + JsonFormat.printer().includingDefaultValueFields(null); + fail("IllegalArgumentException is expected."); + } catch (IllegalArgumentException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + + try { + JsonFormat.printer().includingDefaultValueFields(Collections.emptySet()); + fail("IllegalArgumentException is expected."); + } catch (IllegalArgumentException e) { + // Expected. + assertTrue( + "Exception message should mention includingDefaultValueFields.", + e.getMessage().contains("includingDefaultValueFields")); + } + TestMap mapMessage = TestMap.getDefaultInstance(); assertEquals("{\n}", JsonFormat.printer().print(mapMessage)); assertEquals( @@ -1283,16 +1396,17 @@ public class JsonFormatTest extends TestCase { assertEquals("{\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); oneofMessage = TestOneof.newBuilder().setOneofInt32(42).build(); - assertEquals("{\n \"oneofInt32\": 42\n}", - JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n \"oneofInt32\": 42\n}", + assertEquals("{\n \"oneofInt32\": 42\n}", JsonFormat.printer().print(oneofMessage)); + assertEquals( + "{\n \"oneofInt32\": 42\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); TestOneof.Builder oneofBuilder = TestOneof.newBuilder(); mergeFromJson("{\n" + " \"oneofNullValue\": null \n" + "}", oneofBuilder); oneofMessage = oneofBuilder.build(); assertEquals("{\n \"oneofNullValue\": null\n}", JsonFormat.printer().print(oneofMessage)); - assertEquals("{\n \"oneofNullValue\": null\n}", + assertEquals( + "{\n \"oneofNullValue\": null\n}", JsonFormat.printer().includingDefaultValueFields().print(oneofMessage)); } @@ -1424,11 +1538,12 @@ public class JsonFormatTest extends TestCase { // Test that we are not leaking out JSON exceptions. public void testJsonException() throws Exception { - InputStream throwingInputStream = new InputStream() { - public int read() throws IOException { - throw new IOException("12345"); - } - }; + InputStream throwingInputStream = + new InputStream() { + public int read() throws IOException { + throw new IOException("12345"); + } + }; InputStreamReader throwingReader = new InputStreamReader(throwingInputStream); // When the underlying reader throws IOException, JsonFormat should forward // through this IOException. diff --git a/js/binary/decoder.js b/js/binary/decoder.js index 26bf3594..ad9cb01b 100644 --- a/js/binary/decoder.js +++ b/js/binary/decoder.js @@ -71,7 +71,7 @@ jspb.BinaryIterator = function(opt_decoder, opt_next, opt_elements) { */ this.nextMethod_ = null; - /** @private {Array.} */ + /** @private {?Array} */ this.elements_ = null; /** @private {number} */ @@ -100,7 +100,7 @@ jspb.BinaryIterator.prototype.init_ = this.decoder_ = opt_decoder; this.nextMethod_ = opt_next; } - this.elements_ = opt_elements ? opt_elements : null; + this.elements_ = opt_elements || null; this.cursor_ = 0; this.nextValue_ = null; this.atEnd_ = !this.decoder_ && !this.elements_; @@ -953,6 +953,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) { var end = cursor + length; var codeUnits = []; + var result = ''; while (cursor < end) { var c = bytes[cursor++]; if (c < 128) { // Regular 7-bit ASCII. @@ -973,7 +974,7 @@ jspb.BinaryDecoder.prototype.readString = function(length) { var c2 = bytes[cursor++]; var c3 = bytes[cursor++]; var c4 = bytes[cursor++]; - // Characters written on 4 bytes have 21 bits for a codepoint. + // Characters written on 4 bytes have 21 bits for a codepoint. // We can't fit that on 16bit characters, so we use surrogates. var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63); // Surrogates formula from wikipedia. @@ -986,10 +987,14 @@ jspb.BinaryDecoder.prototype.readString = function(length) { var high = ((codepoint >> 10) & 1023) + 0xD800; codeUnits.push(high, low); } + + // Avoid exceeding the maximum stack size when calling {@code apply}. + if (codeUnits.length >= 8192) { + result += String.fromCharCode.apply(null, codeUnits); + codeUnits.length = 0; + } } - // String.fromCharCode.apply is faster than manually appending characters on - // Chrome 25+, and generates no additional cons string garbage. - var result = String.fromCharCode.apply(null, codeUnits); + result += String.fromCharCode.apply(null, codeUnits); this.cursor_ = cursor; return result; }; diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js index cb8aff96..d0139e29 100644 --- a/js/binary/decoder_test.js +++ b/js/binary/decoder_test.js @@ -210,6 +210,25 @@ describe('binaryDecoderTest', function() { assertEquals(hashD, decoder.readFixedHash64()); }); + /** + * Tests reading and writing large strings + */ + it('testLargeStrings', function() { + var encoder = new jspb.BinaryEncoder(); + + var len = 150000; + var long_string = ''; + for (var i = 0; i < len; i++) { + long_string += 'a'; + } + + encoder.writeString(long_string); + + var decoder = jspb.BinaryDecoder.alloc(encoder.end()); + + assertEquals(long_string, decoder.readString(len)); + }); + /** * Test encoding and decoding utf-8. */ diff --git a/js/binary/encoder.js b/js/binary/encoder.js index aee33e7e..f25935f1 100644 --- a/js/binary/encoder.js +++ b/js/binary/encoder.js @@ -355,8 +355,8 @@ jspb.BinaryEncoder.prototype.writeInt64 = function(value) { */ jspb.BinaryEncoder.prototype.writeInt64String = function(value) { goog.asserts.assert(value == Math.floor(value)); - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); + goog.asserts.assert((+value >= -jspb.BinaryConstants.TWO_TO_63) && + (+value < jspb.BinaryConstants.TWO_TO_63)); jspb.utils.splitHash64(jspb.utils.decimalStringToHash64(value)); this.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High); }; diff --git a/js/binary/reader.js b/js/binary/reader.js index 8c5a4e88..d5d698f7 100644 --- a/js/binary/reader.js +++ b/js/binary/reader.js @@ -971,7 +971,7 @@ jspb.BinaryReader.prototype.readFixedHash64 = function() { /** * Reads a packed scalar field using the supplied raw reader function. - * @param {function()} decodeMethod + * @param {function(this:jspb.BinaryDecoder)} decodeMethod * @return {!Array} * @private */ diff --git a/js/binary/utils.js b/js/binary/utils.js index 3ecd08e9..7702020b 100644 --- a/js/binary/utils.js +++ b/js/binary/utils.js @@ -430,7 +430,7 @@ jspb.utils.joinHash64 = function(bitsLow, bitsHigh) { /** * Individual digits for number->string conversion. - * @const {!Array.} + * @const {!Array.} */ jspb.utils.DIGITS = [ '0', '1', '2', '3', '4', '5', '6', '7', diff --git a/js/binary/writer.js b/js/binary/writer.js index c3009dbb..672e94bd 100644 --- a/js/binary/writer.js +++ b/js/binary/writer.js @@ -596,8 +596,8 @@ jspb.BinaryWriter.prototype.writeSint64 = function(field, value) { */ jspb.BinaryWriter.prototype.writeSint64String = function(field, value) { if (value == null) return; - goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && - (value < jspb.BinaryConstants.TWO_TO_63)); + goog.asserts.assert((+value >= -jspb.BinaryConstants.TWO_TO_63) && + (+value < jspb.BinaryConstants.TWO_TO_63)); this.writeZigzagVarint64String_(field, value); }; diff --git a/js/binary/writer_test.js b/js/binary/writer_test.js index 83fcdf91..118eecfc 100644 --- a/js/binary/writer_test.js +++ b/js/binary/writer_test.js @@ -47,7 +47,7 @@ goog.require('jspb.BinaryWriter'); * @param {function()} func This function should throw an error when run. */ function assertFails(func) { - var e = assertThrows(func); + assertThrows(func); } diff --git a/js/map.js b/js/map.js index 4f562dbc..d423499f 100644 --- a/js/map.js +++ b/js/map.js @@ -136,7 +136,7 @@ jspb.Map.prototype.toArray = function() { * * @param {boolean=} includeInstance Whether to include the JSPB instance for * transitional soy proto support: http://goto/soy-param-migration - * @param {!function((boolean|undefined),!V):!Object=} valueToObject + * @param {!function((boolean|undefined),V):!Object=} valueToObject * The static toObject() method, if V is a message type. * @return {!Array>} */ @@ -146,7 +146,7 @@ jspb.Map.prototype.toObject = function(includeInstance, valueToObject) { for (var i = 0; i < rawArray.length; i++) { var entry = this.map_[rawArray[i][0].toString()]; this.wrapEntry_(entry); - var valueWrapper = /** @type {!V|undefined} */ (entry.valueWrapper); + var valueWrapper = /** @type {V|undefined} */ (entry.valueWrapper); if (valueWrapper) { goog.asserts.assert(valueToObject); entries.push([entry.key, valueToObject(includeInstance, valueWrapper)]); @@ -412,8 +412,8 @@ jspb.Map.prototype.has = function(key) { * @param {!jspb.BinaryWriter} writer * @param {!function(this:jspb.BinaryWriter,number,K)} keyWriterFn * The method on BinaryWriter that writes type K to the stream. - * @param {!function(this:jspb.BinaryWriter,number,V)| - * function(this:jspb.BinaryReader,V,?)} valueWriterFn + * @param {!function(this:jspb.BinaryWriter,number,V,?=)| + * function(this:jspb.BinaryWriter,number,V,?)} valueWriterFn * The method on BinaryWriter that writes type V to the stream. May be * writeMessage, in which case the second callback arg form is used. * @param {function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback @@ -509,7 +509,7 @@ jspb.Map.prototype.stringKeys_ = function() { /** - * @param {!K} key The entry's key. + * @param {K} key The entry's key. * @param {V=} opt_value The entry's value wrapper. * @constructor * @struct diff --git a/js/message.js b/js/message.js index 220a5bdb..1f6bf16b 100644 --- a/js/message.js +++ b/js/message.js @@ -106,8 +106,9 @@ jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, /** * Stores binary-related information for a single extension field. * @param {!jspb.ExtensionFieldInfo} fieldInfo - * @param {!function(number,?)} binaryReaderFn - * @param {!function(number,?)|function(number,?,?,?,?,?)} binaryWriterFn + * @param {function(this:jspb.BinaryReader,number,?)} binaryReaderFn + * @param {function(this:jspb.BinaryWriter,number,?) + * |function(this:jspb.BinaryWriter,number,?,?,?,?,?)} binaryWriterFn * @param {function(?,?)=} opt_binaryMessageSerializeFn * @param {function(?,?)=} opt_binaryMessageDeserializeFn * @param {boolean=} opt_isPacked @@ -141,6 +142,21 @@ jspb.ExtensionFieldInfo.prototype.isMessageType = function() { /** * Base class for all JsPb messages. + * + * Several common methods (toObject, serializeBinary, in particular) are not + * defined on the prototype to encourage code patterns that minimize code bloat + * due to otherwise unused code on all protos contained in the project. + * + * If you want to call these methods on a generic message, either + * pass in your instance of method as a parameter: + * someFunction(instanceOfKnownProto, + * KnownProtoClass.prototype.serializeBinary); + * or use a lambda that knows the type: + * someFunction(()=>instanceOfKnownProto.serializeBinary()); + * or, if you don't care about code size, just suppress the + * WARNING - Property serializeBinary never defined on jspb.Message + * and call it the intuitive way. + * * @constructor * @struct */ @@ -524,7 +540,7 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions, * @param {!jspb.Message} proto The proto whose extensions to convert. * @param {*} writer The binary-format writer to write to. * @param {!Object} extensions The proto class' registered extensions. - * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto + * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo) : *} getExtensionFn The proto * class' getExtension function. Passed for effective dead code removal. */ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, @@ -570,10 +586,13 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, * Reads an extension field from the given reader and, if a valid extension, * sets the extension value. * @param {!jspb.Message} msg A jspb proto. - * @param {{skipField:function(),getFieldNumber:function():number}} reader + * @param {{ + * skipField:function(this:jspb.BinaryReader), + * getFieldNumber:function(this:jspb.BinaryReader):number + * }} reader * @param {!Object} extensions The extensions object. - * @param {function(jspb.ExtensionFieldInfo)} getExtensionFn - * @param {function(jspb.ExtensionFieldInfo, ?)} setExtensionFn + * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo)} getExtensionFn + * @param {function(this:jspb.Message,!jspb.ExtensionFieldInfo, ?)} setExtensionFn */ jspb.Message.readBinaryExtension = function(msg, reader, extensions, getExtensionFn, setExtensionFn) { diff --git a/js/message_test.js b/js/message_test.js index 2298742d..dc0ae211 100644 --- a/js/message_test.js +++ b/js/message_test.js @@ -40,6 +40,7 @@ goog.require('goog.userAgent'); goog.require('jspb.Message'); // CommonJS-LoadFromFile: test8_pb proto.jspb.exttest.nested +goog.require('proto.jspb.exttest.nested.TestNestedExtensionsMessage'); goog.require('proto.jspb.exttest.nested.TestOuterMessage'); // CommonJS-LoadFromFile: test5_pb proto.jspb.exttest.beta diff --git a/python/google/protobuf/descriptor_database.py b/python/google/protobuf/descriptor_database.py index 1333f996..40bcdd72 100644 --- a/python/google/protobuf/descriptor_database.py +++ b/python/google/protobuf/descriptor_database.py @@ -54,9 +54,9 @@ class DescriptorDatabase(object): Args: file_desc_proto: The FileDescriptorProto to add. Raises: - DescriptorDatabaseException: if an attempt is made to add a proto - with the same name but different definition than an exisiting - proto in the database. + DescriptorDatabaseConflictingDefinitionError: if an attempt is made to + add a proto with the same name but different definition than an + exisiting proto in the database. """ proto_name = file_desc_proto.name if proto_name not in self._file_desc_protos_by_file: @@ -65,7 +65,7 @@ class DescriptorDatabase(object): raise DescriptorDatabaseConflictingDefinitionError( '%s already added, but with different descriptor.' % proto_name) - # Add the top-level Message, Enum and Extension descriptors to the index. + # Add all the top-level descriptors to the index. package = file_desc_proto.package for message in file_desc_proto.message_type: self._file_desc_protos_by_symbol.update( @@ -76,6 +76,9 @@ class DescriptorDatabase(object): for extension in file_desc_proto.extension: self._file_desc_protos_by_symbol[ '.'.join((package, extension.name))] = file_desc_proto + for service in file_desc_proto.service: + self._file_desc_protos_by_symbol[ + '.'.join((package, service.name))] = file_desc_proto def FindFileByName(self, name): """Finds the file descriptor proto by file name. diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index fc3a7f44..7844575f 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -124,6 +124,7 @@ class DescriptorPool(object): self._descriptor_db = descriptor_db self._descriptors = {} self._enum_descriptors = {} + self._service_descriptors = {} self._file_descriptors = {} self._toplevel_extensions = {} # We store extensions in two two-level mappings: The first key is the @@ -174,7 +175,7 @@ class DescriptorPool(object): def AddEnumDescriptor(self, enum_desc): """Adds an EnumDescriptor to the pool. - This method also registers the FileDescriptor associated with the message. + This method also registers the FileDescriptor associated with the enum. Args: enum_desc: An EnumDescriptor. @@ -186,6 +187,18 @@ class DescriptorPool(object): self._enum_descriptors[enum_desc.full_name] = enum_desc self.AddFileDescriptor(enum_desc.file) + def AddServiceDescriptor(self, service_desc): + """Adds a ServiceDescriptor to the pool. + + Args: + service_desc: A ServiceDescriptor. + """ + + if not isinstance(service_desc, descriptor.ServiceDescriptor): + raise TypeError('Expected instance of descriptor.ServiceDescriptor.') + + self._service_descriptors[service_desc.full_name] = service_desc + def AddExtensionDescriptor(self, extension): """Adds a FieldDescriptor describing an extension to the pool. @@ -252,7 +265,7 @@ class DescriptorPool(object): A FileDescriptor for the named file. Raises: - KeyError: if the file can not be found in the pool. + KeyError: if the file cannot be found in the pool. """ try: @@ -281,7 +294,7 @@ class DescriptorPool(object): A FileDescriptor that contains the specified symbol. Raises: - KeyError: if the file can not be found in the pool. + KeyError: if the file cannot be found in the pool. """ symbol = _NormalizeFullyQualifiedName(symbol) @@ -296,15 +309,18 @@ class DescriptorPool(object): pass try: - file_proto = self._internal_db.FindFileContainingSymbol(symbol) - except KeyError as error: - if self._descriptor_db: - file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) - else: - raise error - if not file_proto: + return self._FindFileContainingSymbolInDb(symbol) + except KeyError: + pass + + # Try nested extensions inside a message. + message_name, _, extension_name = symbol.rpartition('.') + try: + scope = self.FindMessageTypeByName(message_name) + assert scope.extensions_by_name[extension_name] + return scope.file + except KeyError: raise KeyError('Cannot find a file containing %s' % symbol) - return self._ConvertFileProtoToFileDescriptor(file_proto) def FindMessageTypeByName(self, full_name): """Loads the named descriptor from the pool. @@ -314,11 +330,14 @@ class DescriptorPool(object): Returns: The descriptor for the named type. + + Raises: + KeyError: if the message cannot be found in the pool. """ full_name = _NormalizeFullyQualifiedName(full_name) if full_name not in self._descriptors: - self.FindFileContainingSymbol(full_name) + self._FindFileContainingSymbolInDb(full_name) return self._descriptors[full_name] def FindEnumTypeByName(self, full_name): @@ -329,11 +348,14 @@ class DescriptorPool(object): Returns: The enum descriptor for the named type. + + Raises: + KeyError: if the enum cannot be found in the pool. """ full_name = _NormalizeFullyQualifiedName(full_name) if full_name not in self._enum_descriptors: - self.FindFileContainingSymbol(full_name) + self._FindFileContainingSymbolInDb(full_name) return self._enum_descriptors[full_name] def FindFieldByName(self, full_name): @@ -344,6 +366,9 @@ class DescriptorPool(object): Returns: The field descriptor for the named field. + + Raises: + KeyError: if the field cannot be found in the pool. """ full_name = _NormalizeFullyQualifiedName(full_name) message_name, _, field_name = full_name.rpartition('.') @@ -358,6 +383,9 @@ class DescriptorPool(object): Returns: A FieldDescriptor, describing the named extension. + + Raises: + KeyError: if the extension cannot be found in the pool. """ full_name = _NormalizeFullyQualifiedName(full_name) try: @@ -374,7 +402,7 @@ class DescriptorPool(object): scope = self.FindMessageTypeByName(message_name) except KeyError: # Some extensions are defined at file scope. - scope = self.FindFileContainingSymbol(full_name) + scope = self._FindFileContainingSymbolInDb(full_name) return scope.extensions_by_name[extension_name] def FindExtensionByNumber(self, message_descriptor, number): @@ -390,7 +418,7 @@ class DescriptorPool(object): Returns: A FieldDescriptor describing the extension. - Raise: + Raises: KeyError: when no extension with the given number is known for the specified message. """ @@ -410,6 +438,46 @@ class DescriptorPool(object): """ return list(self._extensions_by_number[message_descriptor].values()) + def FindServiceByName(self, full_name): + """Loads the named service descriptor from the pool. + + Args: + full_name: The full name of the service descriptor to load. + + Returns: + The service descriptor for the named service. + + Raises: + KeyError: if the service cannot be found in the pool. + """ + full_name = _NormalizeFullyQualifiedName(full_name) + if full_name not in self._service_descriptors: + self._FindFileContainingSymbolInDb(full_name) + return self._service_descriptors[full_name] + + def _FindFileContainingSymbolInDb(self, symbol): + """Finds the file in descriptor DB containing the specified symbol. + + Args: + symbol: The name of the symbol to search for. + + Returns: + A FileDescriptor that contains the specified symbol. + + Raises: + KeyError: if the file cannot be found in the descriptor database. + """ + try: + file_proto = self._internal_db.FindFileContainingSymbol(symbol) + except KeyError as error: + if self._descriptor_db: + file_proto = self._descriptor_db.FindFileContainingSymbol(symbol) + else: + raise error + if not file_proto: + raise KeyError('Cannot find a file containing %s' % symbol) + return self._ConvertFileProtoToFileDescriptor(file_proto) + def _ConvertFileProtoToFileDescriptor(self, file_proto): """Creates a FileDescriptor from a proto or returns a cached copy. @@ -804,6 +872,7 @@ class DescriptorPool(object): methods=methods, options=_OptionsOrNone(service_proto), file=file_desc) + self._service_descriptors[service_name] = desc return desc def _MakeMethodDescriptor(self, method_proto, service_name, package, scope, diff --git a/python/google/protobuf/internal/containers.py b/python/google/protobuf/internal/containers.py index de13018e..68be9e54 100755 --- a/python/google/protobuf/internal/containers.py +++ b/python/google/protobuf/internal/containers.py @@ -275,7 +275,7 @@ class RepeatedScalarFieldContainer(BaseContainer): new_values = [self._type_checker.CheckValue(elem) for elem in elem_seq_iter] if new_values: self._values.extend(new_values) - self._message_listener.Modified() + self._message_listener.Modified() def MergeFrom(self, other): """Appends the contents of another repeated field of the same type to this diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index 1e710dcf..2ba1d285 100644 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -71,6 +71,13 @@ class DescriptorPoolTest(unittest.TestCase): self.pool.Add(self.factory_test1_fd) self.pool.Add(self.factory_test2_fd) + self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString( + unittest_import_public_pb2.DESCRIPTOR.serialized_pb)) + self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString( + unittest_import_pb2.DESCRIPTOR.serialized_pb)) + self.pool.Add(descriptor_pb2.FileDescriptorProto.FromString( + unittest_pb2.DESCRIPTOR.serialized_pb)) + def testFindFileByName(self): name1 = 'google/protobuf/internal/factory_test1.proto' file_desc1 = self.pool.FindFileByName(name1) @@ -107,6 +114,20 @@ class DescriptorPoolTest(unittest.TestCase): self.assertEqual('google.protobuf.python.internal', file_desc2.package) self.assertIn('Factory2Message', file_desc2.message_types_by_name) + # Tests top level extension. + file_desc3 = self.pool.FindFileContainingSymbol( + 'google.protobuf.python.internal.another_field') + self.assertIsInstance(file_desc3, descriptor.FileDescriptor) + self.assertEqual('google/protobuf/internal/factory_test2.proto', + file_desc3.name) + + # Tests nested extension inside a message. + file_desc4 = self.pool.FindFileContainingSymbol( + 'google.protobuf.python.internal.Factory2Message.one_more_field') + self.assertIsInstance(file_desc4, descriptor.FileDescriptor) + self.assertEqual('google/protobuf/internal/factory_test2.proto', + file_desc4.name) + def testFindFileContainingSymbolFailure(self): with self.assertRaises(KeyError): self.pool.FindFileContainingSymbol('Does not exist') @@ -311,6 +332,10 @@ class DescriptorPoolTest(unittest.TestCase): self.pool.FindExtensionByName( 'google.protobuf.python.internal.Factory1Message.list_value') + def testFindService(self): + service = self.pool.FindServiceByName('protobuf_unittest.TestService') + self.assertEqual(service.full_name, 'protobuf_unittest.TestService') + def testUserDefinedDB(self): db = descriptor_database.DescriptorDatabase() self.pool = descriptor_pool.DescriptorPool(db) @@ -643,6 +668,17 @@ class AddDescriptorTest(unittest.TestCase): self._TestEnum('') self._TestEnum('.') + @unittest.skipIf(api_implementation.Type() == 'cpp', + 'With the cpp implementation, Add() must be called first') + def testService(self): + pool = descriptor_pool.DescriptorPool() + with self.assertRaises(KeyError): + pool.FindServiceByName('protobuf_unittest.TestService') + pool.AddServiceDescriptor(unittest_pb2._TESTSERVICE) + self.assertEqual( + 'protobuf_unittest.TestService', + pool.FindServiceByName('protobuf_unittest.TestService').full_name) + @unittest.skipIf(api_implementation.Type() == 'cpp', 'With the cpp implementation, Add() must be called first') def testFile(self): diff --git a/python/google/protobuf/internal/encoder.py b/python/google/protobuf/internal/encoder.py index 48ef2df3..80e59cab 100755 --- a/python/google/protobuf/internal/encoder.py +++ b/python/google/protobuf/internal/encoder.py @@ -340,7 +340,7 @@ def MessageSetItemSizer(field_number): # Map is special: it needs custom logic to compute its size properly. -def MapSizer(field_descriptor): +def MapSizer(field_descriptor, is_message_map): """Returns a sizer for a map field.""" # Can't look at field_descriptor.message_type._concrete_class because it may @@ -355,9 +355,12 @@ def MapSizer(field_descriptor): # It's wasteful to create the messages and throw them away one second # later since we'll do the same for the actual encode. But there's not an # obvious way to avoid this within the current design without tons of code - # duplication. + # duplication. For message map, value.ByteSize() should be called to + # update the status. entry_msg = message_type._concrete_class(key=key, value=value) total += message_sizer(entry_msg) + if is_message_map: + value.ByteSize() return total return FieldSize diff --git a/python/google/protobuf/internal/message_test.py b/python/google/protobuf/internal/message_test.py index 9986c0d9..e8b794f0 100755 --- a/python/google/protobuf/internal/message_test.py +++ b/python/google/protobuf/internal/message_test.py @@ -564,6 +564,11 @@ class MessageTest(BaseTestCase): self.assertIsInstance(m.repeated_nested_message, collections.MutableSequence) + def testRepeatedFieldInsideNestedMessage(self, message_module): + m = message_module.NestedTestAllTypes() + m.payload.repeated_int32.extend([]) + self.assertTrue(m.HasField('payload')) + def ensureNestedMessageExists(self, msg, attribute): """Make sure that a nested message object exists. @@ -1432,6 +1437,18 @@ class Proto3Test(BaseTestCase): self.assertIn(-456, msg2.map_int32_foreign_message) self.assertEqual(2, len(msg2.map_int32_foreign_message)) + def testMapByteSize(self): + msg = map_unittest_pb2.TestMap() + msg.map_int32_int32[1] = 1 + size = msg.ByteSize() + msg.map_int32_int32[1] = 128 + self.assertEqual(msg.ByteSize(), size + 1) + + msg.map_int32_foreign_message[19].c = 1 + size = msg.ByteSize() + msg.map_int32_foreign_message[19].c = 128 + self.assertEqual(msg.ByteSize(), size + 1) + def testMergeFrom(self): msg = map_unittest_pb2.TestMap() msg.map_int32_int32[12] = 34 @@ -1456,7 +1473,15 @@ class Proto3Test(BaseTestCase): self.assertEqual(5, msg2.map_int32_foreign_message[111].c) self.assertEqual(10, msg2.map_int32_foreign_message[222].c) self.assertFalse(msg2.map_int32_foreign_message[222].HasField('d')) - self.assertEqual(15, old_map_value.c) + if api_implementation.Type() != 'cpp': + # During the call to MergeFrom(), the C++ implementation will have + # deallocated the underlying message, but this is very difficult to detect + # properly. The line below is likely to cause a segmentation fault. + # With the Python implementation, old_map_value is just 'detached' from + # the main message. Using it will not crash of course, but since it still + # have a reference to the parent message I'm sure we can find interesting + # ways to cause inconsistencies. + self.assertEqual(15, old_map_value.c) # Verify that there is only one entry per key, even though the MergeFrom # may have internally created multiple entries for a single key in the diff --git a/python/google/protobuf/internal/python_message.py b/python/google/protobuf/internal/python_message.py index 4b701039..cb97cb28 100755 --- a/python/google/protobuf/internal/python_message.py +++ b/python/google/protobuf/internal/python_message.py @@ -288,7 +288,8 @@ def _AttachFieldHelpers(cls, field_descriptor): if is_map_entry: field_encoder = encoder.MapEncoder(field_descriptor) - sizer = encoder.MapSizer(field_descriptor) + sizer = encoder.MapSizer(field_descriptor, + _IsMessageMapField(field_descriptor)) elif _IsMessageSetExtension(field_descriptor): field_encoder = encoder.MessageSetItemEncoder(field_descriptor.number) sizer = encoder.MessageSetItemSizer(field_descriptor.number) @@ -891,7 +892,7 @@ def _AddHasExtensionMethod(cls): def _InternalUnpackAny(msg): """Unpacks Any message and returns the unpacked message. - This internal method is differnt from public Any Unpack method which takes + This internal method is different from public Any Unpack method which takes the target message as argument. _InternalUnpackAny method does not have target message type and need to find the message type in descriptor pool. diff --git a/python/google/protobuf/internal/python_protobuf.cc b/python/google/protobuf/internal/python_protobuf.cc new file mode 100644 index 00000000..f90cc438 --- /dev/null +++ b/python/google/protobuf/internal/python_protobuf.cc @@ -0,0 +1,63 @@ +// 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: qrczak@google.com (Marcin Kowalczyk) + +#include + +namespace google { +namespace protobuf { +namespace python { + +static const Message* GetCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} +static Message* MutableCProtoInsidePyProtoStub(PyObject* msg) { + return NULL; +} + +// This is initialized with a default, stub implementation. +// If python-google.protobuf.cc is loaded, the function pointer is overridden +// with a full implementation. +const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg) = + GetCProtoInsidePyProtoStub; +Message* (*MutableCProtoInsidePyProtoPtr)(PyObject* msg) = + MutableCProtoInsidePyProtoStub; + +const Message* GetCProtoInsidePyProto(PyObject* msg) { + return GetCProtoInsidePyProtoPtr(msg); +} +Message* MutableCProtoInsidePyProto(PyObject* msg) { + return MutableCProtoInsidePyProtoPtr(msg); +} + +} // namespace python +} // namespace protobuf +} // namespace google diff --git a/python/google/protobuf/internal/reflection_test.py b/python/google/protobuf/internal/reflection_test.py index 0e881015..55b0d72e 100755 --- a/python/google/protobuf/internal/reflection_test.py +++ b/python/google/protobuf/internal/reflection_test.py @@ -1551,7 +1551,14 @@ class ReflectionTest(BaseTestCase): container = copy.deepcopy(proto1.repeated_int32) self.assertEqual([2, 3], container) - # TODO(anuraag): Implement deepcopy for repeated composite / extension dict + message1 = proto1.repeated_nested_message.add() + message1.bb = 1 + messages = copy.deepcopy(proto1.repeated_nested_message) + self.assertEqual(proto1.repeated_nested_message, messages) + message1.bb = 2 + self.assertNotEqual(proto1.repeated_nested_message, messages) + + # TODO(anuraag): Implement deepcopy for extension dict def testClear(self): proto = unittest_pb2.TestAllTypes() diff --git a/python/google/protobuf/internal/symbol_database_test.py b/python/google/protobuf/internal/symbol_database_test.py index 4f5173b2..af42681a 100644 --- a/python/google/protobuf/internal/symbol_database_test.py +++ b/python/google/protobuf/internal/symbol_database_test.py @@ -60,6 +60,7 @@ class SymbolDatabaseTest(unittest.TestCase): db.RegisterMessage(unittest_pb2.TestAllTypes.RepeatedGroup) db.RegisterEnumDescriptor(unittest_pb2.ForeignEnum.DESCRIPTOR) db.RegisterEnumDescriptor(unittest_pb2.TestAllTypes.NestedEnum.DESCRIPTOR) + db.RegisterServiceDescriptor(unittest_pb2._TESTSERVICE) return db def testGetPrototype(self): @@ -109,7 +110,13 @@ class SymbolDatabaseTest(unittest.TestCase): self._Database().pool.FindMessageTypeByName( 'protobuf_unittest.TestAllTypes.NestedMessage').full_name) - def testFindFindContainingSymbol(self): + def testFindServiceByName(self): + self.assertEqual( + 'protobuf_unittest.TestService', + self._Database().pool.FindServiceByName( + 'protobuf_unittest.TestService').full_name) + + def testFindFileContainingSymbol(self): # Lookup based on either enum or message. self.assertEqual( 'google/protobuf/unittest.proto', diff --git a/python/google/protobuf/internal/text_format_test.py b/python/google/protobuf/internal/text_format_test.py index 176cbd15..188310b2 100755 --- a/python/google/protobuf/internal/text_format_test.py +++ b/python/google/protobuf/internal/text_format_test.py @@ -1119,6 +1119,11 @@ class Proto3Tests(unittest.TestCase): packed_message = unittest_pb2.OneString() message.any_value.Unpack(packed_message) self.assertEqual('string', packed_message.data) + message.Clear() + text_format.Parse(text, message, descriptor_pool=descriptor_pool.Default()) + packed_message = unittest_pb2.OneString() + message.any_value.Unpack(packed_message) + self.assertEqual('string', packed_message.data) def testMergeExpandedAnyRepeated(self): message = any_test_pb2.TestAny() @@ -1373,6 +1378,52 @@ class TokenizerTest(unittest.TestCase): self.assertEqual('# some comment', tokenizer.ConsumeComment()) self.assertTrue(tokenizer.AtEnd()) + def testConsumeLineComment(self): + tokenizer = text_format.Tokenizer('# some comment'.splitlines(), + skip_comments=False) + self.assertFalse(tokenizer.AtEnd()) + self.assertEqual((False, '# some comment'), + tokenizer.ConsumeCommentOrTrailingComment()) + self.assertTrue(tokenizer.AtEnd()) + + def testConsumeTwoLineComments(self): + text = '# some comment\n# another comment' + tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False) + self.assertEqual((False, '# some comment'), + tokenizer.ConsumeCommentOrTrailingComment()) + self.assertFalse(tokenizer.AtEnd()) + self.assertEqual((False, '# another comment'), + tokenizer.ConsumeCommentOrTrailingComment()) + self.assertTrue(tokenizer.AtEnd()) + + def testConsumeAndCheckTrailingComment(self): + text = 'some_number: 4 # some comment' # trailing comment on the same line + tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False) + self.assertRaises(text_format.ParseError, + tokenizer.ConsumeCommentOrTrailingComment) + + self.assertEqual('some_number', tokenizer.ConsumeIdentifier()) + self.assertEqual(tokenizer.token, ':') + tokenizer.NextToken() + self.assertRaises(text_format.ParseError, + tokenizer.ConsumeCommentOrTrailingComment) + self.assertEqual(4, tokenizer.ConsumeInteger()) + self.assertFalse(tokenizer.AtEnd()) + + self.assertEqual((True, '# some comment'), + tokenizer.ConsumeCommentOrTrailingComment()) + self.assertTrue(tokenizer.AtEnd()) + + def testHashinComment(self): + text = 'some_number: 4 # some comment # not a new comment' + tokenizer = text_format.Tokenizer(text.splitlines(), skip_comments=False) + self.assertEqual('some_number', tokenizer.ConsumeIdentifier()) + self.assertEqual(tokenizer.token, ':') + tokenizer.NextToken() + self.assertEqual(4, tokenizer.ConsumeInteger()) + self.assertEqual((True, '# some comment # not a new comment'), + tokenizer.ConsumeCommentOrTrailingComment()) + self.assertTrue(tokenizer.AtEnd()) if __name__ == '__main__': unittest.main() diff --git a/python/google/protobuf/pyext/descriptor.cc b/python/google/protobuf/pyext/descriptor.cc index 924ae0b9..f13e1bc1 100644 --- a/python/google/protobuf/pyext/descriptor.cc +++ b/python/google/protobuf/pyext/descriptor.cc @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -1666,6 +1667,15 @@ PyObject* PyServiceDescriptor_FromDescriptor( &PyServiceDescriptor_Type, service_descriptor, NULL); } +const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj) { + if (!PyObject_TypeCheck(obj, &PyServiceDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Not a ServiceDescriptor"); + return NULL; + } + return reinterpret_cast( + reinterpret_cast(obj)->descriptor); +} + namespace method_descriptor { // Unchecked accessor to the C++ pointer. @@ -1769,6 +1779,15 @@ PyObject* PyMethodDescriptor_FromDescriptor( &PyMethodDescriptor_Type, method_descriptor, NULL); } +const MethodDescriptor* PyMethodDescriptor_AsDescriptor(PyObject* obj) { + if (!PyObject_TypeCheck(obj, &PyMethodDescriptor_Type)) { + PyErr_SetString(PyExc_TypeError, "Not a MethodDescriptor"); + return NULL; + } + return reinterpret_cast( + reinterpret_cast(obj)->descriptor); +} + // Add a enum values to a type dictionary. static bool AddEnumValues(PyTypeObject *type, const EnumDescriptor* enum_descriptor) { diff --git a/python/google/protobuf/pyext/descriptor.h b/python/google/protobuf/pyext/descriptor.h index 1ae0e672..f081df84 100644 --- a/python/google/protobuf/pyext/descriptor.h +++ b/python/google/protobuf/pyext/descriptor.h @@ -80,6 +80,8 @@ const Descriptor* PyMessageDescriptor_AsDescriptor(PyObject* obj); const FieldDescriptor* PyFieldDescriptor_AsDescriptor(PyObject* obj); const EnumDescriptor* PyEnumDescriptor_AsDescriptor(PyObject* obj); const FileDescriptor* PyFileDescriptor_AsDescriptor(PyObject* obj); +const ServiceDescriptor* PyServiceDescriptor_AsDescriptor(PyObject* obj); +const MethodDescriptor* PyMethodDescriptor_AsDescriptor(PyObject* obj); // Returns the raw C++ pointer. const void* PyDescriptor_AsVoidPtr(PyObject* obj); diff --git a/python/google/protobuf/pyext/descriptor_pool.cc b/python/google/protobuf/pyext/descriptor_pool.cc index fa66bf9a..16f4d49d 100644 --- a/python/google/protobuf/pyext/descriptor_pool.cc +++ b/python/google/protobuf/pyext/descriptor_pool.cc @@ -39,6 +39,7 @@ #include #include #include +#include #if PY_MAJOR_VERSION >= 3 #define PyString_FromStringAndSize PyUnicode_FromStringAndSize @@ -437,8 +438,23 @@ PyObject* AddExtensionDescriptor(PyDescriptorPool* self, PyObject* descriptor) { Py_RETURN_NONE; } -// The code below loads new Descriptors from a serialized FileDescriptorProto. +PyObject* AddServiceDescriptor(PyDescriptorPool* self, PyObject* descriptor) { + const ServiceDescriptor* service_descriptor = + PyServiceDescriptor_AsDescriptor(descriptor); + if (!service_descriptor) { + return NULL; + } + if (service_descriptor != + self->pool->FindServiceByName(service_descriptor->full_name())) { + PyErr_Format(PyExc_ValueError, + "The service descriptor %s does not belong to this pool", + service_descriptor->full_name().c_str()); + return NULL; + } + Py_RETURN_NONE; +} +// The code below loads new Descriptors from a serialized FileDescriptorProto. // Collects errors that occur during proto file building to allow them to be // propagated in the python exception instead of only living in ERROR logs. @@ -538,6 +554,8 @@ static PyMethodDef Methods[] = { "No-op. Add() must have been called before." }, { "AddExtensionDescriptor", (PyCFunction)AddExtensionDescriptor, METH_O, "No-op. Add() must have been called before." }, + { "AddServiceDescriptor", (PyCFunction)AddServiceDescriptor, METH_O, + "No-op. Add() must have been called before." }, { "FindFileByName", (PyCFunction)FindFileByName, METH_O, "Searches for a file descriptor by its .proto name." }, diff --git a/python/google/protobuf/pyext/descriptor_pool.h b/python/google/protobuf/pyext/descriptor_pool.h index c4d7d403..53ee53dc 100644 --- a/python/google/protobuf/pyext/descriptor_pool.h +++ b/python/google/protobuf/pyext/descriptor_pool.h @@ -85,6 +85,7 @@ extern PyTypeObject PyDescriptorPool_Type; namespace cdescriptor_pool { + // Looks up a message by name. // Returns a message Descriptor, or NULL if not found. const Descriptor* FindMessageTypeByName(PyDescriptorPool* self, diff --git a/python/google/protobuf/pyext/python_protobuf.h b/python/google/protobuf/pyext/python_protobuf.h deleted file mode 100644 index beb6e460..00000000 --- a/python/google/protobuf/pyext/python_protobuf.h +++ /dev/null @@ -1,57 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Author: qrczak@google.com (Marcin Kowalczyk) -// -// This module exposes the C proto inside the given Python proto, in -// case the Python proto is implemented with a C proto. - -#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ -#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ - -#include - -namespace google { -namespace protobuf { - -class Message; - -namespace python { - -// Return the pointer to the C proto inside the given Python proto, -// or NULL when this is not a Python proto implemented with a C proto. -const Message* GetCProtoInsidePyProto(PyObject* msg); -Message* MutableCProtoInsidePyProto(PyObject* msg); - -} // namespace python -} // namespace protobuf - -} // namespace google -#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ diff --git a/python/google/protobuf/pyext/repeated_composite_container.cc b/python/google/protobuf/pyext/repeated_composite_container.cc index 43a2bc12..9cb4e9a1 100644 --- a/python/google/protobuf/pyext/repeated_composite_container.cc +++ b/python/google/protobuf/pyext/repeated_composite_container.cc @@ -47,6 +47,7 @@ #include #include #include +#include #if PY_MAJOR_VERSION >= 3 #define PyInt_Check PyLong_Check @@ -485,6 +486,32 @@ int Release(RepeatedCompositeContainer* self) { return 0; } +PyObject* DeepCopy(RepeatedCompositeContainer* self, PyObject* arg) { + ScopedPyObjectPtr cloneObj( + PyType_GenericAlloc(&RepeatedCompositeContainer_Type, 0)); + if (cloneObj == NULL) { + return NULL; + } + RepeatedCompositeContainer* clone = + reinterpret_cast(cloneObj.get()); + + Message* new_message = self->message->New(); + clone->parent = NULL; + clone->parent_field_descriptor = self->parent_field_descriptor; + clone->message = new_message; + clone->owner.reset(new_message); + Py_INCREF(self->child_message_class); + clone->child_message_class = self->child_message_class; + clone->child_messages = PyList_New(0); + + new_message->GetReflection() + ->GetMutableRepeatedFieldRef(new_message, + self->parent_field_descriptor) + .MergeFrom(self->message->GetReflection()->GetRepeatedFieldRef( + *self->message, self->parent_field_descriptor)); + return cloneObj.release(); +} + int SetOwner(RepeatedCompositeContainer* self, const shared_ptr& new_owner) { GOOGLE_CHECK_ATTACHED(self); @@ -551,6 +578,8 @@ static PyMappingMethods MpMethods = { }; static PyMethodDef Methods[] = { + { "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS, + "Makes a deep copy of the class." }, { "add", (PyCFunction) Add, METH_VARARGS | METH_KEYWORDS, "Adds an object to the repeated container." }, { "extend", (PyCFunction) Extend, METH_O, diff --git a/python/google/protobuf/pyext/scoped_pyobject_ptr.h b/python/google/protobuf/pyext/scoped_pyobject_ptr.h index a128cd4c..a2afa7f1 100644 --- a/python/google/protobuf/pyext/scoped_pyobject_ptr.h +++ b/python/google/protobuf/pyext/scoped_pyobject_ptr.h @@ -36,61 +36,70 @@ #include #include - namespace google { -class ScopedPyObjectPtr { +namespace protobuf { +namespace python { + +// Owns a python object and decrements the reference count on destruction. +// This class is not threadsafe. +template +class ScopedPythonPtr { public: - // Constructor. Defaults to initializing with NULL. - // There is no way to create an uninitialized ScopedPyObjectPtr. - explicit ScopedPyObjectPtr(PyObject* p = NULL) : ptr_(p) { } + // Takes the ownership of the specified object to ScopedPythonPtr. + // The reference count of the specified py_object is not incremented. + explicit ScopedPythonPtr(PyObjectStruct* py_object = NULL) + : ptr_(py_object) {} - // Destructor. If there is a PyObject object, delete it. - ~ScopedPyObjectPtr() { - Py_XDECREF(ptr_); - } + // If a PyObject is owned, decrement its reference count. + ~ScopedPythonPtr() { Py_XDECREF(ptr_); } - // Reset. Deletes the current owned object, if any. - // Then takes ownership of a new object, if given. + // Deletes the current owned object, if any. + // Then takes ownership of a new object without incrementing the reference + // count. // This function must be called with a reference that you own. // this->reset(this->get()) is wrong! // this->reset(this->release()) is OK. - PyObject* reset(PyObject* p = NULL) { + PyObjectStruct* reset(PyObjectStruct* p = NULL) { Py_XDECREF(ptr_); ptr_ = p; return ptr_; } - // Releases ownership of the object. + // Releases ownership of the object without decrementing the reference count. // The caller now owns the returned reference. - PyObject* release() { + PyObjectStruct* release() { PyObject* p = ptr_; ptr_ = NULL; return p; } - PyObject* operator->() const { + PyObjectStruct* operator->() const { assert(ptr_ != NULL); return ptr_; } - PyObject* get() const { return ptr_; } + PyObjectStruct* get() const { return ptr_; } - Py_ssize_t refcnt() const { return Py_REFCNT(ptr_); } + PyObject* as_pyobject() const { return reinterpret_cast(ptr_); } + // Increments the reference count fo the current object. + // Should not be called when no object is held. void inc() const { Py_INCREF(ptr_); } - // Comparison operators. - // These return whether a ScopedPyObjectPtr and a raw pointer - // refer to the same object, not just to two different but equal - // objects. - bool operator==(const PyObject* p) const { return ptr_ == p; } - bool operator!=(const PyObject* p) const { return ptr_ != p; } + // True when a ScopedPyObjectPtr and a raw pointer refer to the same object. + // Comparison operators are non reflexive. + bool operator==(const PyObjectStruct* p) const { return ptr_ == p; } + bool operator!=(const PyObjectStruct* p) const { return ptr_ != p; } private: - PyObject* ptr_; + PyObjectStruct* ptr_; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPyObjectPtr); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ScopedPythonPtr); }; +typedef ScopedPythonPtr ScopedPyObjectPtr; + +} // namespace python +} // namespace protobuf } // namespace google #endif // GOOGLE_PROTOBUF_PYTHON_CPP_SCOPED_PYOBJECT_PTR_H__ diff --git a/python/google/protobuf/python_protobuf.h b/python/google/protobuf/python_protobuf.h new file mode 100644 index 00000000..beb6e460 --- /dev/null +++ b/python/google/protobuf/python_protobuf.h @@ -0,0 +1,57 @@ +// 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: qrczak@google.com (Marcin Kowalczyk) +// +// This module exposes the C proto inside the given Python proto, in +// case the Python proto is implemented with a C proto. + +#ifndef GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ +#define GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ + +#include + +namespace google { +namespace protobuf { + +class Message; + +namespace python { + +// Return the pointer to the C proto inside the given Python proto, +// or NULL when this is not a Python proto implemented with a C proto. +const Message* GetCProtoInsidePyProto(PyObject* msg); +Message* MutableCProtoInsidePyProto(PyObject* msg); + +} // namespace python +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_PYTHON_PYTHON_PROTOBUF_H__ diff --git a/python/google/protobuf/reflection.py b/python/google/protobuf/reflection.py index 05bafd69..f4ce8caf 100755 --- a/python/google/protobuf/reflection.py +++ b/python/google/protobuf/reflection.py @@ -107,7 +107,7 @@ def MakeClass(descriptor): The Message class object described by the descriptor. """ if descriptor in MESSAGE_CLASS_CACHE: - return MESSAGE_CLASS_CACHE[descriptor] + return MESSAGE_CLASS_CACHE[descriptor] attributes = {} for name, nested_type in descriptor.nested_types_by_name.items(): @@ -115,7 +115,7 @@ def MakeClass(descriptor): attributes[GeneratedProtocolMessageType._DESCRIPTOR_KEY] = descriptor - result = GeneratedProtocolMessageType(str(descriptor.name), (message.Message,), - attributes) + result = GeneratedProtocolMessageType( + str(descriptor.name), (message.Message,), attributes) MESSAGE_CLASS_CACHE[descriptor] = result return result diff --git a/python/google/protobuf/symbol_database.py b/python/google/protobuf/symbol_database.py index ecbef211..07341efa 100644 --- a/python/google/protobuf/symbol_database.py +++ b/python/google/protobuf/symbol_database.py @@ -94,6 +94,17 @@ class SymbolDatabase(message_factory.MessageFactory): self.pool.AddEnumDescriptor(enum_descriptor) return enum_descriptor + def RegisterServiceDescriptor(self, service_descriptor): + """Registers the given service descriptor in the local database. + + Args: + service_descriptor: a descriptor.ServiceDescriptor. + + Returns: + The provided descriptor. + """ + self.pool.AddServiceDescriptor(service_descriptor) + def RegisterFileDescriptor(self, file_descriptor): """Registers the given file descriptor in the local database. diff --git a/python/google/protobuf/text_format.py b/python/google/protobuf/text_format.py index 90f6ce42..c216e097 100755 --- a/python/google/protobuf/text_format.py +++ b/python/google/protobuf/text_format.py @@ -422,7 +422,8 @@ class _Printer(object): def Parse(text, message, allow_unknown_extension=False, - allow_field_number=False): + allow_field_number=False, + descriptor_pool=None): """Parses a text representation of a protocol message into a message. Args: @@ -431,6 +432,7 @@ def Parse(text, allow_unknown_extension: if True, skip over missing extensions and keep parsing allow_field_number: if True, both field number and field name are allowed. + descriptor_pool: A DescriptorPool used to resolve Any types. Returns: The same message passed as argument. @@ -440,8 +442,11 @@ def Parse(text, """ if not isinstance(text, str): text = text.decode('utf-8') - return ParseLines( - text.split('\n'), message, allow_unknown_extension, allow_field_number) + return ParseLines(text.split('\n'), + message, + allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool) def Merge(text, @@ -479,7 +484,8 @@ def Merge(text, def ParseLines(lines, message, allow_unknown_extension=False, - allow_field_number=False): + allow_field_number=False, + descriptor_pool=None): """Parses a text representation of a protocol message into a message. Args: @@ -496,7 +502,9 @@ def ParseLines(lines, Raises: ParseError: On text parsing problems. """ - parser = _Parser(allow_unknown_extension, allow_field_number) + parser = _Parser(allow_unknown_extension, + allow_field_number, + descriptor_pool=descriptor_pool) return parser.ParseLines(lines, message) @@ -513,6 +521,7 @@ def MergeLines(lines, allow_unknown_extension: if True, skip over missing extensions and keep parsing allow_field_number: if True, both field number and field name are allowed. + descriptor_pool: A DescriptorPool used to resolve Any types. Returns: The same message passed as argument. @@ -1023,6 +1032,22 @@ class Tokenizer(object): self.NextToken() return result + def ConsumeCommentOrTrailingComment(self): + """Consumes a comment, returns a 2-tuple (trailing bool, comment str).""" + + # Tokenizer initializes _previous_line and _previous_column to 0. As the + # tokenizer starts, it looks like there is a previous token on the line. + just_started = self._line == 0 and self._column == 0 + + before_parsing = self._previous_line + comment = self.ConsumeComment() + + # A trailing comment is a comment on the same line than the previous token. + trailing = (self._previous_line == before_parsing + and not just_started) + + return trailing, comment + def TryConsumeIdentifier(self): try: self.ConsumeIdentifier() diff --git a/src/Makefile.am b/src/Makefile.am index bcd81576..34abfcab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,18 +37,19 @@ protodir = $(includedir) # If you are adding new files here, also remember to change the build files for # all other languages, //protoc-artifacts/build-zip.sh and run # //update_file_list.sh for bazel. -nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ - google/protobuf/any.proto \ - google/protobuf/api.proto \ - google/protobuf/duration.proto \ - google/protobuf/empty.proto \ - google/protobuf/field_mask.proto \ - google/protobuf/source_context.proto \ - google/protobuf/struct.proto \ - google/protobuf/timestamp.proto \ - google/protobuf/type.proto \ - google/protobuf/wrappers.proto \ - google/protobuf/compiler/plugin.proto +nobase_dist_proto_DATA = google/protobuf/descriptor.proto \ + google/protobuf/any.proto \ + google/protobuf/api.proto \ + google/protobuf/duration.proto \ + google/protobuf/empty.proto \ + google/protobuf/field_mask.proto \ + google/protobuf/source_context.proto \ + google/protobuf/struct.proto \ + google/protobuf/timestamp.proto \ + google/protobuf/type.proto \ + google/protobuf/wrappers.proto \ + google/protobuf/compiler/plugin.proto \ + google/protobuf/compiler/profile.proto # Not sure why these don't get cleaned automatically. clean-local: @@ -155,6 +156,7 @@ nobase_include_HEADERS = \ google/protobuf/compiler/parser.h \ google/protobuf/compiler/plugin.h \ google/protobuf/compiler/plugin.pb.h \ + google/protobuf/compiler/profile.pb.h \ google/protobuf/compiler/cpp/cpp_generator.h \ google/protobuf/compiler/csharp/csharp_generator.h \ google/protobuf/compiler/csharp/csharp_names.h \ @@ -324,6 +326,7 @@ libprotoc_la_SOURCES = \ google/protobuf/compiler/command_line_interface.cc \ google/protobuf/compiler/plugin.cc \ google/protobuf/compiler/plugin.pb.cc \ + google/protobuf/compiler/profile.pb.cc \ google/protobuf/compiler/subprocess.cc \ google/protobuf/compiler/subprocess.h \ google/protobuf/compiler/zip_writer.cc \ @@ -535,6 +538,9 @@ protoc_inputs = \ google/protobuf/unittest_import.proto \ google/protobuf/unittest_import_public_lite.proto \ google/protobuf/unittest_import_public.proto \ + google/protobuf/unittest_lazy_dependencies.proto \ + google/protobuf/unittest_lazy_dependencies_custom_option.proto \ + google/protobuf/unittest_lazy_dependencies_enum.proto \ google/protobuf/unittest_lite_imports_nonlite.proto \ google/protobuf/unittest_lite.proto \ google/protobuf/unittest_mset.proto \ @@ -639,6 +645,12 @@ protoc_outputs = \ google/protobuf/unittest_import.pb.h \ google/protobuf/unittest_import_public.pb.cc \ google/protobuf/unittest_import_public.pb.h \ + google/protobuf/unittest_lazy_dependencies.pb.cc \ + google/protobuf/unittest_lazy_dependencies.pb.h \ + google/protobuf/unittest_lazy_dependencies_custom_option.pb.cc \ + google/protobuf/unittest_lazy_dependencies_custom_option.pb.h \ + google/protobuf/unittest_lazy_dependencies_enum.pb.cc \ + google/protobuf/unittest_lazy_dependencies_enum.pb.h \ google/protobuf/unittest_lite_imports_nonlite.pb.cc \ google/protobuf/unittest_lite_imports_nonlite.pb.h \ google/protobuf/unittest_mset.pb.cc \ @@ -847,7 +859,12 @@ COMMON_LITE_TEST_SOURCES = \ # 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_LDADD = $(PTHREAD_LIBS) libprotobuf-lite.la \ + ../gmock/gtest/lib/libgtest.la \ + ../gmock/lib/libgmock.la \ + ../gmock/lib/libgmock_main.la +protobuf_lite_test_CPPFLAGS= -I$(srcdir)/../gmock/include \ + -I$(srcdir)/../gmock/gtest/include protobuf_lite_test_CXXFLAGS = $(NO_OPT_CXXFLAGS) protobuf_lite_test_SOURCES = \ google/protobuf/lite_unittest.cc \ diff --git a/src/google/protobuf/any.h b/src/google/protobuf/any.h index 04e54166..c2c27ec3 100644 --- a/src/google/protobuf/any.h +++ b/src/google/protobuf/any.h @@ -63,7 +63,7 @@ class LIBPROTOBUF_EXPORT AnyMetadata { // Unpacks the payload into the given message. Returns false if the message's // type doesn't match the type specified in the type URL (i.e., the full - // name after the last "/" of the type URL doesn't match the message's actaul + // name after the last "/" of the type URL doesn't match the message's actual // full name) or parsing the payload has failed. bool UnpackTo(Message* message) const; @@ -90,8 +90,8 @@ extern const char kTypeGoogleProdComPrefix[]; // "type.googleprod.com/". // Get the proto type name from Any::type_url value. For example, passing // "type.googleapis.com/rpc.QueryOrigin" will return "rpc.QueryOrigin" in -// *full_type_name. Returns false if type_url does not start with -// "type.googleapis.com" or "type.googleprod.com". +// *full_type_name. Returns false if the type_url does not have a "/" +// in the type url separating the full type name. bool ParseAnyTypeUrl(const string& type_url, string* full_type_name); // See if message is of type google.protobuf.Any, if so, return the descriptors diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 94c9539f..6c80aaa2 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, type_url_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Any, value_), }; @@ -186,7 +201,7 @@ void Any::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Any::descriptor() { protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Any& Any::default_instance() { @@ -270,6 +285,9 @@ failure: void Any::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Any) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string type_url = 1; if (this->type_url().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -291,8 +309,10 @@ void Any::SerializeWithCachedSizes( ::google::protobuf::uint8* Any::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Any) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string type_url = 1; if (this->type_url().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -359,6 +379,9 @@ void Any::MergeFrom(const Any& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Any) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.type_url().size() > 0) { type_url_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_url_); @@ -399,7 +422,7 @@ void Any::InternalSwap(Any* other) { ::google::protobuf::Metadata Any::GetMetadata() const { protobuf_google_2fprotobuf_2fany_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fany_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -427,6 +450,7 @@ void Any::set_type_url(::std::string&& value) { } #endif void Any::set_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) @@ -479,6 +503,7 @@ void Any::set_value(::std::string&& value) { } #endif void Any::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 1a61d5af..e5051c79 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fany_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -73,6 +77,8 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in return reinterpret_cast( &_Any_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; // implements Any ----------------------------------------------- @@ -105,11 +111,6 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -167,7 +168,7 @@ class LIBPROTOBUF_EXPORT Any : public ::google::protobuf::Message /* @@protoc_in ::google::protobuf::internal::ArenaStringPtr value_; mutable int _cached_size_; ::google::protobuf::internal::AnyMetadata _any_metadata_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fany_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fany_2eproto::TableStruct; }; // =================================================================== @@ -199,6 +200,7 @@ inline void Any::set_type_url(::std::string&& value) { } #endif inline void Any::set_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.type_url) @@ -251,6 +253,7 @@ inline void Any::set_value(::std::string&& value) { } #endif inline void Any::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Any.value) diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 6518e518..94c6685f 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -35,11 +35,28 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, methods_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Api, options_), @@ -51,6 +68,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Method, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ 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_), @@ -62,14 +80,15 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Mixin, root_), }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { { 0, -1, sizeof(Api)}, - { 11, -1, sizeof(Method)}, - { 22, -1, sizeof(Mixin)}, + { 12, -1, sizeof(Method)}, + { 24, -1, sizeof(Mixin)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -246,7 +265,7 @@ void Api::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Api::descriptor() { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Api& Api::default_instance() { @@ -306,13 +325,11 @@ bool Api::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_methods())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -320,13 +337,11 @@ bool Api::MergePartialFromCodedStream( case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(26u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -362,13 +377,11 @@ bool Api::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(50u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_mixins())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -411,6 +424,9 @@ failure: void Api::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Api) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -466,8 +482,10 @@ void Api::SerializeWithCachedSizes( ::google::protobuf::uint8* Api::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Api) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -483,14 +501,14 @@ void Api::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->methods_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->methods(i), false, target); + 2, this->methods(i), deterministic, target); } // repeated .google.protobuf.Option options = 3; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, this->options(i), false, target); + 3, this->options(i), deterministic, target); } // string version = 4; @@ -508,14 +526,14 @@ void Api::SerializeWithCachedSizes( if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 5, *this->source_context_, false, target); + 5, *this->source_context_, deterministic, target); } // repeated .google.protobuf.Mixin mixins = 6; for (unsigned int i = 0, n = this->mixins_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 6, this->mixins(i), false, target); + 6, this->mixins(i), deterministic, target); } // .google.protobuf.Syntax syntax = 7; @@ -618,6 +636,9 @@ void Api::MergeFrom(const Api& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Api) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + methods_.MergeFrom(from.methods_); options_.MergeFrom(from.options_); mixins_.MergeFrom(from.mixins_); @@ -660,9 +681,9 @@ void Api::Swap(Api* other) { InternalSwap(other); } void Api::InternalSwap(Api* other) { - methods_.UnsafeArenaSwap(&other->methods_); - options_.UnsafeArenaSwap(&other->options_); - mixins_.UnsafeArenaSwap(&other->mixins_); + methods_.InternalSwap(&other->methods_); + options_.InternalSwap(&other->options_); + mixins_.InternalSwap(&other->mixins_); name_.Swap(&other->name_); version_.Swap(&other->version_); std::swap(source_context_, other->source_context_); @@ -672,7 +693,7 @@ void Api::InternalSwap(Api* other) { ::google::protobuf::Metadata Api::GetMetadata() const { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -700,6 +721,7 @@ void Api::set_name(::std::string&& value) { } #endif void Api::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) @@ -812,6 +834,7 @@ void Api::set_version(::std::string&& value) { } #endif void Api::set_version(const char* value) { + GOOGLE_DCHECK(value != NULL); version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) @@ -998,7 +1021,7 @@ void Method::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Method::descriptor() { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Method& Method::default_instance() { @@ -1114,13 +1137,11 @@ bool Method::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(50u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1163,6 +1184,9 @@ failure: void Method::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Method) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1220,8 +1244,10 @@ void Method::SerializeWithCachedSizes( ::google::protobuf::uint8* Method::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Method) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1269,7 +1295,7 @@ void Method::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 6, this->options(i), false, target); + 6, this->options(i), deterministic, target); } // .google.protobuf.Syntax syntax = 7; @@ -1360,6 +1386,9 @@ void Method::MergeFrom(const Method& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Method) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + options_.MergeFrom(from.options_); if (from.name().size() > 0) { @@ -1407,7 +1436,7 @@ void Method::Swap(Method* other) { InternalSwap(other); } void Method::InternalSwap(Method* other) { - options_.UnsafeArenaSwap(&other->options_); + options_.InternalSwap(&other->options_); name_.Swap(&other->name_); request_type_url_.Swap(&other->request_type_url_); response_type_url_.Swap(&other->response_type_url_); @@ -1419,7 +1448,7 @@ void Method::InternalSwap(Method* other) { ::google::protobuf::Metadata Method::GetMetadata() const { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1447,6 +1476,7 @@ void Method::set_name(::std::string&& value) { } #endif void Method::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) @@ -1499,6 +1529,7 @@ void Method::set_request_type_url(::std::string&& value) { } #endif void Method::set_request_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) @@ -1565,6 +1596,7 @@ void Method::set_response_type_url(::std::string&& value) { } #endif void Method::set_response_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) @@ -1709,7 +1741,7 @@ void Mixin::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Mixin::descriptor() { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Mixin& Mixin::default_instance() { @@ -1797,6 +1829,9 @@ failure: void Mixin::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Mixin) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1822,8 +1857,10 @@ void Mixin::SerializeWithCachedSizes( ::google::protobuf::uint8* Mixin::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Mixin) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -1894,6 +1931,9 @@ void Mixin::MergeFrom(const Mixin& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Mixin) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.name().size() > 0) { name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); @@ -1934,7 +1974,7 @@ void Mixin::InternalSwap(Mixin* other) { ::google::protobuf::Metadata Mixin::GetMetadata() const { protobuf_google_2fprotobuf_2fapi_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2fapi_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1962,6 +2002,7 @@ void Mixin::set_name(::std::string&& value) { } #endif void Mixin::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name) @@ -2014,6 +2055,7 @@ void Mixin::set_root(::std::string&& value) { } #endif void Mixin::set_root(const char* value) { + GOOGLE_DCHECK(value != NULL); root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root) diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 2eb571e6..5ddd78e7 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -69,6 +70,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fapi_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -98,6 +102,8 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in return reinterpret_cast( &_Api_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void Swap(Api* other); @@ -120,11 +126,6 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -237,7 +238,7 @@ class LIBPROTOBUF_EXPORT Api : public ::google::protobuf::Message /* @@protoc_in ::google::protobuf::SourceContext* source_context_; int syntax_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -260,6 +261,8 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc return reinterpret_cast( &_Method_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void Swap(Method* other); @@ -282,11 +285,6 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -392,7 +390,7 @@ class LIBPROTOBUF_EXPORT Method : public ::google::protobuf::Message /* @@protoc bool response_streaming_; int syntax_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -415,6 +413,8 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast( &_Mixin_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void Swap(Mixin* other); @@ -437,11 +437,6 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -498,7 +493,7 @@ class LIBPROTOBUF_EXPORT Mixin : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr root_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fapi_2eproto::TableStruct; }; // =================================================================== @@ -530,6 +525,7 @@ inline void Api::set_name(::std::string&& value) { } #endif inline void Api::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.name) @@ -642,6 +638,7 @@ inline void Api::set_version(::std::string&& value) { } #endif inline void Api::set_version(const char* value) { + GOOGLE_DCHECK(value != NULL); version_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Api.version) @@ -781,6 +778,7 @@ inline void Method::set_name(::std::string&& value) { } #endif inline void Method::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.name) @@ -833,6 +831,7 @@ inline void Method::set_request_type_url(::std::string&& value) { } #endif inline void Method::set_request_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); request_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.request_type_url) @@ -899,6 +898,7 @@ inline void Method::set_response_type_url(::std::string&& value) { } #endif inline void Method::set_response_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); response_type_url_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Method.response_type_url) @@ -1013,6 +1013,7 @@ inline void Mixin::set_name(::std::string&& value) { } #endif inline void Mixin::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.name) @@ -1065,6 +1066,7 @@ inline void Mixin::set_root(::std::string&& value) { } #endif inline void Mixin::set_root(const char* value) { + GOOGLE_DCHECK(value != NULL); root_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.Mixin.root) diff --git a/src/google/protobuf/arena.h b/src/google/protobuf/arena.h index 05e05ebc..b6a375ac 100644 --- a/src/google/protobuf/arena.h +++ b/src/google/protobuf/arena.h @@ -303,6 +303,17 @@ class LIBPROTOBUF_EXPORT Arena { // (unless the destructor is trivial). Hence, from T's point of view, it is as // if the object were allocated on the heap (except that the underlying memory // is obtained from the arena). +#if LANG_CXX11 + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + static T* Create(::google::protobuf::Arena* arena, Args&&... args) { + if (arena == NULL) { + return new T(std::forward(args)...); + } else { + return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, + std::forward(args)...); + } + } +#endif template GOOGLE_ATTRIBUTE_ALWAYS_INLINE static T* Create(::google::protobuf::Arena* arena) { if (arena == NULL) { @@ -322,17 +333,6 @@ class LIBPROTOBUF_EXPORT Arena { arg); } } -#if LANG_CXX11 - template GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static T* Create(::google::protobuf::Arena* arena, Arg&& arg) { - if (arena == NULL) { - return new T(std::move(arg)); - } else { - return arena->CreateInternal(google::protobuf::internal::has_trivial_destructor::value, - std::move(arg)); - } - } -#endif // Version of the above with two constructor arguments for the created object. template GOOGLE_ATTRIBUTE_ALWAYS_INLINE @@ -655,35 +655,34 @@ class LIBPROTOBUF_EXPORT Arena { AllocateAligned(RTTI_TYPE_ID(T), sizeof(T) * num_elements)); } - template GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateInternal(bool skip_explicit_ownership) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(); +#if LANG_CXX11 + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + T* CreateInternal(bool skip_explicit_ownership, Args&&... args) { + T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) + T(std::forward(args)...); if (!skip_explicit_ownership) { AddListNode(t, &internal::arena_destruct_object); } return t; } - - template GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateInternal(bool skip_explicit_ownership, const Arg& arg) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T(arg); +#endif + template GOOGLE_ATTRIBUTE_ALWAYS_INLINE + 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); } return t; } -#if LANG_CXX11 template GOOGLE_ATTRIBUTE_ALWAYS_INLINE - T* CreateInternal(bool skip_explicit_ownership, Arg&& arg) { - T* t = new (AllocateAligned(RTTI_TYPE_ID(T), sizeof(T))) T( - std::move(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); } return t; } -#endif template GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateInternal( @@ -796,22 +795,20 @@ class LIBPROTOBUF_EXPORT Arena { template GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(typename T::InternalArenaConstructable_*) { - return CreateInternal(SkipDeleteList(static_cast(0)), - this); + return CreateInternal(SkipDeleteList(static_cast(0)), this); } template GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(typename T::InternalArenaConstructable_*, const Arg& arg) { - return CreateInternal(SkipDeleteList(static_cast(0)), - this, arg); + return CreateInternal(SkipDeleteList(static_cast(0)), this, arg); } template GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* CreateMessageInternal(typename T::InternalArenaConstructable_*, const Arg1& arg1, const Arg2& arg2) { - return CreateInternal(SkipDeleteList(static_cast(0)), - this, arg1, arg2); + return CreateInternal(SkipDeleteList(static_cast(0)), this, arg1, + arg2); } // CreateInArenaStorage is used to implement map field. Without it, diff --git a/src/google/protobuf/arena_unittest.cc b/src/google/protobuf/arena_unittest.cc index 4f9571db..6172cade 100644 --- a/src/google/protobuf/arena_unittest.cc +++ b/src/google/protobuf/arena_unittest.cc @@ -180,6 +180,35 @@ TEST(ArenaTest, BasicCreate) { EXPECT_EQ(2, notifier.GetCount()); } +TEST(ArenaTest, CreateAndConstCopy) { + Arena arena; + const string s("foo"); + const string* s_copy = Arena::Create(&arena, s); + EXPECT_TRUE(s_copy != NULL); + EXPECT_EQ("foo", s); + EXPECT_EQ("foo", *s_copy); +} + +TEST(ArenaTest, CreateAndNonConstCopy) { + Arena arena; + string s("foo"); + const string* s_copy = Arena::Create(&arena, s); + EXPECT_TRUE(s_copy != NULL); + EXPECT_EQ("foo", s); + EXPECT_EQ("foo", *s_copy); +} + +#if LANG_CXX11 +TEST(ArenaTest, CreateAndMove) { + Arena arena; + string s("foo"); + const string* s_move = Arena::Create(&arena, std::move(s)); + EXPECT_TRUE(s_move != NULL); + EXPECT_TRUE(s.empty()); // NOLINT + EXPECT_EQ("foo", *s_move); +} +#endif + TEST(ArenaTest, CreateWithFourConstructorArguments) { Arena arena; const string three("3"); @@ -214,6 +243,29 @@ TEST(ArenaTest, CreateWithEightConstructorArguments) { ASSERT_EQ("8", new_object->eight_); } +#if LANG_CXX11 +class PleaseMoveMe { + public: + explicit PleaseMoveMe(const string& value) : value_(value) {} + PleaseMoveMe(PleaseMoveMe&&) = default; + PleaseMoveMe(const PleaseMoveMe&) = delete; + + const string& value() const { return value_; } + + private: + string value_; +}; + +TEST(ArenaTest, CreateWithMoveArguments) { + Arena arena; + PleaseMoveMe one("1"); + const PleaseMoveMe* new_object = + Arena::Create(&arena, std::move(one)); + EXPECT_TRUE(new_object); + ASSERT_EQ("1", new_object->value()); +} +#endif + TEST(ArenaTest, InitialBlockTooSmall) { // Construct a small (64 byte) initial block of memory to be used by the // arena allocator; then, allocate an object which will not fit in the diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc index f10732c0..7f33a0c8 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -38,16 +38,6 @@ namespace protobuf { namespace internal { -void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value, - ArenaStringPtr value) { - const ::std::string* me = *UnsafeRawStringPointer(); - const ::std::string* other = *value.UnsafeRawStringPointer(); - // If the pointers are the same then do nothing. - if (me != other) { - SetNoArena(default_value, value.GetNoArena()); - } -} - } // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/arenastring.h b/src/google/protobuf/arenastring.h index a7efb752..63fd00e5 100755 --- a/src/google/protobuf/arenastring.h +++ b/src/google/protobuf/arenastring.h @@ -310,5 +310,21 @@ struct LIBPROTOBUF_EXPORT ArenaStringPtr { +namespace protobuf { +namespace internal { + +inline void ArenaStringPtr::AssignWithDefault(const ::std::string* default_value, + ArenaStringPtr value) { + const ::std::string* me = *UnsafeRawStringPointer(); + const ::std::string* other = *value.UnsafeRawStringPointer(); + // If the pointers are the same then do nothing. + if (me != other) { + SetNoArena(default_value, value.GetNoArena()); + } +} + +} // namespace internal +} // namespace protobuf + } // namespace google #endif // GOOGLE_PROTOBUF_ARENASTRING_H__ diff --git a/src/google/protobuf/compiler/code_generator.h b/src/google/protobuf/compiler/code_generator.h index e2b2a661..b917d373 100644 --- a/src/google/protobuf/compiler/code_generator.h +++ b/src/google/protobuf/compiler/code_generator.h @@ -162,7 +162,7 @@ typedef GeneratorContext OutputDirectory; // "foo=bar,baz,qux=corge" // parses to the pairs: // ("foo", "bar"), ("baz", ""), ("qux", "corge") -extern void LIBPROTOC_EXPORT ParseGeneratorParameter(const string&, +extern void ParseGeneratorParameter(const string&, std::vector >*); } // namespace compiler diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index f516477b..30a79c5d 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -816,11 +816,11 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) { if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == direct_dependencies_.end()) { indirect_imports = true; - cerr << parsed_file->name() << ": " - << StringReplace(direct_dependencies_violation_msg_, "%s", - parsed_file->dependency(i)->name(), - true /* replace_all */) - << std::endl; + std::cerr << parsed_file->name() << ": " + << StringReplace(direct_dependencies_violation_msg_, "%s", + parsed_file->dependency(i)->name(), + true /* replace_all */) + << std::endl; } } if (indirect_imports) { @@ -1038,7 +1038,7 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { // Make sure each plugin option has a matching plugin output. bool foundUnknownPluginOption = false; - for (map::const_iterator i = plugin_parameters_.begin(); + for (std::map::const_iterator i = plugin_parameters_.begin(); i != plugin_parameters_.end(); ++i) { if (plugins_.find(i->first) != plugins_.end()) { continue; @@ -1221,7 +1221,8 @@ CommandLineInterface::InterpretArgument(const string& name, if (access(disk_path.c_str(), F_OK) < 0) { // Try the original path; it may have just happed to have a '=' in it. if (access(parts[i].c_str(), F_OK) < 0) { - cerr << disk_path << ": warning: directory does not exist." << endl; + std::cerr << disk_path << ": warning: directory does not exist." + << std::endl; } else { virtual_path = ""; disk_path = parts[i]; @@ -1391,6 +1392,7 @@ CommandLineInterface::InterpretArgument(const string& name, } mode_ = MODE_PRINT; print_mode_ = PRINT_FREE_FIELDS; + } else if (name == "--profile_path") { } else { // Some other flag. Look it up in the generators list. const GeneratorInfo* generator_info = @@ -1790,31 +1792,34 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) { } bool CommandLineInterface::WriteDescriptorSet( - const std::vector parsed_files) { + const std::vector& parsed_files) { FileDescriptorSet file_set; - if (imports_in_descriptor_set_) { - std::set already_seen; - for (int i = 0; i < parsed_files.size(); i++) { - GetTransitiveDependencies(parsed_files[i], - true, // Include json_name - source_info_in_descriptor_set_, - &already_seen, file_set.mutable_file()); - } - } else { - std::set already_seen; + std::set already_seen; + if (!imports_in_descriptor_set_) { + // Since we don't want to output transitive dependencies, but we do want + // things to be in dependency order, add all dependencies that aren't in + // parsed_files to already_seen. This will short circuit the recursion + // in GetTransitiveDependencies. + std::set to_output; + to_output.insert(parsed_files.begin(), parsed_files.end()); 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); - parsed_files[i]->CopyJsonNameTo(file_proto); - if (source_info_in_descriptor_set_) { - parsed_files[i]->CopySourceCodeInfoTo(file_proto); + const FileDescriptor* file = parsed_files[i]; + for (int i = 0; i < file->dependency_count(); i++) { + const FileDescriptor* dependency = file->dependency(i); + // if the dependency isn't in parsed files, mark it as already seen + if (to_output.find(dependency) == to_output.end()) { + already_seen.insert(dependency); + } } } } + for (int i = 0; i < parsed_files.size(); i++) { + GetTransitiveDependencies(parsed_files[i], + true, // Include json_name + source_info_in_descriptor_set_, + &already_seen, file_set.mutable_file()); + } int fd; do { diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 8f8c2682..997c1748 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -258,7 +258,7 @@ class LIBPROTOC_EXPORT CommandLineInterface { // Implements the --descriptor_set_out option. bool WriteDescriptorSet( - const std::vector parsed_files); + const std::vector& parsed_files); // Implements the --dependency_out option bool GenerateDependencyManifestFile( @@ -391,6 +391,11 @@ class LIBPROTOC_EXPORT CommandLineInterface { // dependency file will be written. Otherwise, empty. string dependency_out_name_; + // Path to a file that contains serialized AccessInfo which provides + // relative hotness of fields per message. This helps protoc to generate + // better code. + string profile_path_; + // True if --include_imports was given, meaning that we should // write all transitive dependencies to the DescriptorSet. Otherwise, only // the .proto files listed on the command-line are added. diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index eab14f60..366e623f 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -32,9 +32,9 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. -#include -#include #include +#include +#include #ifdef _MSC_VER #include #else @@ -46,25 +46,25 @@ #endif #include -#include -#include -#include -#include -#include +#include +#include #include #include #include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include +#include #include #include #include #include +#include namespace google { namespace protobuf { @@ -101,7 +101,7 @@ class CommandLineInterfaceTest : public testing::Test { // command is automatically split on spaces, and the string "$tmpdir" // is replaced with TestTempDir(). void Run(const string& command); - void RunWithArgs(vector args); + void RunWithArgs(std::vector args); // ----------------------------------------------------------------- // Methods to set up the test (called before Run()). @@ -301,7 +301,7 @@ void CommandLineInterfaceTest::Run(const string& command) { RunWithArgs(Split(command, " ", true)); } -void CommandLineInterfaceTest::RunWithArgs(vector args) { +void CommandLineInterfaceTest::RunWithArgs(std::vector args) { if (!disallow_plugins_) { cli_.AllowPlugins("prefix-"); #ifndef GOOGLE_THIRD_PARTY_PROTOBUF @@ -1044,7 +1044,7 @@ TEST_F(CommandLineInterfaceTest, DirectDependencies_CustomErrorMessage) { "syntax = \"proto2\";\n" "message Bar { optional string text = 1; }"); - vector commands; + std::vector commands; commands.push_back("protocol_compiler"); commands.push_back("--test_out=$tmpdir"); commands.push_back("--proto_path=$tmpdir"); @@ -1127,15 +1127,17 @@ TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithDuplicates) { 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()); + // foo should come first since the output is in dependency order. + // since bar and baz are unordered, they should be in command line order. + EXPECT_EQ("foo.proto", descriptor_set.file(0).name()); + EXPECT_EQ("bar.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()); // Descriptor set should have json_name. - EXPECT_EQ("Bar", descriptor_set.file(0).message_type(0).name()); - EXPECT_EQ("foo", descriptor_set.file(0).message_type(0).field(0).name()); - EXPECT_TRUE(descriptor_set.file(0).message_type(0).field(0).has_json_name()); + EXPECT_EQ("Bar", descriptor_set.file(1).message_type(0).name()); + EXPECT_EQ("foo", descriptor_set.file(1).message_type(0).field(0).name()); + EXPECT_TRUE(descriptor_set.file(1).message_type(0).field(0).has_json_name()); } TEST_F(CommandLineInterfaceTest, WriteDescriptorSetWithSourceInfo) { diff --git a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc index bf4e5831..fce58c02 100644 --- a/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_bootstrap_unittest.cc @@ -46,12 +46,11 @@ #include #include -#include #include +#include +#include #include #include -#include -#include #include #include @@ -126,9 +125,12 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { importer.Import("google/protobuf/descriptor.proto"); const FileDescriptor* plugin_proto_file = importer.Import("google/protobuf/compiler/plugin.proto"); + const FileDescriptor* profile_proto_file = + importer.Import("google/protobuf/compiler/profile.proto"); EXPECT_EQ("", error_collector.text_); ASSERT_TRUE(proto_file != NULL); ASSERT_TRUE(plugin_proto_file != NULL); + ASSERT_TRUE(profile_proto_file != NULL); CppGenerator generator; MockGeneratorContext context; @@ -139,6 +141,8 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { parameter = "dllexport_decl=LIBPROTOC_EXPORT"; ASSERT_TRUE(generator.Generate(plugin_proto_file, parameter, &context, &error)); + ASSERT_TRUE(generator.Generate(profile_proto_file, parameter, + &context, &error)); context.ExpectFileMatches("google/protobuf/descriptor.pb.h", "google/protobuf/descriptor.pb.h"); @@ -148,6 +152,10 @@ TEST(BootstrapTest, GeneratedDescriptorMatches) { "google/protobuf/compiler/plugin.pb.h"); context.ExpectFileMatches("google/protobuf/compiler/plugin.pb.cc", "google/protobuf/compiler/plugin.pb.cc"); + context.ExpectFileMatches("google/protobuf/compiler/profile.pb.h", + "google/protobuf/compiler/profile.pb.h"); + context.ExpectFileMatches("google/protobuf/compiler/profile.pb.cc", + "google/protobuf/compiler/profile.pb.cc"); } } // namespace diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index e4b17a98..c15be942 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -318,7 +318,7 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedEnumFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n"); + printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); } void RepeatedEnumFieldGenerator:: @@ -461,20 +461,14 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { " target);\n" " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(" " _$name$_cached_byte_size_, target);\n" - "}\n"); - } - printer->Print(variables_, - "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"); - if (descriptor_->is_packed()) { - printer->Print(variables_, " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n" - " this->$name$(i), target);\n"); + " this->$name$_, target);\n" + "}\n"); } else { printer->Print(variables_, - " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n" - " $number$, this->$name$(i), target);\n"); + "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n" + " $number$, this->$name$_, target);\n"); } - printer->Print("}\n"); } void RepeatedEnumFieldGenerator:: diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index f2e013c0..83e68c12 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -39,6 +39,7 @@ #include #endif #include +#include #include #include @@ -67,7 +68,7 @@ bool IsMacroName(const string& name) { return false; } -void CollectMacroNames(const Descriptor* message, vector* names) { +void CollectMacroNames(const Descriptor* message, std::vector* names) { for (int i = 0; i < message->field_count(); ++i) { const FieldDescriptor* field = message->field(i); if (IsMacroName(field->name())) { @@ -79,7 +80,13 @@ void CollectMacroNames(const Descriptor* message, vector* names) { } } -void CollectMacroNames(const FileDescriptor* file, vector* names) { +void CollectMacroNames(const FileDescriptor* file, std::vector* names) { + // Only do this for protobuf's own types. There are some google3 protos using + // macros as field names and the generated code compiles after the macro + // expansion. Undefing these macros actually breaks such code. + if (file->name() != "google/protobuf/compiler/plugin.proto") { + return; + } for (int i = 0; i < file->message_type_count(); ++i) { CollectMacroNames(file->message_type(i), names); } @@ -93,18 +100,19 @@ void CollectMacroNames(const FileDescriptor* file, vector* names) { FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) : file_(file), options_(options), + scc_analyzer_(options), message_generators_owner_( - new google::protobuf::scoped_ptr[ file->message_type_count() ]), + new google::protobuf::scoped_ptr[file->message_type_count()]), enum_generators_owner_( - new google::protobuf::scoped_ptr[ file->enum_type_count() ]), + new google::protobuf::scoped_ptr[file->enum_type_count()]), service_generators_owner_( - new google::protobuf::scoped_ptr[ file->service_count() ]), + new google::protobuf::scoped_ptr[file->service_count()]), extension_generators_owner_( - new google::protobuf::scoped_ptr[ file->extension_count() ]) { + new google::protobuf::scoped_ptr[file->extension_count()]) { for (int i = 0; i < file->message_type_count(); i++) { message_generators_owner_[i].reset( - new MessageGenerator(file->message_type(i), options)); + new MessageGenerator(file->message_type(i), options, &scc_analyzer_)); message_generators_owner_[i]->Flatten(&message_generators_); } @@ -137,7 +145,7 @@ FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) FileGenerator::~FileGenerator() {} void FileGenerator::GenerateMacroUndefs(io::Printer* printer) { - vector names_to_undef; + std::vector names_to_undef; CollectMacroNames(file_, &names_to_undef); for (int i = 0; i < names_to_undef.size(); ++i) { printer->Print( @@ -241,6 +249,7 @@ void FileGenerator::GeneratePBHeader(io::Printer* printer, } else { GenerateLibraryIncludes(printer); } + GenerateDependencyIncludes(printer); GenerateMetadataPragma(printer, info_path); @@ -327,11 +336,17 @@ void FileGenerator::GenerateSource(io::Printer* printer) { GenerateNamespaceOpeners(printer); for (int i = 0; i < message_generators_.size(); i++) { - if (IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; + string parent; + if (IsMapEntryMessage(message_generators_[i]->descriptor_)) { + parent = ClassName(message_generators_[i]->descriptor_->containing_type(), + false) + + "::"; + } printer->Print( "class $classname$DefaultTypeInternal : " - "public ::google::protobuf::internal::ExplicitlyConstructed<$classname$> {\n", - "classname", message_generators_[i]->classname_); + "public ::google::protobuf::internal::ExplicitlyConstructed<$parent$$classname$> " + "{\n", + "parent", parent, "classname", message_generators_[i]->classname_); printer->Indent(); message_generators_[i]->GenerateExtraDefaultFields(printer); printer->Outdent(); @@ -340,9 +355,6 @@ void FileGenerator::GenerateSource(io::Printer* printer) { "classname", message_generators_[i]->classname_); } - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->index_in_metadata_ = i; - } for (int i = 0; i < enum_generators_.size(); i++) { enum_generators_[i]->index_in_metadata_ = i; } @@ -530,6 +542,70 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { // In optimize_for = LITE_RUNTIME mode, we don't generate AssignDescriptors() // and we only use AddDescriptors() to allocate default instances. + // TODO(ckennelly): Gate this with the same options flag to enable + // table-driven parsing. + + printer->Print("PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField\n" + " const TableStruct::entries[] = {\n"); + printer->Indent(); + + std::vector entries; + size_t count = 0; + for (int i = 0; i < message_generators_.size(); i++) { + size_t value = message_generators_[i]->GenerateParseOffsets(printer); + entries.push_back(value); + count += value; + } + + // We need these arrays to exist, and MSVC does not like empty arrays. + if (count == 0) { + printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "\n" + "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField\n" + " const TableStruct::aux[] = {\n"); + printer->Indent(); + + std::vector aux_entries; + count = 0; + for (int i = 0; i < message_generators_.size(); i++) { + size_t value = message_generators_[i]->GenerateParseAuxTable(printer); + aux_entries.push_back(value); + count += value; + } + + if (count == 0) { + printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const\n" + " TableStruct::schema[] = {\n"); + printer->Indent(); + + size_t offset = 0; + size_t aux_offset = 0; + for (int i = 0; i < message_generators_.size(); i++) { + message_generators_[i]->GenerateParseTable(printer, offset, aux_offset); + offset += entries[i]; + aux_offset += aux_entries[i]; + } + + if (message_generators_.empty()) { + printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + } + + printer->Outdent(); + printer->Print( + "};\n" + "\n"); + if (HasDescriptorMethods(file_, options_)) { if (!message_generators_.empty()) { printer->Print("const ::google::protobuf::uint32 TableStruct::offsets[] = {\n"); @@ -560,8 +636,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { printer->Indent(); for (int i = 0; i < message_generators_.size(); i++) { const Descriptor* descriptor = message_generators_[i]->descriptor_; - if (IsMapEntryMessage(descriptor)) continue; - printer->Print( "reinterpret_cast(&_$classname$_default_instance_),\n", @@ -600,7 +674,31 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { " AssignDescriptors(\n" " \"$filename$\", schemas, file_default_instances, " "TableStruct::offsets, factory,\n" - " $metadata$, $enum_descriptors$, $service_descriptors$);\n" + " $metadata$, $enum_descriptors$, $service_descriptors$);\n", + "filename", file_->name(), "metadata", + !message_generators_.empty() ? "file_level_metadata" : "NULL", + "enum_descriptors", + !enum_generators_.empty() ? "file_level_enum_descriptors" : "NULL", + "service_descriptors", + HasGenericServices(file_, options_) && file_->service_count() > 0 + ? "file_level_service_descriptors" + : "NULL", + "factory", message_factory); + // TODO(gerbens) have the compiler include the schemas for map types + // so that this can go away, and we can potentially use table driven + // serialization for map types as well. + for (int i = 0; i < message_generators_.size(); i++) { + if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; + printer->Print( + "file_level_metadata[$index$].reflection = " + "$parent$::$classname$::CreateReflection(file_level_metadata[$index$]" + ".descriptor, _$classname$_default_instance_.get_mutable());\n", + "index", SimpleItoa(i), "parent", + ClassName(message_generators_[i]->descriptor_->containing_type(), + false), + "classname", ClassName(message_generators_[i]->descriptor_, false)); + } + printer->Print( "}\n" "\n" "void protobuf_AssignDescriptorsOnce() {\n" @@ -634,12 +732,6 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { "size", SimpleItoa(message_generators_.size())); } - // Map types are treated special - // TODO(gerbens) find a way to treat maps more like normal messages. - for (int i = 0; i < message_generators_.size(); i++) { - message_generators_[i]->GenerateTypeRegistrations(printer); - } - printer->Outdent(); printer->Print( "}\n" @@ -902,8 +994,16 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { "#include \n" "#include \n" "#include \n" - "#include \n" + "#include \n" + "#include \n"); + + if (HasDescriptorMethods(file_, options_)) { + printer->Print( "#include \n"); + } else { + printer->Print( + "#include \n"); + } if (!message_generators_.empty()) { if (HasDescriptorMethods(file_, options_)) { @@ -921,7 +1021,8 @@ void FileGenerator::GenerateLibraryIncludes(io::Printer* printer) { " // IWYU pragma: export\n"); if (HasMapFields(file_)) { printer->Print( - "#include \n"); + "#include " + " // IWYU pragma: export\n"); if (HasDescriptorMethods(file_, options_)) { printer->Print( "#include \n"); @@ -1001,6 +1102,9 @@ void FileGenerator::GenerateGlobalStateFunctionDeclarations( "namespace $file_namespace$ {\n" "// Internal implementation detail -- do not call these.\n" "struct $dllexport_decl$TableStruct {\n" + " static const ::google::protobuf::internal::ParseTableField entries[];\n" + " static const ::google::protobuf::internal::AuxillaryParseTableField aux[];\n" + " static const ::google::protobuf::internal::ParseTable schema[];\n" " static const ::google::protobuf::uint32 offsets[];\n" // The following function(s) need to be able to access private members of // the messages defined in the file. So we make them static members. diff --git a/src/google/protobuf/compiler/cpp/cpp_file.h b/src/google/protobuf/compiler/cpp/cpp_file.h index e3fbb96d..e10fe2f3 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.h +++ b/src/google/protobuf/compiler/cpp/cpp_file.h @@ -43,6 +43,7 @@ #include #include #include +#include #include namespace google { @@ -145,6 +146,8 @@ class FileGenerator { const FileDescriptor* file_; const Options options_; + SCCAnalyzer scc_analyzer_; + // Contains the post-order walk of all the messages (and child messages) in // this file. If you need a pre-order walk just reverse iterate. std::vector message_generators_; diff --git a/src/google/protobuf/compiler/cpp/cpp_generator.cc b/src/google/protobuf/compiler/cpp/cpp_generator.cc index 648ab28a..cee31224 100644 --- a/src/google/protobuf/compiler/cpp/cpp_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_generator.cc @@ -98,6 +98,8 @@ bool CppGenerator::Generate(const FileDescriptor* file, file_options.annotation_guard_name = options[i].second; } else if (options[i].first == "lite") { file_options.enforce_lite = true; + } else if (options[i].first == "table_driven_parsing") { + file_options.table_driven_parsing = true; } else { *error = "Unknown generator option: " + options[i].first; return false; diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 3c4dddc5..9cddba5c 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -654,6 +654,109 @@ void GenerateUtf8CheckCodeForCord(const FieldDescriptor* field, "VerifyUtf8Cord", "VerifyUTF8CordNamedField", printer); } +bool HasWeakFields(const Descriptor* descriptor) { + return false; +} + +bool HasWeakFields(const FileDescriptor* file) { + return false; +} + +SCCAnalyzer::NodeData SCCAnalyzer::DFS(const Descriptor* descriptor) { + // Must not have visited already. + GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0); + + // Mark visited by inserting in map. + NodeData& result = cache_[descriptor]; + // Initialize data structures. + result.index = result.lowlink = index_++; + stack_.push_back(descriptor); + + // Recurse the fields / nodes in graph + for (int i = 0; i < descriptor->field_count(); i++) { + const Descriptor* child = descriptor->field(i)->message_type(); + if (child) { + if (cache_.count(child) == 0) { + // unexplored node + NodeData child_data = DFS(child); + result.lowlink = std::min(result.lowlink, child_data.lowlink); + } else { + NodeData child_data = cache_[child]; + if (child_data.scc == NULL) { + // Still in the stack_ so we found a back edge + result.lowlink = std::min(result.lowlink, child_data.index); + } + } + } + } + if (result.index == result.lowlink) { + // This is the root of a strongly connected component + SCC* scc = CreateSCC(); + while (true) { + const Descriptor* scc_desc = stack_.back(); + scc->descriptors.push_back(scc_desc); + // Remove from stack + stack_.pop_back(); + cache_[scc_desc].scc = scc; + + if (scc_desc == descriptor) break; + } + } + return result; +} + +MessageAnalysis SCCAnalyzer::GetSCCAnalysis(const SCC* scc) { + if (analysis_cache_.count(scc)) return analysis_cache_[scc]; + MessageAnalysis result = MessageAnalysis(); + for (int i = 0; i < scc->descriptors.size(); i++) { + const Descriptor* descriptor = scc->descriptors[i]; + if (descriptor->extension_range_count() > 0) { + result.contains_extension = true; + } + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + if (field->is_required()) { + result.contains_required = true; + } + switch (field->type()) { + case FieldDescriptor::TYPE_STRING: + case FieldDescriptor::TYPE_BYTES: { + if (field->options().ctype() == FieldOptions::CORD) { + result.contains_cord = true; + } + break; + } + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: { + const SCC* child = GetSCC(field->message_type()); + if (child != scc) { + MessageAnalysis analysis = GetSCCAnalysis(child); + result.contains_cord |= analysis.contains_cord; + result.contains_extension |= analysis.contains_extension; + if (!ShouldIgnoreRequiredFieldCheck(field, options_)) { + result.contains_required |= analysis.contains_required; + } + } else { + // This field points back into the same SCC hence the messages + // in the SCC are recursive. Note if SCC contains more than two + // nodes it has to be recursive, however this test also works for + // a single node that is recursive. + result.is_recursive = true; + } + break; + } + default: + break; + } + } + } + // We deliberately only insert the result here. After we contracted the SCC + // in the graph, the graph should be a DAG. Hence we shouldn't need to mark + // nodes visited as we can never return to them. By inserting them here + // we will go in an infinite loop if the SCC is not correct. + return analysis_cache_[scc] = result; +} + } // 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 0f297ec8..a744a865 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -277,6 +277,73 @@ inline ::google::protobuf::FileOptions_OptimizeMode GetOptimizeFor( : file->options().optimize_for(); } +bool HasWeakFields(const Descriptor* desc); +bool HasWeakFields(const FileDescriptor* desc); + +// Returns true if the "required" restriction check should be ignored for the +// given field. +inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, + const Options& options) { + return false; +} + +struct SCC { + std::vector descriptors; +}; + +struct MessageAnalysis { + bool is_recursive; + bool contains_cord; + bool contains_extension; + bool contains_required; +}; + +// This class is used in FileGenerator, to ensure linear instead of +// quadratic performance, if we do this per message we would get O(V*(V+E)). +// Logically this is just only used in message.cc, but in the header for +// FileGenerator to help share it. +class LIBPROTOC_EXPORT SCCAnalyzer { + public: + explicit SCCAnalyzer(const Options& options) : options_(options), index_(0) {} + ~SCCAnalyzer() { + for (int i = 0; i < garbage_bin_.size(); i++) delete garbage_bin_[i]; + } + + const SCC* GetSCC(const Descriptor* descriptor) { + if (cache_.count(descriptor)) return cache_[descriptor].scc; + return DFS(descriptor).scc; + } + + MessageAnalysis GetSCCAnalysis(const SCC* scc); + + bool HasRequiredFields(const Descriptor* descriptor) { + MessageAnalysis result = GetSCCAnalysis(GetSCC(descriptor)); + return result.contains_required || result.contains_extension; + } + + private: + struct NodeData { + const SCC* scc; // if null it means its still on the stack + int index; + int lowlink; + }; + + Options options_; + std::map cache_; + std::map analysis_cache_; + std::vector stack_; + int index_; + std::vector garbage_bin_; + + SCC* CreateSCC() { + garbage_bin_.push_back(new SCC()); + return garbage_bin_.back(); + } + + // Tarjan's Strongly Connected Components algo + NodeData DFS(const Descriptor* descriptor); +}; + } // 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 b4eaf485..52a3b8b0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.cc @@ -32,6 +32,7 @@ #include #include #include + #include namespace google { @@ -113,18 +114,49 @@ MapFieldGenerator::~MapFieldGenerator() {} void MapFieldGenerator:: GeneratePrivateMembers(io::Printer* printer) const { + if (HasDescriptorMethods(descriptor_->file(), options_)) { + printer->Print( + variables_, + "public:\n" + "class $map_classname$ : public " + "::google::protobuf::internal::MapEntry<$map_classname$, \n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > {\n" + "public:\n" + " typedef ::google::protobuf::internal::MapEntry<$map_classname$, \n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > SuperType;\n" + " $map_classname$();\n" + " $map_classname$(::google::protobuf::Arena* arena);\n" + " void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL;\n" + " void MergeFrom(const $map_classname$& other);\n" + " static const Message* internal_default_instance() { return " + "reinterpret_cast(&_$map_classname$_default_instance_); }\n" + " ::google::protobuf::Metadata GetMetadata() const;\n" + "};\n"); + } else { + printer->Print(variables_, + "public:\n" + "typedef ::google::protobuf::internal::MapEntryLite<\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ >\n" + " $map_classname$;\n"); + } printer->Print(variables_, - "typedef ::google::protobuf::internal::MapEntryLite<\n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ >\n" - " $map_classname$;\n" - "::google::protobuf::internal::MapField$lite$<\n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ > $name$_;\n"); + "::google::protobuf::internal::MapField$lite$<\n" + " $map_classname$,\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ > $name$_;\n" + "private:\n"); } void MapFieldGenerator:: @@ -171,17 +203,6 @@ GenerateSwappingCode(io::Printer* printer) const { printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n"); } -void MapFieldGenerator:: -GenerateConstructorCode(io::Printer* printer) const { - if (HasDescriptorMethods(descriptor_->file(), options_)) { - printer->Print(variables_, - "$name$_.SetAssignDescriptorCallback(\n" - " $file_namespace$::protobuf_AssignDescriptorsOnce);\n" - "$name$_.SetEntryDescriptor(\n" - " &$type$_descriptor);\n"); - } -} - void MapFieldGenerator:: GenerateCopyConstructorCode(io::Printer* printer) const { GenerateConstructorCode(printer); @@ -199,13 +220,15 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { string value; if (IsProto3Field(descriptor_) || value_field->type() != FieldDescriptor::TYPE_ENUM) { - printer->Print(variables_, + printer->Print( + variables_, "$map_classname$::Parser< ::google::protobuf::internal::MapField$lite$<\n" - " $key_cpp$, $val_cpp$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$ >,\n" - " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" + " $map_classname$,\n" + " $key_cpp$, $val_cpp$,\n" + " $key_wire_type$,\n" + " $val_wire_type$,\n" + " $default_enum_value$ >,\n" + " ::google::protobuf::Map< $key_cpp$, $val_cpp$ > >" " parser(&$name$_);\n" "DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(\n" " input, &parser));\n"); diff --git a/src/google/protobuf/compiler/cpp/cpp_map_field.h b/src/google/protobuf/compiler/cpp/cpp_map_field.h index 816687b3..02e66497 100644 --- a/src/google/protobuf/compiler/cpp/cpp_map_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_map_field.h @@ -54,7 +54,7 @@ class MapFieldGenerator : public FieldGenerator { void GenerateClearingCode(io::Printer* printer) const; void GenerateMergingCode(io::Printer* printer) const; void GenerateSwappingCode(io::Printer* printer) const; - void GenerateConstructorCode(io::Printer* printer) const; + void GenerateConstructorCode(io::Printer* printer) const {} void GenerateCopyConstructorCode(io::Printer* printer) const; void GenerateMergeFromCodedStream(io::Printer* printer) const; void GenerateSerializeWithCachedSizes(io::Printer* printer) const; diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index 1373ffc2..d9524f64 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -32,6 +32,8 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include + #include #include #include @@ -41,16 +43,18 @@ #endif #include #include -#include -#include + #include #include +#include #include -#include -#include #include -#include +#include #include +#include +#include +#include +#include namespace google { @@ -103,54 +107,6 @@ struct ExtensionRangeSorter { } }; -// Returns true if the "required" restriction check should be ignored for the -// given field. -inline static bool ShouldIgnoreRequiredFieldCheck(const FieldDescriptor* field, - const Options& options) { - return false; -} - -// Returns true if the message type has any required fields. If it doesn't, -// we can optimize out calls to its IsInitialized() method. -// -// already_seen is used to avoid checking the same type multiple times -// (and also to protect against recursion). -static bool HasRequiredFields(const Descriptor* type, const Options& options, - hash_set* already_seen) { - if (already_seen->count(type) > 0) { - // Since the first occurrence of a required field causes the whole - // function to return true, we can assume that if the type is already - // in the cache it didn't have any required fields. - return false; - } - already_seen->insert(type); - - // If the type has extensions, an extension with message type could contain - // required fields, so we have to be conservative and assume such an - // extension exists. - if (type->extension_range_count() > 0) return true; - - for (int i = 0; i < type->field_count(); i++) { - const FieldDescriptor* field = type->field(i); - if (field->is_required()) { - return true; - } - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && - !ShouldIgnoreRequiredFieldCheck(field, options)) { - if (HasRequiredFields(field->message_type(), options, already_seen)) { - return true; - } - } - } - - return false; -} - -static bool HasRequiredFields(const Descriptor* type, const Options& options) { - hash_set already_seen; - return HasRequiredFields(type, options, &already_seen); -} - // This returns an estimate of the compiler's alignment for the field. This // can't guarantee to be correct because the generated code could be compiled on // different systems with different alignment rules. The estimates below assume @@ -288,10 +244,13 @@ bool CanConstructByZeroing(const FieldDescriptor* field, // order, fields of similiar family (see below) are together and within each // family, alignment padding is minimized. // -// We try to do this while keeping each field as close as possible to its -// declaration order (from the .proto file) so that we don't reduce cache -// locality much for function that access each field in order. This is also the -// only (weak) signal we have for author intent concerning field layout. +// We try to do this while keeping each field as close as possible to its field +// number order so that we don't reduce cache locality much for function that +// access each field in order. Originally, OptimizePadding used declaration +// order for its decisions, but generated code minus the serializer/parsers uses +// the output of OptimizePadding as well (stored in +// MessageGenerator::optimized_order_). Since the serializers use field number +// order, we use that as a tie-breaker. // // TODO(ckennelly): If/when we have profiles available for the compiler, use // those rather than respect declaration order. @@ -346,10 +305,11 @@ void OptimizePadding(std::vector* fields, f = ZERO_INITIALIZABLE; } + const int j = field->number(); switch (EstimateAlignmentSize(field)) { - case 1: aligned_to_1[f].push_back(FieldGroup(i, field)); break; - case 4: aligned_to_4[f].push_back(FieldGroup(i, field)); break; - case 8: aligned_to_8[f].push_back(FieldGroup(i, field)); break; + case 1: aligned_to_1[f].push_back(FieldGroup(j, field)); break; + case 4: aligned_to_4[f].push_back(FieldGroup(j, field)); break; + case 8: aligned_to_8[f].push_back(FieldGroup(j, field)); break; default: GOOGLE_LOG(FATAL) << "Unknown alignment size."; } @@ -366,7 +326,7 @@ void OptimizePadding(std::vector* fields, } aligned_to_4[f].push_back(field_group); } - // Sort by preferred location to keep fields as close to their declaration + // Sort by preferred location to keep fields as close to their field number // order as possible. Using stable_sort ensures that the output is // consistent across runs. std::stable_sort(aligned_to_4[f].begin(), aligned_to_4[f].end()); @@ -406,9 +366,6 @@ void OptimizePadding(std::vector* fields, } } -string MessageTypeProtoName(const FieldDescriptor* field) { - return field->message_type()->full_name(); -} // Emits an if-statement with a condition that evaluates to true if |field| is // considered non-default (will be sent over the wire), for message types @@ -495,30 +452,99 @@ bool HasPrivateHasMethod(const FieldDescriptor* field) { } +bool TableDrivenEnabled(const Descriptor* descriptor, const Options& options) { + if (!options.table_driven_parsing) { + return false; + } + + // Consider table-driven parsing. We only do this if: + // - There are no extensions + if (descriptor->extension_range_count() != 0) { + return false; + } + + // - We are not using UnknownFieldSet (part of the non-lite library). + if (UseUnknownFieldSet(descriptor->file(), options)) { + return false; + } + + // - We have has_bits for fields. This avoids a check on every field we set + // when are present (the common case). + if (!HasFieldPresence(descriptor->file())) { + return false; + } + + const double table_sparseness = 0.5; + int max_field_number = 0; + for (int i = 0; i < descriptor->field_count(); i++) { + const FieldDescriptor* field = descriptor->field(i); + if (max_field_number < field->number()) { + max_field_number = field->number(); + } + + // - There are no map fields. + if (field->is_map()) { + return false; + } + + // - There are no oneof fields. + if (field->containing_oneof()) { + return false; + } + + // - There are no weak fields. + if (field->options().weak()) { + return false; + } + } + + // - There range of field numbers is "small" + if (max_field_number >= (2 << 14)) { + return false; + } + + // - Field numbers are relatively dense within the actual number of fields + if (max_field_number * table_sparseness >= descriptor->field_count()) { + return false; + } + + // - This is not a MapEntryMessage. + if (IsMapEntryMessage(descriptor)) { + return false; + } + + return true; +} + } // anonymous namespace // =================================================================== MessageGenerator::MessageGenerator(const Descriptor* descriptor, - const Options& options) + const Options& options, + SCCAnalyzer* scc_analyzer) : descriptor_(descriptor), classname_(ClassName(descriptor, false)), options_(options), field_generators_(descriptor, options), max_has_bit_index_(0), nested_generators_(new google::protobuf::scoped_ptr< - MessageGenerator>[descriptor->nested_type_count()]), + MessageGenerator>[descriptor->nested_type_count()]), enum_generators_( new google::protobuf::scoped_ptr[descriptor->enum_type_count()]), extension_generators_(new google::protobuf::scoped_ptr< - ExtensionGenerator>[descriptor->extension_count()]), - use_dependent_base_(false) { - + ExtensionGenerator>[descriptor->extension_count()]), + use_dependent_base_(false), + num_weak_fields_(0), + scc_analyzer_(scc_analyzer) { // Compute optimized field order to be used for layout and initialization // purposes. for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - optimized_order_.push_back(descriptor_->field(i)); + const FieldDescriptor* field = descriptor_->field(i); + if (field->options().weak()) { + num_weak_fields_++; + } else if (!field->containing_oneof()) { + optimized_order_.push_back(field); } } OptimizePadding(&optimized_order_, options_); @@ -538,8 +564,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, } for (int i = 0; i < descriptor->nested_type_count(); i++) { - nested_generators_[i].reset( - new MessageGenerator(descriptor->nested_type(i), options)); + nested_generators_[i].reset(new MessageGenerator(descriptor->nested_type(i), + options, scc_analyzer)); } for (int i = 0; i < descriptor->enum_type_count(); i++) { @@ -565,6 +591,8 @@ MessageGenerator::MessageGenerator(const Descriptor* descriptor, // Always make oneofs dependent. use_dependent_base_ = true; } + + table_driven_ = TableDrivenEnabled(descriptor_, options_); } MessageGenerator::~MessageGenerator() {} @@ -586,6 +614,7 @@ void MessageGenerator::Flatten(std::vector* list) { for (int i = 0; i < descriptor_->nested_type_count(); i++) { nested_generators_[i]->Flatten(list); } + index_in_file_messages_ = list->size(); list->push_back(this); } @@ -602,7 +631,6 @@ void MessageGenerator::AddGenerators( void MessageGenerator::FillMessageForwardDeclarations( std::map* class_names) { - if (IsMapEntryMessage(descriptor_)) return; (*class_names)[classname_] = descriptor_; } @@ -644,7 +672,7 @@ GenerateFieldAccessorDeclarations(io::Printer* printer) { ordered_fields.begin(), optimized_order_.begin(), optimized_order_.end()); for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof() == NULL) { + if (field->containing_oneof() == NULL && !field->options().weak()) { continue; } ordered_fields.push_back(field); @@ -777,6 +805,15 @@ void MessageGenerator:: GenerateSingularFieldHasBits(const FieldDescriptor* field, std::map vars, io::Printer* printer) { + if (field->options().weak()) { + printer->Print( + vars, + "$inline$" + "bool $classname$::has_$name$() const {\n" + " return _weak_field_map_.Has($number$);\n" + "}\n"); + return; + } if (HasFieldPresence(descriptor_->file())) { // N.B.: without field presence, we do not use has-bits or generate // has_$name$() methods. @@ -896,7 +933,7 @@ GenerateFieldClear(const FieldDescriptor* field, field_generators_.get(field) .GenerateClearingCode(printer); if (HasFieldPresence(descriptor_->file())) { - if (!field->is_repeated()) { + if (!field->is_repeated() && !field->options().weak()) { printer->Print(vars, "$this_message$clear_has_$name$();\n"); } @@ -1049,6 +1086,29 @@ GenerateClassDefinition(io::Printer* printer) { "}\n" "\n"); + // Generate move constructor and move assignment operator for types other than + // Any. + #ifdef PROTO_EXPERIMENTAL_ENABLE_MOVE + if (!IsAnyMessage(descriptor_)) { + printer->Print(vars, + "#if LANG_CXX11\n" + "$classname$($classname$&& from)\n" + " : $classname$() {\n" + " *this = ::std::move(from);\n" + "}\n" + "\n" + "inline $classname$& operator=($classname$&& from) {\n" + " if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {\n" + " InternalSwap(&from);\n" + " } else {\n" + " CopyFrom(from);\n" + " }\n" + " return *this;\n" + "}\n" + "#endif\n"); + } + #endif + if (PreserveUnknownFields(descriptor_)) { string type = UseUnknownFieldSet(descriptor_->file(), options_) ? "::google::protobuf::UnknownFieldSet" @@ -1119,12 +1179,15 @@ GenerateClassDefinition(io::Printer* printer) { } // TODO(gerbens) make this private, while still granting other protos access. + vars["message_index"] = SimpleItoa(index_in_file_messages_); printer->Print( vars, "static inline const $classname$* internal_default_instance() {\n" " return reinterpret_cast(\n" " &_$classname$_default_instance_);\n" "}\n" + "static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =\n" + " $message_index$;\n" "\n"); @@ -1199,14 +1262,8 @@ GenerateClassDefinition(io::Printer* printer) { } if (HasFastArraySerialization(descriptor_->file(), options_)) { printer->Print( - "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n" - " bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;\n" - "::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output)\n" - " const PROTOBUF_FINAL {\n" - " return InternalSerializeWithCachedSizesToArray(\n" - " ::google::protobuf::io::CodedOutputStream::" - "IsDefaultSerializationDeterministic(), output);\n" - "}\n"); + "::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(\n" + " bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;\n"); } } @@ -1312,7 +1369,8 @@ GenerateClassDefinition(io::Printer* printer) { for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->is_repeated()) { + if (!descriptor_->field(i)->is_repeated() && + !descriptor_->field(i)->options().weak()) { // set_has_***() generated in all proto1/2 code and in oneofs (only) for // messages without true field presence. if (HasFieldPresence(descriptor_->file()) || @@ -1451,6 +1509,10 @@ GenerateClassDefinition(io::Printer* printer) { "\n"); } + if (num_weak_fields_) { + printer->Print( + "::google::protobuf::internal::WeakFieldMap _weak_field_map_;\n"); + } // Generate _any_metadata_ for the Any type. if (IsAnyMessage(descriptor_)) { printer->Print(vars, @@ -1459,6 +1521,7 @@ GenerateClassDefinition(io::Printer* printer) { // The TableStruct struct needs access to the private parts, in order to // construct the offsets of all members. + // // Some InitDefault and Shutdown are defined as static member functions of // TableStruct such that they are also allowed to access private members. printer->Print( @@ -1511,8 +1574,9 @@ GenerateInlineMethods(io::Printer* printer, bool is_inline) { void MessageGenerator:: GenerateExtraDefaultFields(io::Printer* printer) { - // Generate oneof default instance for reflection usage. - if (descriptor_->oneof_decl_count() > 0) { + // Generate oneof default instance and weak field instances for reflection + // usage. + if (descriptor_->oneof_decl_count() > 0 || num_weak_fields_ > 0) { printer->Print("public:\n"); for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { @@ -1525,9 +1589,71 @@ GenerateExtraDefaultFields(io::Printer* printer) { field_generators_.get(field).GeneratePrivateMembers(printer); } } + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (field->options().weak()) { + printer->Print( + " const ::google::protobuf::Message* $name$_;\n", "name", FieldName(field)); + } + } } } +bool MessageGenerator::GenerateParseTable(io::Printer* printer, size_t offset, + size_t aux_offset) { + if (!table_driven_) { + printer->Print("{ NULL, NULL, 0, -1, -1, false },\n"); + return false; + } + + std::map vars; + + vars["classname"] = classname_; + vars["offset"] = SimpleItoa(offset); + vars["aux_offset"] = SimpleItoa(aux_offset); + + int max_field_number = 0; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = descriptor_->field(i); + if (max_field_number < field->number()) { + max_field_number = field->number(); + } + } + + vars["max_field_number"] = SimpleItoa(max_field_number); + + printer->Print("{\n"); + printer->Indent(); + + printer->Print(vars, + "TableStruct::entries + $offset$,\n" + "TableStruct::aux + $aux_offset$,\n" + "$max_field_number$,\n"); + + if (!HasFieldPresence(descriptor_->file())) { + // If we don't have field presence, then _has_bits_ does not exist. + printer->Print(vars, "-1,\n"); + } else { + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classname$, _has_bits_),\n"); + } + + printer->Print(vars, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classname$, _internal_metadata_),\n"); + + if (UseUnknownFieldSet(descriptor_->file(), options_)) { + printer->Print(vars, "true,\n"); + } else { + printer->Print(vars, "false,\n"); + } + + printer->Outdent(); + printer->Print("},\n"); + return true; +} + void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, int has_offset) { if (IsMapEntryMessage(descriptor_)) return; @@ -1544,47 +1670,8 @@ void MessageGenerator::GenerateSchema(io::Printer* printer, int offset, "{ $offset$, $has_bits_offsets$, sizeof($classname$)},\n"); } -void MessageGenerator:: -GenerateTypeRegistrations(io::Printer* printer) { - // Register this message type with the message factory. - if (IsMapEntryMessage(descriptor_)) { - std::map vars; - CollectMapInfo(descriptor_, &vars); - vars["classname"] = classname_; - vars["file_namespace"] = FileLevelNamespace(descriptor_->file()->name()); - - const FieldDescriptor* val = descriptor_->FindFieldByName("value"); - if (descriptor_->file()->syntax() == FileDescriptor::SYNTAX_PROTO2 && - val->type() == FieldDescriptor::TYPE_ENUM) { - const EnumValueDescriptor* default_value = val->default_value_enum(); - vars["default_enum_value"] = Int32ToString(default_value->number()); - } else { - vars["default_enum_value"] = "0"; - } - - vars["index_in_metadata"] = SimpleItoa(index_in_metadata_); - - printer->Print( - vars, - "const ::google::protobuf::Descriptor* $classname$_descriptor = " - "$file_namespace$::file_level_metadata[$index_in_metadata$].descriptor;" - "\n" - "::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(\n" - " $classname$_descriptor,\n" - " ::google::protobuf::internal::MapEntry<\n" - " $key$,\n" - " $val$,\n" - " $key_wire_type$,\n" - " $val_wire_type$,\n" - " $default_enum_value$>::CreateDefaultInstance(\n" - " $classname$_descriptor));\n"); - } -} - void MessageGenerator:: GenerateDefaultInstanceAllocator(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; - // Construct the default instances of all fields, as they will be used // when creating the default instance of the entire message. for (int i = 0; i < descriptor_->field_count(); i++) { @@ -1601,7 +1688,15 @@ GenerateDefaultInstanceAllocator(io::Printer* printer) { void MessageGenerator:: GenerateDefaultInstanceInitializer(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; + if (IsMapEntryMessage(descriptor_)) { + printer->Print( + "_$classname$_default_instance_.get_mutable()->set_default_instance(_$" + "classname$_default_instance_.get_mutable());\n" + "_$classname$_default_instance_.get_mutable()->InitAsDefaultInstance();" + "\n", + "classname", classname_); + return; + } // The default instance needs all of its embedded message pointers // cross-linked to other default instances. We can't do this initialization @@ -1617,7 +1712,7 @@ GenerateDefaultInstanceInitializer(io::Printer* printer) { (field->containing_oneof() == NULL || HasDescriptorMethods(descriptor_->file(), options_))) { string name; - if (field->containing_oneof()) { + if (field->containing_oneof() || field->options().weak()) { name = "_" + classname_ + "_default_instance_."; } else { name = "_" + classname_ + "_default_instance_.get_mutable()->"; @@ -1645,7 +1740,7 @@ GenerateShutdownCode(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { printer->Print("delete file_level_metadata[$index$].reflection;\n", "index", - SimpleItoa(index_in_metadata_)); + SimpleItoa(index_in_file_messages_)); } // Handle default instances of fields. @@ -1657,7 +1752,31 @@ GenerateShutdownCode(io::Printer* printer) { void MessageGenerator:: GenerateClassMethods(io::Printer* printer) { - if (IsMapEntryMessage(descriptor_)) return; + if (IsMapEntryMessage(descriptor_)) { + if (HasDescriptorMethods(descriptor_->file(), options_)) { + printer->Print( + "$parent$::$classname$::$classname$() {}\n" + "$parent$::$classname$::$classname$(::google::protobuf::Arena* arena) : " + "SuperType(arena) {}\n" + "::google::protobuf::Metadata $parent$::$classname$::GetMetadata() const {\n" + " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" + " return $file_namespace$::file_level_metadata[$index$];\n" + "}\n" + "void $parent$::$classname$::MergeFrom(\n" + " const ::google::protobuf::Message& other) {\n" + " ::google::protobuf::Message::MergeFrom(other);\n" + "}\n" + "void $parent$::$classname$::MergeFrom(const $classname$& other) {\n" + " MergeFromInternal(other);\n" + "}\n" + "\n", + "file_namespace", FileLevelNamespace(descriptor_->file()->name()), + "parent", ClassName(descriptor_->containing_type(), false), + "classname", classname_, "index", + SimpleItoa(index_in_file_messages_)); + } + return; + } if (IsAnyMessage(descriptor_)) { printer->Print( @@ -1739,11 +1858,12 @@ GenerateClassMethods(io::Printer* printer) { printer->Print( "::google::protobuf::Metadata $classname$::GetMetadata() const {\n" " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" - " return $file_namespace$::file_level_metadata[$index$];\n" + " return " + "$file_namespace$::file_level_metadata[kIndexInFileMessages];\n" "}\n" "\n", - "classname", classname_, "index", SimpleItoa(index_in_metadata_), - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "file_namespace", + FileLevelNamespace(descriptor_->file()->name())); } else { printer->Print( "::std::string $classname$::GetTypeName() const {\n" @@ -1756,6 +1876,185 @@ GenerateClassMethods(io::Printer* printer) { } +size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) { + if (!table_driven_) { + return 0; + } + + // Field "0" is special: We use it in our switch statement of processing + // types to handle the successful end tag case. + printer->Print("{0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0},\n"); + int last_field_number = 1; + + std::vector ordered_fields = + SortFieldsByNumber(descriptor_); + + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = ordered_fields[i]; + GOOGLE_CHECK_GE(field->number(), last_field_number); + + for (; last_field_number < field->number(); last_field_number++) { + printer->Print( + "{ 0, 0, ::google::protobuf::internal::kInvalidMask,\n" + " ::google::protobuf::internal::kInvalidMask, 0, 0 },\n"); + } + last_field_number++; + + unsigned char normal_wiretype, packed_wiretype, processing_type; + normal_wiretype = WireFormat::WireTypeForFieldType(field->type()); + + if (field->is_packable()) { + packed_wiretype = WireFormatLite::WIRETYPE_LENGTH_DELIMITED; + } else { + packed_wiretype = internal::kNotPackedMask; + } + + processing_type = static_cast(field->type()); + if (field->type() == FieldDescriptor::TYPE_STRING) { + switch (EffectiveStringCType(field)) { + case FieldOptions::STRING: + default: + break; + } + } else if (field->type() == FieldDescriptor::TYPE_BYTES) { + switch (EffectiveStringCType(field)) { + case FieldOptions::STRING: + default: + break; + } + } + + processing_type |= static_cast( + field->is_repeated() ? internal::kRepeatedMask : 0); + const unsigned char tag_size = + WireFormat::TagSize(field->number(), field->type()); + + std::map vars; + vars["classname"] = classname_; + vars["name"] = FieldName(field); + vars["has"] = SimpleItoa(has_bit_indices_[field->index()]); + vars["nwtype"] = SimpleItoa(normal_wiretype); + vars["pwtype"] = SimpleItoa(packed_wiretype); + vars["ptype"] = SimpleItoa(processing_type); + vars["tag_size"] = SimpleItoa(tag_size); + + printer->Print(vars, + "{\n" + " GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(\n" + " $classname$, $name$_),\n" + " static_cast< ::google::protobuf::uint32>($has$),\n" + " $nwtype$, $pwtype$, $ptype$, $tag_size$\n" + "},\n"); + } + + return last_field_number; +} + +size_t MessageGenerator::GenerateParseAuxTable(io::Printer* printer) { + if (!table_driven_) { + return 0; + } + + std::vector ordered_fields = + SortFieldsByNumber(descriptor_); + + printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n"); + int last_field_number = 1; + for (int i = 0; i < descriptor_->field_count(); i++) { + const FieldDescriptor* field = ordered_fields[i]; + + GOOGLE_CHECK_GE(field->number(), last_field_number); + for (; last_field_number < field->number(); last_field_number++) { + printer->Print("::google::protobuf::internal::AuxillaryParseTableField(),\n"); + } + + std::map vars; + SetCommonFieldVariables(field, &vars, options_); + + switch (field->cpp_type()) { + case FieldDescriptor::CPPTYPE_ENUM: + vars["type"] = ClassName(field->enum_type(), true); + printer->Print( + vars, + "{::google::protobuf::internal::AuxillaryParseTableField::enum_aux{" + "$type$_IsValid, \"$type$\" }},\n"); + last_field_number++; + break; + case FieldDescriptor::CPPTYPE_MESSAGE: { + std::vector package_parts; + + const Descriptor* outer = field->message_type(); + while (outer->containing_type() != NULL) { + outer = outer->containing_type(); + } + + package_parts = Split( + outer->full_name(), ".", true); + // outer->full_name() contains the class itself. Remove it as it is + // used in the name of the default instance variable. + GOOGLE_DCHECK_NE(package_parts.size(), 0); + package_parts.back().clear(); + + vars["classname"] = ClassName(field->message_type(), false); + vars["ns"] = Join(package_parts, "::"); + vars["type"] = FieldMessageTypeName(field); + vars["file_namespace"] = FileLevelNamespace(outer->file()->name()); + + printer->Print(vars, + "{::google::protobuf::internal::AuxillaryParseTableField::message_aux{\n" + " &::$ns$_$classname$_default_instance_,\n"); + + bool dont_emit_table = + !TableDrivenEnabled(field->message_type(), options_); + + if (dont_emit_table) { + printer->Print(" NULL,\n"); + } else { + printer->Print(vars, + " ::$ns$$file_namespace$::TableStruct::schema +\n" + " ::$ns$$classname$::kIndexInFileMessages,\n"); + } + + printer->Print("}},\n"); + last_field_number++; + break; + } + case FieldDescriptor::CPPTYPE_STRING: + switch (EffectiveStringCType(field)) { + case FieldOptions::STRING: + vars["default"] = + field->default_value_string().empty() + ? "&::google::protobuf::internal::fixed_address_empty_string" + : "&" + classname_ + "::_default_" + FieldName(field) + "_"; + break; + case FieldOptions::CORD: + case FieldOptions::STRING_PIECE: + vars["default"] = + "\"" + CEscape(field->default_value_string()) + "\""; + break; + } + vars["full_name"] = field->full_name(); + vars["strict"] = + field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 + ? "true" : "false"; + vars["type"] = field->full_name(); + printer->Print(vars, + "{::google::protobuf::internal::AuxillaryParseTableField::string_aux{\n" + " $default$,\n" + " \"$full_name$\",\n" + " $strict$,\n" + " \"$type$\"\n" + "}},\n"); + last_field_number++; + break; + default: + break; + } + } + + return last_field_number; +} + std::pair MessageGenerator::GenerateOffsets( io::Printer* printer) { if (IsMapEntryMessage(descriptor_)) return std::make_pair(0, 0); @@ -1765,7 +2064,8 @@ std::pair MessageGenerator::GenerateOffsets( if (HasFieldPresence(descriptor_->file())) { printer->Print( variables, - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _has_bits_),\n"); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_has_bits_),\n"); } else { printer->Print("~0u, // no _has_bits_\n"); } @@ -1775,34 +2075,41 @@ std::pair MessageGenerator::GenerateOffsets( if (descriptor_->extension_range_count() > 0) { printer->Print( variables, - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, _extensions_),\n"); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " + "_extensions_),\n"); } else { printer->Print("~0u, // no _extensions_\n"); } if (descriptor_->oneof_decl_count() > 0) { printer->Print(variables, - "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " - "_oneof_case_[0]),\n"); + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(" + "$classname$, _oneof_case_[0]),\n"); } else { printer->Print("~0u, // no _oneof_case_\n"); } - - const int kNumGenericOffsets = 4; // the number of fixed offsets above + if (num_weak_fields_ > 0) { + printer->Print(variables, + "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$," + " _weak_field_map_),\n"); + } else { + printer->Print("~0u, // no _weak_field_map_\n"); + } + const int kNumGenericOffsets = 5; // the number of fixed offsets above const size_t offsets = kNumGenericOffsets + descriptor_->field_count() + descriptor_->oneof_decl_count(); size_t entries = offsets; for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->containing_oneof()) { + if (field->containing_oneof() || field->options().weak()) { printer->Print( - "PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" + "GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(" "(&_$classname$_default_instance_), $name$_),\n", "classname", classname_, "name", FieldName(field)); } else { printer->Print( "GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET($classname$, " - "$name$_),\n", + "$name$_),\n", "classname", classname_, "name", FieldName(field)); } @@ -1844,19 +2151,6 @@ GenerateSharedConstructorCode(io::Printer* printer) { need_to_clear_cached_size = false; } - // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer?? - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - if (HasDescriptorMethods(descriptor_->file(), options_) && - IsMapEntryMessage(descriptor_->nested_type(i))) { - printer->Print( - "const ::google::protobuf::Descriptor*& $type$_descriptor = " - "$file_namespace$::file_level_metadata[$index$].descriptor;\n", - "type", ClassName(descriptor_->nested_type(i), false), "index", - SimpleItoa(nested_generators_[i]->index_in_metadata_), - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); - } - } - std::vector processed(optimized_order_.size(), false); GenerateConstructorBody(printer, processed, false); @@ -1906,6 +2200,9 @@ GenerateSharedDestructorCode(io::Printer* printer) { "oneof_name", descriptor_->oneof_decl(i)->name()); } + if (num_weak_fields_) { + printer->Print("_weak_field_map_.ClearAll();\n"); + } printer->Outdent(); printer->Print( "}\n" @@ -1956,6 +2253,12 @@ GenerateArenaDestructorCode(io::Printer* printer) { } } } + if (num_weak_fields_) { + // _this is the object being destructed (we are inside a static method + // here). + printer->Print("_this->_weak_field_map_.ClearAll();\n"); + need_registration = true; + } printer->Outdent(); printer->Print( @@ -2077,12 +2380,18 @@ GenerateStructors(io::Printer* printer) { if (IsAnyMessage(descriptor_)) { initializer_with_arena += ",\n _any_metadata_(&type_url_, &value_)"; } + if (num_weak_fields_ > 0) { + initializer_with_arena += ", _weak_field_map_(arena)"; + } string initializer_null; initializer_null = ", _internal_metadata_(NULL)"; if (IsAnyMessage(descriptor_)) { initializer_null += ", _any_metadata_(&type_url_, &value_)"; } + if (num_weak_fields_ > 0) { + initializer_null += ", _weak_field_map_(NULL)"; + } printer->Print( "$classname$::$classname$()\n" @@ -2165,6 +2474,9 @@ GenerateStructors(io::Printer* printer) { if (IsAnyMessage(descriptor_)) { printer->Print(",\n_any_metadata_(&type_url_, &value_)"); } + if (num_weak_fields_ > 0) { + printer->Print(",\n_weak_field_map_(from._weak_field_map_)"); + } printer->Outdent(); printer->Outdent(); @@ -2177,19 +2489,6 @@ GenerateStructors(io::Printer* printer) { printer->Print("_extensions_.MergeFrom(from._extensions_);\n"); } - // TODO(gerbens) Clean this hack, and why do i need a reference to a pointer?? - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - if (HasDescriptorMethods(descriptor_->file(), options_) && - IsMapEntryMessage(descriptor_->nested_type(i))) { - printer->Print( - "const ::google::protobuf::Descriptor*& $type$_descriptor = " - "$file_namespace$::file_level_metadata[$index$].descriptor;\n", - "type", ClassName(descriptor_->nested_type(i), false), "index", - SimpleItoa(nested_generators_[i]->index_in_metadata_), - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); - } - } - GenerateConstructorBody(printer, processed, true); // Copy oneof fields. Oneof field requires oneof case check. @@ -2268,11 +2567,13 @@ GenerateStructors(io::Printer* printer) { printer->Print( "const ::google::protobuf::Descriptor* $classname$::descriptor() {\n" " $file_namespace$::protobuf_AssignDescriptorsOnce();\n" - " return $file_namespace$::file_level_metadata[$index$].descriptor;\n" + " return " + "$file_namespace$::file_level_metadata[kIndexInFileMessages]." + "descriptor;\n" "}\n" "\n", - "index", SimpleItoa(index_in_metadata_), "classname", classname_, - "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + "classname", classname_, "file_namespace", + FileLevelNamespace(descriptor_->file()->name())); } printer->Print( @@ -2504,6 +2805,10 @@ GenerateClear(io::Printer* printer) { "oneof_name", descriptor_->oneof_decl(i)->name()); } + if (num_weak_fields_) { + printer->Print("_weak_field_map_.ClearAll();\n"); + } + if (HasFieldPresence(descriptor_->file())) { // Step 5: Everything else. printer->Print("_has_bits_.Clear();\n"); @@ -2647,6 +2952,10 @@ GenerateSwap(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { printer->Print("_extensions_.Swap(&other->_extensions_);\n"); } + if (num_weak_fields_) { + printer->Print( + "_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n"); + } } else { printer->Print("GetReflection()->Swap(this, other);"); } @@ -2714,7 +3023,14 @@ GenerateMergeFrom(io::Printer* printer) { } printer->Print( - "_internal_metadata_.MergeFrom(from._internal_metadata_);\n"); + "_internal_metadata_.MergeFrom(from._internal_metadata_);\n" + "::google::protobuf::uint32 cached_has_bits = 0;\n" + "(void) cached_has_bits;\n\n"); + + // cached_has_bit_index maintains that: + // cached_has_bits = from._has_bits_[cached_has_bit_index] + // for cached_has_bit_index >= 0 + int cached_has_bit_index = -1; int last_i = -1; for (int i = 0; i < optimized_order_.size(); ) { @@ -2734,7 +3050,7 @@ GenerateMergeFrom(io::Printer* printer) { generator.GenerateMergingCode(printer); } - // Merge Optional and Required fields (after a _has_bit check). + // Merge Optional and Required fields (after a _has_bit_ check). int last_chunk = -1; int last_chunk_start = -1; int last_chunk_end = -1; @@ -2779,23 +3095,43 @@ GenerateMergeFrom(io::Printer* printer) { GOOGLE_DCHECK_LE(2, count); GOOGLE_DCHECK_GE(8, count); + if (cached_has_bit_index != last_chunk / 4) { + int new_index = last_chunk / 4; + printer->Print("cached_has_bits = from._has_bits_[$new_index$];\n", + "new_index", SimpleItoa(new_index)); + cached_has_bit_index = new_index; + } + printer->Print( - "if (from._has_bits_[$index$ / 32] & $mask$u) {\n", - "index", SimpleItoa(last_chunk * 8), + "if (cached_has_bits & $mask$u) {\n", "mask", SimpleItoa(last_chunk_mask)); printer->Indent(); } // Go back and emit clears for each of the fields we processed. + bool deferred_has_bit_changes = false; for (int j = last_chunk_start; j <= last_chunk_end; j++) { const FieldDescriptor* field = optimized_order_[j]; const FieldGenerator& generator = field_generators_.get(field); bool have_enclosing_if = false; if (HasFieldPresence(descriptor_->file())) { - printer->Print( - "if (from.has_$name$()) {\n", - "name", FieldName(field)); + // Attempt to use the state of cached_has_bits, if possible. + int has_bit_index = has_bit_indices_[field->index()]; + if (!field->options().weak() && + cached_has_bit_index == has_bit_index / 32) { + const string mask = StrCat( + strings::Hex(1u << (has_bit_index % 32), + strings::ZERO_PAD_8)); + + printer->Print( + "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask); + } else { + printer->Print( + "if (from.has_$name$()) {\n", + "name", FieldName(field)); + } + printer->Indent(); have_enclosing_if = true; } else { @@ -2805,7 +3141,17 @@ GenerateMergeFrom(io::Printer* printer) { printer, "from.", field); } - generator.GenerateMergingCode(printer); + if (have_outer_if && IsPOD(field)) { + // GenerateCopyConstructorCode for enum and primitive scalar fields + // does not do _has_bits_ modifications. We defer _has_bits_ + // manipulation until the end of the outer if. + // + // This can reduce the number of loads/stores by up to 7 per 8 fields. + deferred_has_bit_changes = true; + generator.GenerateCopyConstructorCode(printer); + } else { + generator.GenerateMergingCode(printer); + } if (have_enclosing_if) { printer->Outdent(); @@ -2814,6 +3160,14 @@ GenerateMergeFrom(io::Printer* printer) { } if (have_outer_if) { + if (deferred_has_bit_changes) { + // Flush the has bits for the primitives we deferred. + GOOGLE_CHECK_LE(0, cached_has_bit_index); + printer->Print( + "_has_bits_[$index$] |= cached_has_bits;\n", + "index", SimpleItoa(cached_has_bit_index)); + } + printer->Outdent(); printer->Print("}\n"); } @@ -2849,6 +3203,9 @@ GenerateMergeFrom(io::Printer* printer) { printer->Print( "}\n"); } + if (num_weak_fields_) { + printer->Print("_weak_field_map_.MergeFrom(from._weak_field_map_);\n"); + } printer->Outdent(); printer->Print("}\n"); @@ -2913,13 +3270,36 @@ GenerateMergeFromCodedStream(io::Printer* printer) { return; } + std::vector ordered_fields = + SortFieldsByNumber(descriptor_); + printer->Print( "bool $classname$::MergePartialFromCodedStream(\n" - " ::google::protobuf::io::CodedInputStream* input) {\n" - "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n" - " ::google::protobuf::uint32 tag;\n", + " ::google::protobuf::io::CodedInputStream* input) {\n", "classname", classname_); + if (table_driven_) { + printer->Indent(); + + printer->Print( + "return ::google::protobuf::internal::MergePartialFromCodedStream(\n" + " this,\n" + " $file_namespace$::TableStruct::schema[\n" + " $classname$::kIndexInFileMessages],\n" + " input);\n", + "classname", classname_, + "file_namespace", FileLevelNamespace(descriptor_->file()->name())); + + printer->Outdent(); + + printer->Print("}\n"); + return; + } + + printer->Print( + "#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure\n" + " ::google::protobuf::uint32 tag;\n"); + if (PreserveUnknownFields(descriptor_) && !UseUnknownFieldSet(descriptor_->file(), options_)) { // Use LazyStringOutputString to avoid initializing unknown fields string @@ -2928,7 +3308,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print( " ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(\n" " ::google::protobuf::NewPermanentCallback(&_internal_metadata_,\n" - " &::google::protobuf::internal::InternalMetadataWithArenaLite::mutable_unknown_fields));\n" + " &::google::protobuf::internal::InternalMetadataWithArenaLite::\n" + " mutable_unknown_fields));\n" " ::google::protobuf::io::CodedOutputStream unknown_fields_stream(\n" " &unknown_fields_string, false);\n", "classname", classname_); @@ -2942,8 +3323,6 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Print("for (;;) {\n"); printer->Indent(); - std::vector ordered_fields = - SortFieldsByNumber(descriptor_); uint32 maxtag = descriptor_->field_count() == 0 ? 0 : WireFormat::MakeTag(ordered_fields[descriptor_->field_count() - 1]); const int kCutoff0 = 127; // fits in 1-byte varint @@ -3004,20 +3383,8 @@ GenerateMergeFromCodedStream(io::Printer* printer) { printer->Indent(); - // Find repeated messages and groups now, to simplify what follows. - hash_set fields_with_parse_loop; - for (int i = 0; i < ordered_fields.size(); i++) { - const FieldDescriptor* field = ordered_fields[i]; - if (field->is_repeated() && - (field->type() == FieldDescriptor::TYPE_MESSAGE || - field->type() == FieldDescriptor::TYPE_GROUP)) { - fields_with_parse_loop.insert(i); - } - } - for (int i = 0; i < ordered_fields.size(); i++) { const FieldDescriptor* field = ordered_fields[i]; - const bool loops = fields_with_parse_loop.count(i) > 0; PrintFieldComment(printer, field); @@ -3030,11 +3397,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { // Emit code to parse the common, expected case. printer->Print("if (static_cast< ::google::protobuf::uint8>(tag) ==\n" " static_cast< ::google::protobuf::uint8>($commontag$u)) {\n", - "commontag", SimpleItoa(WireFormat::MakeTag(field))); - - if (loops) { - printer->Print(" DO_(input->IncrementRecursionDepth());\n"); - } + "commontag", SimpleItoa(WireFormat::MakeTag(field))); printer->Indent(); if (field->is_packed()) { @@ -3074,12 +3437,6 @@ GenerateMergeFromCodedStream(io::Printer* printer) { " goto handle_unusual;\n" "}\n"); - // For repeated messages/groups, we need to decrement recursion depth. - if (loops) { - printer->Print( - "input->UnsafeDecrementRecursionDepth();\n"); - } - printer->Print( "break;\n"); @@ -3194,7 +3551,7 @@ void MessageGenerator::GenerateSerializeOneofFields( bool to_array) { GOOGLE_CHECK(!fields.empty()); if (fields.size() == 1) { - GenerateSerializeOneField(printer, fields[0], to_array); + GenerateSerializeOneField(printer, fields[0], to_array, -1); return; } // We have multiple mutually exclusive choices. Emit a switch statement. @@ -3227,14 +3584,31 @@ void MessageGenerator::GenerateSerializeOneofFields( } void MessageGenerator::GenerateSerializeOneField( - io::Printer* printer, const FieldDescriptor* field, bool to_array) { - PrintFieldComment(printer, field); + io::Printer* printer, const FieldDescriptor* field, bool to_array, + int cached_has_bits_index) { + if (!field->options().weak()) { + // For weakfields, PrintFieldComment is called during iteration. + PrintFieldComment(printer, field); + } bool have_enclosing_if = false; - if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) { - printer->Print( - "if (has_$name$()) {\n", - "name", FieldName(field)); + if (field->options().weak()) { + } else if (!field->is_repeated() && HasFieldPresence(descriptor_->file())) { + // Attempt to use the state of cached_has_bits, if possible. + int has_bit_index = has_bit_indices_[field->index()]; + if (cached_has_bits_index == has_bit_index / 32) { + const string mask = StrCat( + strings::Hex(1u << (has_bit_index % 32), + strings::ZERO_PAD_8)); + + printer->Print( + "if (cached_has_bits & 0x$mask$u) {\n", "mask", mask); + } else { + printer->Print( + "if (has_$name$()) {\n", + "name", FieldName(field)); + } + printer->Indent(); have_enclosing_if = true; } else if (!HasFieldPresence(descriptor_->file())) { @@ -3341,7 +3715,6 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) { "classname", classname_); printer->Indent(); - printer->Print("(void)deterministic; // Unused\n"); printer->Print( "// @@protoc_insertion_point(serialize_to_array_start:$full_name$)\n", "full_name", descriptor_->full_name()); @@ -3372,7 +3745,8 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { : mg_(mg), printer_(printer), to_array_(to_array), - eager_(!HasFieldPresence(mg->descriptor_->file())) {} + eager_(!HasFieldPresence(mg->descriptor_->file())), + cached_has_bit_index_(-1) {} ~LazySerializerEmitter() { Flush(); } @@ -3383,7 +3757,27 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { Flush(); } if (field->containing_oneof() == NULL) { - mg_->GenerateSerializeOneField(printer_, field, to_array_); + // TODO(ckennelly): Defer non-oneof fields similarly to oneof fields. + + if (!field->options().weak() && !field->is_repeated() && !eager_) { + // We speculatively load the entire _has_bits_[index] contents, even + // if it is for only one field. Deferring non-oneof emitting would + // allow us to determine whether this is going to be useful. + int has_bit_index = mg_->has_bit_indices_[field->index()]; + if (cached_has_bit_index_ != has_bit_index / 32) { + // Reload. + int new_index = has_bit_index / 32; + + printer_->Print( + "cached_has_bits = _has_bits_[$new_index$];\n", + "new_index", SimpleItoa(new_index)); + + cached_has_bit_index_ = new_index; + } + } + + mg_->GenerateSerializeOneField( + printer_, field, to_array_, cached_has_bit_index_); } else { v_.push_back(field); } @@ -3409,6 +3803,11 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { const bool to_array_; const bool eager_; std::vector v_; + + // cached_has_bit_index_ maintains that: + // cached_has_bits = from._has_bits_[cached_has_bit_index_] + // for cached_has_bit_index_ >= 0 + int cached_has_bit_index_; }; std::vector ordered_fields = @@ -3420,29 +3819,51 @@ GenerateSerializeWithCachedSizesBody(io::Printer* printer, bool to_array) { } std::sort(sorted_extensions.begin(), sorted_extensions.end(), ExtensionRangeSorter()); + if (num_weak_fields_) { + printer->Print( + "::google::protobuf::internal::WeakFieldMap::FieldWriter field_writer(" + "_weak_field_map_);\n"); + } + + printer->Print( + "::google::protobuf::uint32 cached_has_bits = 0;\n" + "(void) cached_has_bits;\n\n"); // Merge the fields and the extension ranges, both sorted by field number. { LazySerializerEmitter e(this, printer, to_array); + const FieldDescriptor* last_weak_field = NULL; int i, j; for (i = 0, j = 0; i < ordered_fields.size() || j < sorted_extensions.size();) { - if (i == descriptor_->field_count()) { - e.Flush(); - GenerateSerializeOneExtensionRange(printer, - sorted_extensions[j++], - to_array); - } else if (j == sorted_extensions.size()) { - e.Emit(ordered_fields[i++]); - } else if (ordered_fields[i]->number() < sorted_extensions[j]->start) { - e.Emit(ordered_fields[i++]); - } else { + if ((j == sorted_extensions.size()) || + (i < descriptor_->field_count() && + ordered_fields[i]->number() < sorted_extensions[j]->start)) { + const FieldDescriptor* field = ordered_fields[i++]; + if (field->options().weak()) { + last_weak_field = field; + PrintFieldComment(printer, field); + } else { + if (last_weak_field != NULL) { + e.Emit(last_weak_field); + last_weak_field = NULL; + } + e.Emit(field); + } + } else { + if (last_weak_field != NULL) { + e.Emit(last_weak_field); + last_weak_field = NULL; + } e.Flush(); GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++], to_array); } } + if (last_weak_field != NULL) { + e.Emit(last_weak_field); + } } if (PreserveUnknownFields(descriptor_)) { @@ -3783,6 +4204,11 @@ GenerateByteSize(io::Printer* printer) { "}\n"); } + if (num_weak_fields_) { + // TagSize + MessageSize + printer->Print("total_size += _weak_field_map_.ByteSizeLong();\n"); + } + // We update _cached_size_ even though this is a const method. In theory, // this is not thread-compatible, because concurrent writes have undefined // results. In practice, since any concurrent writes will be writing the @@ -3840,26 +4266,28 @@ GenerateIsInitialized(io::Printer* printer) { // TODO(ckennelly): Push this down into a generator? if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && - HasRequiredFields(field->message_type(), options_)) { + scc_analyzer_->HasRequiredFields(field->message_type())) { if (field->is_repeated()) { printer->Print( "if (!::google::protobuf::internal::AllAreInitialized(this->$name$()))" " return false;\n", "name", FieldName(field)); + } else if (field->options().weak()) { + continue; } else { - GOOGLE_CHECK(field->options().weak() || !field->containing_oneof()); - // For weak fields, use the data member (::google::protobuf::Message*) instead - // of the getter to avoid a link dependency on the weak message type - // which is only forward declared. + GOOGLE_CHECK(!field->containing_oneof()); printer->Print( "if (has_$name$()) {\n" " if (!this->$name$_->IsInitialized()) return false;\n" "}\n", - "name", FieldName(field)); + "name", FieldName(field)); } } } - + if (num_weak_fields_) { + // For Weak fields. + printer->Print("if (!_weak_field_map_.IsInitialized()) return false;\n"); + } // Go through the oneof fields, emitting a switch if any might have required // fields. for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { @@ -3871,7 +4299,7 @@ GenerateIsInitialized(io::Printer* printer) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && - HasRequiredFields(field->message_type(), options_)) { + scc_analyzer_->HasRequiredFields(field->message_type())) { has_required_fields = true; break; } @@ -3894,17 +4322,10 @@ GenerateIsInitialized(io::Printer* printer) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !ShouldIgnoreRequiredFieldCheck(field, options_) && - HasRequiredFields(field->message_type(), options_)) { + scc_analyzer_->HasRequiredFields(field->message_type())) { GOOGLE_CHECK(!(field->options().weak() || !field->containing_oneof())); if (field->options().weak()) { - // For weak fields, use the data member (::google::protobuf::Message*) instead - // of the getter to avoid a link dependency on the weak message type - // which is only forward declared. - printer->Print( - "if (has_$name$()) {\n" - " if (!this->$name$_->IsInitialized()) return false;\n" - "}\n", - "name", FieldName(field)); + // Just skip. } else { printer->Print( "if (has_$name$()) {\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_message.h b/src/google/protobuf/compiler/cpp/cpp_message.h index 1a804a16..23aaeeb0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.h +++ b/src/google/protobuf/compiler/cpp/cpp_message.h @@ -42,6 +42,7 @@ #include #include #include +#include #include namespace google { @@ -61,7 +62,8 @@ class ExtensionGenerator; // extension.h class MessageGenerator { public: // See generator.cc for the meaning of dllexport_decl. - MessageGenerator(const Descriptor* descriptor, const Options& options); + MessageGenerator(const Descriptor* descriptor, const Options& options, + SCCAnalyzer* scc_analyzer); ~MessageGenerator(); // Appends the pre-order walk of the nested generators to list. @@ -94,10 +96,6 @@ class MessageGenerator { // Generate extra fields void GenerateExtraDefaultFields(io::Printer* printer); - // Generate code that calls MessageFactory::InternalRegisterGeneratedMessage() - // for all types. - void GenerateTypeRegistrations(io::Printer* printer); - // Generates code that allocates the message's default instance. void GenerateDefaultInstanceAllocator(io::Printer* printer); @@ -121,6 +119,15 @@ class MessageGenerator { void GenerateDependentFieldAccessorDefinitions(io::Printer* printer); void GenerateFieldAccessorDefinitions(io::Printer* printer, bool is_inline); + // Generate the table-driven parsing array. Returns the number of entries + // generated. + size_t GenerateParseOffsets(io::Printer* printer); + size_t GenerateParseAuxTable(io::Printer* printer); + // Generates a ParseTable entry. Returns whether the proto uses table-driven + // parsing. + bool GenerateParseTable(io::Printer* printer, size_t offset, + size_t aux_offset); + // Generate the field offsets array. Returns the a pair of the total numer // of entries generated and the index of the first has_bit entry. std::pair GenerateOffsets(io::Printer* printer); @@ -155,9 +162,14 @@ class MessageGenerator { void GenerateIsInitialized(io::Printer* printer); // Helpers for GenerateSerializeWithCachedSizes(). + // + // cached_has_bit_index maintains that: + // cached_has_bits = _has_bits_[cached_has_bit_index] + // for cached_has_bit_index >= 0 void GenerateSerializeOneField(io::Printer* printer, const FieldDescriptor* field, - bool unbounded); + bool unbounded, + int cached_has_bits_index); // Generate a switch statement to serialize 2+ fields from the same oneof. // Or, if fields.size() == 1, just call GenerateSerializeOneField(). void GenerateSerializeOneofFields( @@ -197,7 +209,7 @@ class MessageGenerator { // optimized_order_ is the order we layout the message's fields in the class. // This is reused to initialize the fields in-order for cache efficiency. // - // optimized_order_ excludes oneof fields. + // optimized_order_ excludes oneof fields and weak fields. std::vector optimized_order_; std::vector has_bit_indices_; int max_has_bit_index_; @@ -206,8 +218,13 @@ class MessageGenerator { google::protobuf::scoped_array > extension_generators_; int num_required_fields_; bool use_dependent_base_; + int num_weak_fields_; + // table_driven_ indicates the generated message uses table-driven parsing. + bool table_driven_; + + int index_in_file_messages_; - int index_in_metadata_; + SCCAnalyzer* scc_analyzer_; friend class FileGenerator; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.cc b/src/google/protobuf/compiler/cpp/cpp_message_field.cc index c3d1745c..fc3c4564 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.cc @@ -35,6 +35,7 @@ #include #include #include + #include namespace google { @@ -583,7 +584,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { printer->Print(variables_, "target = ::google::protobuf::internal::WireFormatLite::\n" " InternalWrite$declared_type$NoVirtualToArray(\n" - " $number$, *$non_null_ptr_to_name$, false, target);\n"); + " $number$, *$non_null_ptr_to_name$, deterministic, target);\n"); } void MessageFieldGenerator:: @@ -670,15 +671,6 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, InternalGenerateInlineAccessorDefinitions(variables, printer); } -void MessageOneofFieldGenerator:: -GenerateNonInlineAccessorDefinitions(io::Printer* printer) const { - std::map variables(variables_); - variables["field_member"] = - variables["oneof_prefix"] + variables["name"] + "_"; - - //printer->Print(variables, -} - void MessageOneofFieldGenerator::InternalGenerateInlineAccessorDefinitions( const std::map& variables, io::Printer* printer) const { printer->Print(variables, @@ -1066,7 +1058,7 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedMessageFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n"); + printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); } void RepeatedMessageFieldGenerator:: @@ -1079,12 +1071,12 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { if (descriptor_->type() == FieldDescriptor::TYPE_MESSAGE) { printer->Print(variables_, "DO_(::google::protobuf::internal::WireFormatLite::" - "ReadMessageNoVirtualNoRecursionDepth(\n" + "ReadMessageNoVirtual(\n" " input, add_$name$()));\n"); } else { printer->Print(variables_, "DO_(::google::protobuf::internal::WireFormatLite::" - "ReadGroupNoVirtualNoRecursionDepth(\n" + "ReadGroupNoVirtual(\n" " $number$, input, add_$name$()));\n"); } } @@ -1104,7 +1096,7 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { "for (unsigned int i = 0, n = this->$name$_size(); i < n; i++) {\n" " target = ::google::protobuf::internal::WireFormatLite::\n" " InternalWrite$declared_type$NoVirtualToArray(\n" - " $number$, this->$name$(i), false, target);\n" + " $number$, this->$name$(i), deterministic, target);\n" "}\n"); } diff --git a/src/google/protobuf/compiler/cpp/cpp_message_field.h b/src/google/protobuf/compiler/cpp/cpp_message_field.h index 9ca91153..cd9737f0 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message_field.h +++ b/src/google/protobuf/compiler/cpp/cpp_message_field.h @@ -95,7 +95,7 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator { 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; // MessageFieldGenerator, from which we inherit, overrides this so we need to diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index ee44fb0a..bdaa12a5 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -46,16 +46,18 @@ struct Options { Options() : safe_boundary_check(false), proto_h(false), - allow_import_public(true), + transitive_pb_h(true), annotate_headers(false), - enforce_lite(false) {} + enforce_lite(false), + table_driven_parsing(false) {} string dllexport_decl; bool safe_boundary_check; bool proto_h; - bool allow_import_public; + bool transitive_pb_h; bool annotate_headers; bool enforce_lite; + bool table_driven_parsing; string annotation_pragma_name; string annotation_guard_name; }; diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 4a0a23f6..020c1941 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -342,7 +342,7 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedPrimitiveFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n"); + printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); } void RepeatedPrimitiveFieldGenerator:: @@ -385,6 +385,9 @@ GenerateSerializeWithCachedSizes(io::Printer* printer) const { " output->WriteVarint32(_$name$_cached_byte_size_);\n"); if (FixedSize(descriptor_->type()) > 0) { + // TODO(ckennelly): Use RepeatedField::unsafe_data() via + // WireFormatLite to access the contents of this->$name$_ to save a branch + // here. printer->Print(variables_, " ::google::protobuf::internal::WireFormatLite::Write$declared_type$Array(\n" " this->$name$().data(), this->$name$_size(), output);\n"); @@ -420,20 +423,14 @@ GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const { " target);\n" " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n" " _$name$_cached_byte_size_, target);\n" - "}\n"); - } - printer->Print(variables_, - "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"); - if (descriptor_->is_packed()) { - printer->Print(variables_, " target = ::google::protobuf::internal::WireFormatLite::\n" - " Write$declared_type$NoTagToArray(this->$name$(i), target);\n"); + " Write$declared_type$NoTagToArray(this->$name$_, target);\n" + "}\n"); } else { printer->Print(variables_, - " target = ::google::protobuf::internal::WireFormatLite::\n" - " Write$declared_type$ToArray($number$, this->$name$(i), target);\n"); + "target = ::google::protobuf::internal::WireFormatLite::\n" + " Write$declared_type$ToArray($number$, this->$name$_, target);\n"); } - printer->Print("}\n"); } void RepeatedPrimitiveFieldGenerator:: diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 664a2779..7a849e2e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -36,6 +36,7 @@ #include #include #include + #include namespace google { @@ -61,6 +62,7 @@ void SetStringVariables(const FieldDescriptor* descriptor, ".get()"; (*variables)["pointer_type"] = descriptor->type() == FieldDescriptor::TYPE_BYTES ? "void" : "char"; + (*variables)["null_check"] = "GOOGLE_DCHECK(value != NULL);\n"; // NOTE: Escaped here to unblock proto1->proto2 migration. // TODO(liujisi): Extend this to apply for other conflicting methods. (*variables)["release_name"] = @@ -190,6 +192,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "$inline$void $classname$::set_$name$(const char* value) {\n" + " $null_check$" " $set_hasbit$\n" " $name$_.Set($default_variable$, $string_piece$(value),\n" " GetArenaNoVirtual());\n" @@ -267,6 +270,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, "}\n" "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" + " $null_check$" " $set_hasbit$\n" " $name$_.SetNoArena($default_variable$, $string_piece$(value));\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" @@ -548,6 +552,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, " // @@protoc_insertion_point(field_set:$full_name$)\n" "}\n" "$inline$void $classname$::set_$name$(const char* value) {\n" + " $null_check$" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -664,6 +669,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, "}\n" "#endif\n" "$inline$void $classname$::set_$name$(const char* value) {\n" + " $null_check$" " if (!has_$name$()) {\n" " clear_$oneof_name$();\n" " set_has_$name$();\n" @@ -882,6 +888,7 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, "}\n" "#endif\n" "$inline$void $classname$::set_$name$(int index, const char* value) {\n" + " $null_check$" " $name$_.Mutable(index)->assign(value);\n" " // @@protoc_insertion_point(field_set_char:$full_name$)\n" "}\n" @@ -902,11 +909,12 @@ GenerateInlineAccessorDefinitions(io::Printer* printer, "}\n" "#if LANG_CXX11\n" "$inline$void $classname$::add_$name$(::std::string&& value) {\n" - " $name$_.Add()->assign(std::move(value));\n" + " $name$_.Add(std::move(value));\n" " // @@protoc_insertion_point(field_add:$full_name$)\n" "}\n" "#endif\n" "$inline$void $classname$::add_$name$(const char* value) {\n" + " $null_check$" " $name$_.Add()->assign(value);\n" " // @@protoc_insertion_point(field_add_char:$full_name$)\n" "}\n" @@ -939,7 +947,7 @@ GenerateMergingCode(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateSwappingCode(io::Printer* printer) const { - printer->Print(variables_, "$name$_.UnsafeArenaSwap(&other->$name$_);\n"); + printer->Print(variables_, "$name$_.InternalSwap(&other->$name$_);\n"); } void RepeatedStringFieldGenerator:: @@ -969,7 +977,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) const { void RepeatedStringFieldGenerator:: GenerateSerializeWithCachedSizes(io::Printer* printer) const { printer->Print(variables_, - "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"); + "for (int i = 0, n = this->$name$_size(); i < n; i++) {\n"); printer->Indent(); if (descriptor_->type() == FieldDescriptor::TYPE_STRING) { GenerateUtf8CheckCodeForString( diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 6d68ec35..e56964c7 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -76,7 +76,6 @@ #include #include #include -#include #include #include #include @@ -2162,6 +2161,61 @@ TEST_F(OneofTest, MergeFrom) { } +TEST(HelpersTest, TestSCC) { + protobuf_unittest::TestMutualRecursionA a; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(a.GetDescriptor()); + std::vector names; + for (int i = 0; i < scc->descriptors.size(); i++) { + names.push_back(scc->descriptors[i]->full_name()); + } + ASSERT_EQ(names.size(), 4); + std::sort(names.begin(), names.end()); + EXPECT_EQ(names[0], "protobuf_unittest.TestMutualRecursionA"); + EXPECT_EQ(names[1], "protobuf_unittest.TestMutualRecursionA.SubGroup"); + EXPECT_EQ(names[2], "protobuf_unittest.TestMutualRecursionA.SubMessage"); + EXPECT_EQ(names[3], "protobuf_unittest.TestMutualRecursionB"); + + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, true); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, true); // TestAllTypes + EXPECT_EQ(result.contains_extension, false); // TestAllTypes +} + +TEST(HelpersTest, TestSCCAnalysis) { + { + protobuf_unittest::TestRecursiveMessage msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, true); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, false); + } + { + protobuf_unittest::TestAllExtensions msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, false); + EXPECT_EQ(result.contains_required, false); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, true); + } + { + protobuf_unittest::TestRequired msg; + SCCAnalyzer scc_analyzer((Options())); + const SCC* scc = scc_analyzer.GetSCC(msg.GetDescriptor()); + MessageAnalysis result = scc_analyzer.GetSCCAnalysis(scc); + EXPECT_EQ(result.is_recursive, false); + EXPECT_EQ(result.contains_required, true); + EXPECT_EQ(result.contains_cord, false); + EXPECT_EQ(result.contains_extension, false); + } +} + } // namespace cpp_unittest } // namespace cpp } // namespace compiler diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc index 462748b9..844edc1c 100644 --- a/src/google/protobuf/compiler/importer.cc +++ b/src/google/protobuf/compiler/importer.cc @@ -222,6 +222,7 @@ void Importer::ClearUnusedImportTrackFiles() { pool_.ClearUnusedImportTrackFiles(); } + // =================================================================== SourceTree::~SourceTree() {} diff --git a/src/google/protobuf/compiler/importer.h b/src/google/protobuf/compiler/importer.h index 759636e1..a4ffcf87 100644 --- a/src/google/protobuf/compiler/importer.h +++ b/src/google/protobuf/compiler/importer.h @@ -175,6 +175,7 @@ class LIBPROTOBUF_EXPORT Importer { void AddUnusedImportTrackFile(const string& file_name); void ClearUnusedImportTrackFiles(); + private: SourceTreeDescriptorDatabase database_; DescriptorPool pool_; diff --git a/src/google/protobuf/compiler/importer_unittest.cc b/src/google/protobuf/compiler/importer_unittest.cc index 00285bcc..a96ac853 100644 --- a/src/google/protobuf/compiler/importer_unittest.cc +++ b/src/google/protobuf/compiler/importer_unittest.cc @@ -47,11 +47,11 @@ #include #include #include -#include #include #include #include #include +#include namespace google { namespace protobuf { 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 50eed5da..1eefdcfc 100644 --- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc @@ -314,6 +314,7 @@ GenerateParsingDoneCode(io::Printer* printer) const { // noop for enums } + void ImmutableEnumFieldLiteGenerator:: GenerateSerializationCode(io::Printer* printer) const { printer->Print(variables_, @@ -423,6 +424,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); } + void ImmutableEnumOneofFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { @@ -707,6 +709,7 @@ GenerateMembers(io::Printer* printer) const { } } + void RepeatedImmutableEnumFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { WriteFieldDocComment(printer, descriptor_); diff --git a/src/google/protobuf/compiler/java/java_enum_lite.cc b/src/google/protobuf/compiler/java/java_enum_lite.cc index 96815920..38b054e7 100644 --- a/src/google/protobuf/compiler/java/java_enum_lite.cc +++ b/src/google/protobuf/compiler/java/java_enum_lite.cc @@ -49,17 +49,6 @@ 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), @@ -139,22 +128,30 @@ void EnumLiteGenerator::Generate(io::Printer* printer) { // ----------------------------------------------------------------- printer->Print( - "\n" - "public final int getNumber() {\n" - " return value;\n" - "}\n" - "\n" - "/**\n" - " * @deprecated Use {@link #forNumber(int)} instead.\n" - " */\n" - "@java.lang.Deprecated\n" - "public static $classname$ valueOf(int value) {\n" - " return forNumber(value);\n" - "}\n" - "\n" - "public static $classname$ forNumber(int value) {\n" - " switch (value) {\n", - "classname", descriptor_->name()); + "\n" + "public final int getNumber() {\n"); + if (SupportUnknownEnumValue(descriptor_->file())) { + printer->Print( + " if (this == UNRECOGNIZED) {\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" + "/**\n" + " * @deprecated Use {@link #forNumber(int)} instead.\n" + " */\n" + "@java.lang.Deprecated\n" + "public static $classname$ valueOf(int value) {\n" + " return forNumber(value);\n" + "}\n" + "\n" + "public static $classname$ forNumber(int value) {\n" + " switch (value) {\n", + "classname", descriptor_->name()); printer->Indent(); printer->Indent(); diff --git a/src/google/protobuf/compiler/java/java_field.h b/src/google/protobuf/compiler/java/java_field.h index 434e610c..cc1d83d9 100644 --- a/src/google/protobuf/compiler/java/java_field.h +++ b/src/google/protobuf/compiler/java/java_field.h @@ -119,6 +119,7 @@ class ImmutableFieldLiteGenerator { virtual void GenerateEqualsCode(io::Printer* printer) const = 0; virtual void GenerateHashCode(io::Printer* printer) const = 0; + virtual string GetBoxedType() const = 0; private: diff --git a/src/google/protobuf/compiler/java/java_file.cc b/src/google/protobuf/compiler/java/java_file.cc index 86719f70..0fda166d 100644 --- a/src/google/protobuf/compiler/java/java_file.cc +++ b/src/google/protobuf/compiler/java/java_file.cc @@ -154,12 +154,6 @@ void CollectExtensions(const FileDescriptorProto& file_proto, } } -// Compare two field descriptors, returning true if the first should come -// before the second. -bool CompareFieldsByName(const FieldDescriptor *a, const FieldDescriptor *b) { - return a->full_name() < b->full_name(); -} - // Our static initialization methods can become very, very large. // So large that if we aren't careful we end up blowing the JVM's // 64K bytes of bytecode/method. Fortunately, since these static diff --git a/src/google/protobuf/compiler/java/java_generator.cc b/src/google/protobuf/compiler/java/java_generator.cc index 2c02d996..02141210 100644 --- a/src/google/protobuf/compiler/java/java_generator.cc +++ b/src/google/protobuf/compiler/java/java_generator.cc @@ -47,6 +47,7 @@ #include #include #include + #include namespace google { diff --git a/src/google/protobuf/compiler/java/java_helpers.cc b/src/google/protobuf/compiler/java/java_helpers.cc index efb5fd45..8469740f 100644 --- a/src/google/protobuf/compiler/java/java_helpers.cc +++ b/src/google/protobuf/compiler/java/java_helpers.cc @@ -43,6 +43,7 @@ #include #include #include +#include // for hash namespace google { namespace protobuf { @@ -245,6 +246,7 @@ string ClassName(const FileDescriptor* descriptor) { return name_resolver.GetClassName(descriptor, true); } + string ExtraMessageInterfaces(const Descriptor* descriptor) { string interfaces = "// @@protoc_insertion_point(message_implements:" + descriptor->full_name() + ")"; diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc index 49070ba0..51bb11f1 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.cc @@ -232,6 +232,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); } + // =================================================================== ImmutableLazyMessageOneofFieldLiteGenerator:: @@ -415,6 +416,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); } + // =================================================================== RepeatedImmutableLazyMessageFieldLiteGenerator:: @@ -716,6 +718,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const { "}\n"); } + } // namespace java } // namespace compiler } // namespace protobuf diff --git a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h index 47ebeb49..65b84fbc 100644 --- a/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h +++ b/src/google/protobuf/compiler/java/java_lazy_message_field_lite.h @@ -68,6 +68,7 @@ class ImmutableLazyMessageFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageFieldLiteGenerator); }; @@ -87,6 +88,7 @@ class ImmutableLazyMessageOneofFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableLazyMessageOneofFieldLiteGenerator); }; @@ -106,6 +108,7 @@ class RepeatedImmutableLazyMessageFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedImmutableLazyMessageFieldLiteGenerator); }; 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 523052cc..36fa2b7b 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc @@ -484,6 +484,7 @@ GenerateMembers(io::Printer* printer) const { } } + void ImmutableMapFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { printer->Print( diff --git a/src/google/protobuf/compiler/java/java_map_field_lite.h b/src/google/protobuf/compiler/java/java_map_field_lite.h index 63dedbc2..94aa4813 100644 --- a/src/google/protobuf/compiler/java/java_map_field_lite.h +++ b/src/google/protobuf/compiler/java/java_map_field_lite.h @@ -62,6 +62,7 @@ class ImmutableMapFieldLiteGenerator : public ImmutableFieldLiteGenerator { void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; private: diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 3b8d7ab8..6e3b4a75 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -685,6 +685,17 @@ GenerateParseFromMethods(io::Printer* printer) { // because they need to be generated even for messages that are optimized // for code size. printer->Print( + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return PARSER.parseFrom(data, extensionRegistry);\n" + "}\n" "public static $classname$ parseFrom(\n" " com.google.protobuf.ByteString data)\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n" diff --git a/src/google/protobuf/compiler/java/java_message_builder_lite.cc b/src/google/protobuf/compiler/java/java_message_builder_lite.cc index 7e404ba1..1ad58c09 100644 --- a/src/google/protobuf/compiler/java/java_message_builder_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_builder_lite.cc @@ -67,13 +67,6 @@ bool GenerateHasBits(const Descriptor* descriptor) { return SupportFieldPresence(descriptor->file()) || HasRepeatedFields(descriptor); } - -string MapValueImmutableClassdName(const Descriptor* descriptor, - ClassNameResolver* name_resolver) { - const FieldDescriptor* value_field = descriptor->FindFieldByName("value"); - GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, value_field->type()); - return name_resolver->GetImmutableClassName(value_field->message_type()); -} } // namespace MessageBuilderLiteGenerator::MessageBuilderLiteGenerator( 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 0957676c..c71e9101 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc @@ -451,6 +451,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); } + void ImmutableMessageOneofFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { // The comments above the methods below are based on a hypothetical @@ -856,6 +857,7 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { "get$capitalized_name$FieldBuilder();\n"); } + void RepeatedImmutableMessageFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = emptyProtobufList();\n"); diff --git a/src/google/protobuf/compiler/java/java_message_field_lite.h b/src/google/protobuf/compiler/java/java_message_field_lite.h index dbb263de..7c814c6d 100644 --- a/src/google/protobuf/compiler/java/java_message_field_lite.h +++ b/src/google/protobuf/compiler/java/java_message_field_lite.h @@ -106,6 +106,7 @@ class ImmutableMessageOneofFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableMessageOneofFieldLiteGenerator); }; @@ -135,6 +136,7 @@ class RepeatedImmutableMessageFieldLiteGenerator void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; protected: diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index e84321bb..5007ecee 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -398,6 +398,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { printer->Print( "}\n" + "// fall through\n" "case GET_DEFAULT_INSTANCE: {\n" " return DEFAULT_INSTANCE;\n" "}\n" @@ -588,6 +589,19 @@ GenerateParseFromMethods(io::Printer* printer) { // because they need to be generated even for messages that are optimized // for code size. printer->Print( + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data);\n" + "}\n" + "public static $classname$ parseFrom(\n" + " java.nio.ByteBuffer data,\n" + " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" + " throws com.google.protobuf.InvalidProtocolBufferException {\n" + " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" + " DEFAULT_INSTANCE, data, extensionRegistry);\n" + "}\n" "public static $classname$ parseFrom(\n" " com.google.protobuf.ByteString data)\n" " throws com.google.protobuf.InvalidProtocolBufferException {\n" @@ -1057,21 +1071,6 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream( // =================================================================== -namespace { -bool CheckHasBitsForEqualsAndHashCode(const FieldDescriptor* field) { - if (field->is_repeated()) { - return false; - } - if (SupportFieldPresence(field->file())) { - return true; - } - return GetJavaType(field) == JAVATYPE_MESSAGE && - field->containing_oneof() == NULL; -} -} // namespace - -// =================================================================== - void ImmutableMessageLiteGenerator:: GenerateExtensionRegistrationCode(io::Printer* printer) { for (int i = 0; i < descriptor_->extension_count(); i++) { 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 b04bf1c2..0e8e492f 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc @@ -297,6 +297,7 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for primitives } + void ImmutablePrimitiveFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { if (IsByteStringWithCustomDefaultValue(descriptor_)) { @@ -747,6 +748,7 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for primitives } + void RepeatedImmutablePrimitiveFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = $empty_list$;\n"); diff --git a/src/google/protobuf/compiler/java/java_primitive_field_lite.h b/src/google/protobuf/compiler/java/java_primitive_field_lite.h index dc59f0cf..93416f0b 100644 --- a/src/google/protobuf/compiler/java/java_primitive_field_lite.h +++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.h @@ -80,6 +80,7 @@ class ImmutablePrimitiveFieldLiteGenerator void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; protected: @@ -110,6 +111,7 @@ class ImmutablePrimitiveOneofFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutablePrimitiveOneofFieldLiteGenerator); }; @@ -142,6 +144,7 @@ class RepeatedImmutablePrimitiveFieldLiteGenerator void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; private: 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 138e59b6..7e3ad1d0 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.cc +++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc @@ -295,6 +295,7 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for strings } + void ImmutableStringFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = $default$;\n"); @@ -467,6 +468,7 @@ GenerateMembers(io::Printer* printer) const { "}\n"); } + void ImmutableStringOneofFieldLiteGenerator:: GenerateBuilderMembers(io::Printer* printer) const { if (SupportFieldPresence(descriptor_->file())) { @@ -763,6 +765,7 @@ GenerateFieldBuilderInitializationCode(io::Printer* printer) const { // noop for strings } + void RepeatedImmutableStringFieldLiteGenerator:: GenerateInitializationCode(io::Printer* printer) const { printer->Print(variables_, "$name$_ = $empty_list$;\n"); diff --git a/src/google/protobuf/compiler/java/java_string_field_lite.h b/src/google/protobuf/compiler/java/java_string_field_lite.h index 80496c87..b7fb6409 100644 --- a/src/google/protobuf/compiler/java/java_string_field_lite.h +++ b/src/google/protobuf/compiler/java/java_string_field_lite.h @@ -78,6 +78,7 @@ class ImmutableStringFieldLiteGenerator : public ImmutableFieldLiteGenerator { void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; protected: @@ -108,6 +109,7 @@ class ImmutableStringOneofFieldLiteGenerator void GenerateSerializationCode(io::Printer* printer) const; void GenerateSerializedSizeCode(io::Printer* printer) const; + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ImmutableStringOneofFieldLiteGenerator); }; @@ -136,6 +138,7 @@ class RepeatedImmutableStringFieldLiteGenerator void GenerateEqualsCode(io::Printer* printer) const; void GenerateHashCode(io::Printer* printer) const; + string GetBoxedType() const; private: diff --git a/src/google/protobuf/compiler/js/embed.cc b/src/google/protobuf/compiler/js/embed.cc index 57d38237..a725b62e 100644 --- a/src/google/protobuf/compiler/js/embed.cc +++ b/src/google/protobuf/compiler/js/embed.cc @@ -98,7 +98,7 @@ static void AddFile(const char* name, std::basic_ostream* out) { int main(int argc, char *argv[]) { std::cout << "#include " - "\n"; + "\"google/protobuf/compiler/js/well_known_types_embed.h\"\n"; std::cout << "struct FileToc well_known_types_js[] = {\n"; for (int i = 1; i < argc; i++) { diff --git a/src/google/protobuf/compiler/js/js_generator.cc b/src/google/protobuf/compiler/js/js_generator.cc index 727ed090..7c63e58f 100755 --- a/src/google/protobuf/compiler/js/js_generator.cc +++ b/src/google/protobuf/compiler/js/js_generator.cc @@ -198,8 +198,8 @@ string ModuleAlias(const string& filename) { // Returns the fully normalized JavaScript path for the given // file descriptor's package. -string GetPath(const GeneratorOptions& options, - const FileDescriptor* file) { +string GetFilePath(const GeneratorOptions& options, + const FileDescriptor* file) { if (!options.namespace_prefix.empty()) { return options.namespace_prefix; } else if (!file->package().empty()) { @@ -231,51 +231,32 @@ string GetNestedMessageName(const Descriptor* descriptor) { string GetPrefix(const GeneratorOptions& options, const FileDescriptor* file_descriptor, const Descriptor* containing_type) { - string prefix = - GetPath(options, file_descriptor) + GetNestedMessageName(containing_type); + string prefix = GetFilePath(options, file_descriptor) + + GetNestedMessageName(containing_type); if (!prefix.empty()) { prefix += "."; } return prefix; } - // Returns the fully normalized JavaScript path for the given // message descriptor. -string GetPath(const GeneratorOptions& options, - const Descriptor* descriptor) { +string GetMessagePath(const GeneratorOptions& options, + const Descriptor* descriptor) { return GetPrefix( options, descriptor->file(), descriptor->containing_type()) + descriptor->name(); } - -// Returns the fully normalized JavaScript path for the given -// field's containing message descriptor. -string GetPath(const GeneratorOptions& options, - const FieldDescriptor* descriptor) { - return GetPath(options, descriptor->containing_type()); -} - // Returns the fully normalized JavaScript path for the given // enumeration descriptor. -string GetPath(const GeneratorOptions& options, - const EnumDescriptor* enum_descriptor) { +string GetEnumPath(const GeneratorOptions& options, + const EnumDescriptor* enum_descriptor) { return GetPrefix( options, enum_descriptor->file(), enum_descriptor->containing_type()) + enum_descriptor->name(); } - -// Returns the fully normalized JavaScript path for the given -// enumeration value descriptor. -string GetPath(const GeneratorOptions& options, - const EnumValueDescriptor* value_descriptor) { - return GetPath( - options, - value_descriptor->type()) + "." + value_descriptor->name(); -} - string MaybeCrossFileRef(const GeneratorOptions& options, const FileDescriptor* from_file, const Descriptor* to_message) { @@ -288,7 +269,7 @@ string MaybeCrossFileRef(const GeneratorOptions& options, to_message->name(); } else { // Within a single file we use a full name. - return GetPath(options, to_message); + return GetMessagePath(options, to_message); } } @@ -413,7 +394,7 @@ string ToFileName(const string& input) { // that top-level extensions should go in. string GetExtensionFileName(const GeneratorOptions& options, const FileDescriptor* file) { - return options.output_dir + "/" + ToFileName(GetPath(options, file)) + + return options.output_dir + "/" + ToFileName(GetFilePath(options, file)) + options.GetFileNameExtension(); } @@ -550,14 +531,6 @@ string JSGetterName(const GeneratorOptions& options, return name; } -string JSMapGetterName(const GeneratorOptions& options, - const FieldDescriptor* field) { - return JSIdent(options, field, - /* is_upper_camel = */ true, - /* is_map = */ true, - /* drop_list = */ false); -} - string JSOneofName(const OneofDescriptor* oneof) { @@ -872,11 +845,11 @@ string ProtoTypeName(const GeneratorOptions& options, case FieldDescriptor::TYPE_BYTES: return "bytes"; case FieldDescriptor::TYPE_GROUP: - return GetPath(options, field->message_type()); + return GetMessagePath(options, field->message_type()); case FieldDescriptor::TYPE_ENUM: - return GetPath(options, field->enum_type()); + return GetEnumPath(options, field->enum_type()); case FieldDescriptor::TYPE_MESSAGE: - return GetPath(options, field->message_type()); + return GetMessagePath(options, field->message_type()); default: return ""; } @@ -925,9 +898,9 @@ string JSTypeName(const GeneratorOptions& options, case FieldDescriptor::CPPTYPE_STRING: return JSStringTypeName(options, field, bytes_mode); case FieldDescriptor::CPPTYPE_ENUM: - return GetPath(options, field->enum_type()); + return GetEnumPath(options, field->enum_type()); case FieldDescriptor::CPPTYPE_MESSAGE: - return GetPath(options, field->message_type()); + return GetMessagePath(options, field->message_type()); default: return ""; } @@ -1111,7 +1084,7 @@ static const char* kRepeatedFieldArrayName = ".repeatedFields_"; string RepeatedFieldsArrayName(const GeneratorOptions& options, const Descriptor* desc) { return HasRepeatedFields(options, desc) - ? (GetPath(options, desc) + kRepeatedFieldArrayName) + ? (GetMessagePath(options, desc) + kRepeatedFieldArrayName) : "null"; } @@ -1128,8 +1101,9 @@ static const char* kOneofGroupArrayName = ".oneofGroups_"; string OneofFieldsArrayName(const GeneratorOptions& options, const Descriptor* desc) { - return HasOneofFields(desc) ? - (GetPath(options, desc) + kOneofGroupArrayName) : "null"; + return HasOneofFields(desc) + ? (GetMessagePath(options, desc) + kOneofGroupArrayName) + : "null"; } string RepeatedFieldNumberList(const GeneratorOptions& options, @@ -1571,7 +1545,7 @@ void Generator::FindProvidesForMessage( return; } - string name = GetPath(options, desc); + string name = GetMessagePath(options, desc); provided->insert(name); for (int i = 0; i < desc->enum_type_count(); i++) { @@ -1588,7 +1562,7 @@ void Generator::FindProvidesForEnum(const GeneratorOptions& options, io::Printer* printer, const EnumDescriptor* enumdesc, std::set* provided) const { - string name = GetPath(options, enumdesc); + string name = GetEnumPath(options, enumdesc); provided->insert(name); } @@ -1604,9 +1578,8 @@ void Generator::FindProvidesForFields( continue; } - string name = - GetPath(options, field->file()) + "." + - JSObjectFieldName(options, field); + string name = GetFilePath(options, field->file()) + "." + + JSObjectFieldName(options, field); provided->insert(name); } } @@ -1684,7 +1657,7 @@ void Generator::GenerateRequiresForLibrary( } if (extension->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") { - required.insert(GetPath(options, extension->containing_type())); + required.insert(GetMessagePath(options, extension->containing_type())); } FindRequiresForField(options, extension, &required, &forwards); have_extensions = true; @@ -1805,13 +1778,13 @@ void Generator::FindRequiresForField(const GeneratorOptions& options, // dependencies, as per original codegen. !(field->is_extension() && field->extension_scope() == NULL)) { if (options.add_require_for_enums) { - required->insert(GetPath(options, field->enum_type())); + required->insert(GetEnumPath(options, field->enum_type())); } else { - forwards->insert(GetPath(options, field->enum_type())); + forwards->insert(GetEnumPath(options, field->enum_type())); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (!IgnoreMessage(options, field->message_type())) { - required->insert(GetPath(options, field->message_type())); + required->insert(GetMessagePath(options, field->message_type())); } } } @@ -1821,7 +1794,7 @@ void Generator::FindRequiresForExtension(const GeneratorOptions& options, std::set* required, std::set* forwards) const { if (field->containing_type()->full_name() != "google.protobuf.bridge.MessageSet") { - required->insert(GetPath(options, field->containing_type())); + required->insert(GetMessagePath(options, field->containing_type())); } FindRequiresForField(options, field, required, forwards); } @@ -1868,7 +1841,7 @@ void Generator::GenerateClass(const GeneratorOptions& options, } // Recurse on nested types. These must come *before* the extension-field - // info generation in GenerateClassRegistration so that extensions that + // info generation in GenerateClassRegistration so that extensions that // reference nested types proceed the definitions of the nested types. for (int i = 0; i < desc->enum_type_count(); i++) { GenerateEnum(options, printer, desc->enum_type(i)); @@ -1890,7 +1863,6 @@ void Generator::GenerateClass(const GeneratorOptions& options, } } } - } void Generator::GenerateClassConstructor(const GeneratorOptions& options, @@ -1912,7 +1884,7 @@ void Generator::GenerateClassConstructor(const GeneratorOptions& options, " * @constructor\n" " */\n" "$classname$ = function(opt_data) {\n", - "classname", GetPath(options, desc)); + "classname", GetMessagePath(options, desc)); string message_id = GetMessageId(desc); printer->Print( " jspb.Message.initialize(this, opt_data, $messageId$, $pivot$, " @@ -1929,7 +1901,7 @@ void Generator::GenerateClassConstructor(const GeneratorOptions& options, "if (goog.DEBUG && !COMPILED) {\n" " $classname$.displayName = '$classname$';\n" "}\n", - "classname", GetPath(options, desc)); + "classname", GetMessagePath(options, desc)); } void Generator::GenerateClassFieldInfo(const GeneratorOptions& options, @@ -1944,7 +1916,7 @@ void Generator::GenerateClassFieldInfo(const GeneratorOptions& options, " */\n" "$classname$$rptfieldarray$ = $rptfields$;\n" "\n", - "classname", GetPath(options, desc), + "classname", GetMessagePath(options, desc), "rptfieldarray", kRepeatedFieldArrayName, "rptfields", RepeatedFieldNumberList(options, desc)); } @@ -1965,7 +1937,7 @@ void Generator::GenerateClassFieldInfo(const GeneratorOptions& options, " */\n" "$classname$$oneofgrouparray$ = $oneofgroups$;\n" "\n", - "classname", GetPath(options, desc), + "classname", GetMessagePath(options, desc), "oneofgrouparray", kOneofGroupArrayName, "oneofgroups", OneofGroupList(desc)); @@ -1985,7 +1957,7 @@ void Generator::GenerateClassXid(const GeneratorOptions& options, "\n" "\n" "$class$.prototype.messageXid = xid('$class$');\n", - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); } void Generator::GenerateOneofCaseDefinition( @@ -1998,7 +1970,7 @@ void Generator::GenerateOneofCaseDefinition( " */\n" "$classname$.$oneof$Case = {\n" " $upcase$_NOT_SET: 0", - "classname", GetPath(options, oneof->containing_type()), + "classname", GetMessagePath(options, oneof->containing_type()), "oneof", JSOneofName(oneof), "upcase", ToEnumCase(oneof->name())); @@ -2026,7 +1998,7 @@ void Generator::GenerateOneofCaseDefinition( "computeOneofCase(this, $class$.oneofGroups_[$oneofindex$]));\n" "};\n" "\n", - "class", GetPath(options, oneof->containing_type()), + "class", GetMessagePath(options, oneof->containing_type()), "oneof", JSOneofName(oneof), "oneofindex", JSOneofIndex(oneof)); } @@ -2068,7 +2040,7 @@ void Generator::GenerateClassToObject(const GeneratorOptions& options, " */\n" "$classname$.toObject = function(includeInstance, msg) {\n" " var f, obj = {", - "classname", GetPath(options, desc)); + "classname", GetMessagePath(options, desc)); bool first = true; for (int i = 0; i < desc->field_count(); i++) { @@ -2100,7 +2072,7 @@ void Generator::GenerateClassToObject(const GeneratorOptions& options, " $extObject$, $class$.prototype.getExtension,\n" " includeInstance);\n", "extObject", JSExtensionsObjectName(options, desc->file(), desc), - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); } printer->Print( @@ -2112,7 +2084,7 @@ void Generator::GenerateClassToObject(const GeneratorOptions& options, "}\n" "\n" "\n", - "classname", GetPath(options, desc)); + "classname", GetMessagePath(options, desc)); } void Generator::GenerateFieldValueExpression(io::Printer* printer, @@ -2173,7 +2145,7 @@ void Generator::GenerateClassFieldToObject(const GeneratorOptions& options, string value_to_object; if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { value_to_object = - GetPath(options, value_field->message_type()) + ".toObject"; + GetMessagePath(options, value_field->message_type()) + ".toObject"; } else { value_to_object = "undefined"; } @@ -2235,7 +2207,7 @@ void Generator::GenerateClassFromObject(const GeneratorOptions& options, " */\n" "$classname$.fromObject = function(obj) {\n" " var f, msg = new $classname$();\n", - "classname", GetPath(options, desc)); + "classname", GetMessagePath(options, desc)); for (int i = 0; i < desc->field_count(); i++) { const FieldDescriptor* field = desc->field(i); @@ -2263,7 +2235,7 @@ void Generator::GenerateClassFieldFromObject( "$fieldclass$.fromObject));\n", "name", JSObjectFieldName(options, field), "index", JSFieldIndex(field), - "fieldclass", GetPath(options, value_field->message_type())); + "fieldclass", GetMessagePath(options, value_field->message_type())); } else { // `msg` is a newly-constructed message object that has not yet built any // map containers wrapping underlying arrays, so we can simply directly @@ -2354,7 +2326,7 @@ void GenerateBytesWrapper(const GeneratorOptions& options, "fielddef", FieldDefinition(options, field), "comment", FieldComments(field, bytes_mode), "type", type, - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field, bytes_mode), "list", field->is_repeated() ? "List" : "", "suffix", JSByteGetterSuffix(bytes_mode), @@ -2395,7 +2367,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, printer->Print( "$class$.prototype.get$name$ = function(opt_noLazyCreate) {\n" " return /** @type {!jspb.Map<$keytype$,$valuetype$>} */ (\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "keytype", key_type, "valuetype", value_type); @@ -2404,9 +2376,10 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "index", JSFieldIndex(field)); if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { - printer->Print(",\n" + printer->Print( + ",\n" " $messageType$", - "messageType", GetPath(options, value_field->message_type())); + "messageType", GetMessagePath(options, value_field->message_type())); } else { printer->Print(",\n" " null"); @@ -2443,7 +2416,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "};\n" "\n" "\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "type", JSFieldTypeAnnotation(options, field, /* is_setter_argument = */ false, @@ -2464,7 +2437,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, /* force_present = */ false, /* singular_if_not_packed = */ false), "returndoc", JSReturnDoc(options, field), - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "repeatedtag", (field->is_repeated() ? "Repeated" : "")); @@ -2520,7 +2493,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, printer->Print( "$class$.prototype.get$name$ = function() {\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field)); if (untyped) { @@ -2585,7 +2558,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, printer->Print( "$class$.prototype.set$name$ = function(value) {\n" " jspb.Message.set$oneoftag$Field(this, $index$", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "oneoftag", (field->containing_oneof() ? "Oneof" : ""), "index", JSFieldIndex(field)); @@ -2626,7 +2599,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "};\n" "\n" "\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "returnvalue", JSReturnClause(field)); } else if (field->is_repeated() || @@ -2639,7 +2612,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "};\n" "\n" "\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "clearedvalue", (field->is_repeated() ? "[]" : "undefined"), "returnvalue", JSReturnClause(field)); @@ -2650,7 +2623,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "$class$.prototype.clear$name$ = function() {\n" " jspb.Message.set$maybeoneof$Field(this, " "$index$$maybeoneofgroup$, ", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "maybeoneof", (field->containing_oneof() ? "Oneof" : ""), "maybeoneofgroup", (field->containing_oneof() ? @@ -2676,7 +2649,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, "};\n" "\n" "\n", - "class", GetPath(options, field->containing_type()), + "class", GetMessagePath(options, field->containing_type()), "name", JSGetterName(options, field), "index", JSFieldIndex(field)); } @@ -2692,8 +2665,8 @@ void Generator::GenerateRepeatedPrimitiveHelperMethods( " */\n" "$class$.prototype.add$name$ = function(value, opt_index) {\n" " jspb.Message.addToRepeatedField(this, $index$", - "class", GetPath(options, field->containing_type()), "name", - JSGetterName(options, field, BYTES_DEFAULT, + "class", GetMessagePath(options, field->containing_type()), + "name", JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true), "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "index", JSFieldIndex(field)); @@ -2719,9 +2692,9 @@ void Generator::GenerateRepeatedMessageHelperMethods( " */\n" "$class$.prototype.add$name$ = function(opt_value, opt_index) {\n" " return jspb.Message.addTo$repeatedtag$WrapperField(", - "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), "class", - GetPath(options, field->containing_type()), "name", - JSGetterName(options, field, BYTES_DEFAULT, + "optionaltype", JSTypeName(options, field, BYTES_DEFAULT), + "class", GetMessagePath(options, field->containing_type()), + "name", JSGetterName(options, field, BYTES_DEFAULT, /* drop_list = */ true), "repeatedtag", (field->is_repeated() ? "Repeated" : "")); @@ -2732,7 +2705,7 @@ void Generator::GenerateRepeatedMessageHelperMethods( "\n", "index", JSFieldIndex(field), "oneofgroup", (field->containing_oneof() ? (", " + JSOneofArray(options, field)) : ""), - "ctor", GetPath(options, field->message_type())); + "ctor", GetMessagePath(options, field->message_type())); } void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, @@ -2758,7 +2731,7 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, " */\n" "$class$.extensions = {};\n" "\n", - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); printer->Print( "\n" @@ -2779,7 +2752,7 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, " */\n" "$class$.extensionsBinary = {};\n" "\n", - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); } } @@ -2817,7 +2790,7 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options, " }\n" " var field = reader.getFieldNumber();\n" " switch (field) {\n", - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); for (int i = 0; i < desc->field_count(); i++) { if (!IgnoreField(desc->field(i))) { @@ -2834,7 +2807,7 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options, " $class$.prototype.setExtension);\n" " break;\n", "extobj", JSExtensionsObjectName(options, desc->file(), desc), - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); } else { printer->Print( " reader.skipField();\n" @@ -2873,7 +2846,7 @@ void Generator::GenerateClassDeserializeBinaryField( if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { printer->Print(", $messageType$.deserializeBinaryFromReader", - "messageType", GetPath(options, value_field->message_type())); + "messageType", GetMessagePath(options, value_field->message_type())); } printer->Print(");\n"); @@ -2941,7 +2914,7 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, "$class$.serializeBinaryToWriter = function(message, " "writer) {\n" " var f = undefined;\n", - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); for (int i = 0; i < desc->field_count(); i++) { if (!IgnoreField(desc->field(i))) { @@ -2954,7 +2927,7 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, " jspb.Message.serializeBinaryExtensions(message, writer,\n" " $extobj$Binary, $class$.prototype.getExtension);\n", "extobj", JSExtensionsObjectName(options, desc->file(), desc), - "class", GetPath(options, desc)); + "class", GetMessagePath(options, desc)); } printer->Print( @@ -3049,7 +3022,7 @@ void Generator::GenerateClassSerializeBinaryField( if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) { printer->Print(", $messageType$.serializeBinaryToWriter", - "messageType", GetPath(options, value_field->message_type())); + "messageType", GetMessagePath(options, value_field->message_type())); } printer->Print(");\n"); @@ -3088,7 +3061,7 @@ void Generator::GenerateEnum(const GeneratorOptions& options, " * @enum {number}\n" " */\n" "$name$ = {\n", - "name", GetPath(options, enumdesc)); + "name", GetEnumPath(options, enumdesc)); for (int i = 0; i < enumdesc->value_count(); i++) { const EnumValueDescriptor* value = enumdesc->value(i); @@ -3108,9 +3081,9 @@ void Generator::GenerateExtension(const GeneratorOptions& options, io::Printer* printer, const FieldDescriptor* field) const { string extension_scope = - (field->extension_scope() ? - GetPath(options, field->extension_scope()) : - GetPath(options, field->file())); + (field->extension_scope() + ? GetMessagePath(options, field->extension_scope()) + : GetFilePath(options, field->file())); printer->Print( "\n" @@ -3347,7 +3320,7 @@ void Generator::GenerateFile(const GeneratorOptions& options, IgnoreField(file->extension(i))) { continue; } - provided.insert(GetPath(options, file) + "." + + provided.insert(GetFilePath(options, file) + "." + JSObjectFieldName(options, file->extension(i))); extensions.insert(file->extension(i)); } @@ -3371,7 +3344,7 @@ void Generator::GenerateFile(const GeneratorOptions& options, if (options.import_style == GeneratorOptions::kImportCommonJs) { printer->Print("goog.object.extend(exports, $package$);\n", - "package", GetPath(options, file)); + "package", GetFilePath(options, file)); } // Emit well-known type methods. diff --git a/src/google/protobuf/compiler/js/well_known_types/timestamp.js b/src/google/protobuf/compiler/js/well_known_types/timestamp.js index 77c07bb4..b7e43f19 100644 --- a/src/google/protobuf/compiler/js/well_known_types/timestamp.js +++ b/src/google/protobuf/compiler/js/well_known_types/timestamp.js @@ -48,7 +48,6 @@ proto.google.protobuf.Timestamp.prototype.toDate = function() { * @param {!Date} value The value to set. */ proto.google.protobuf.Timestamp.prototype.fromDate = function(value) { - var millis = value.getTime(); this.setSeconds(Math.floor(value.getTime() / 1000)); this.setNanos(value.getMilliseconds() * 1000000); }; diff --git a/src/google/protobuf/compiler/mock_code_generator.cc b/src/google/protobuf/compiler/mock_code_generator.cc index a4b522ce..0ddb99e5 100644 --- a/src/google/protobuf/compiler/mock_code_generator.cc +++ b/src/google/protobuf/compiler/mock_code_generator.cc @@ -40,27 +40,21 @@ #endif #include +#include + #include #include #include #include #include +#include #include #include #include #include -#include #include #include -#ifdef major -#undef major -#endif -#ifdef minor -#undef minor -#endif -#include - namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/compiler/parser_unittest.cc b/src/google/protobuf/compiler/parser_unittest.cc index 20140f8e..d5e31325 100644 --- a/src/google/protobuf/compiler/parser_unittest.cc +++ b/src/google/protobuf/compiler/parser_unittest.cc @@ -42,14 +42,13 @@ #include +#include +#include #include #include #include -#include #include -#include -#include -#include +#include #include #include diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index d044fbbe..f7dc1b70 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -38,11 +38,29 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, major_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, minor_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Version, patch_), @@ -55,6 +73,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, file_to_generate_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, parameter_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorRequest, proto_file_), @@ -67,6 +86,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, insertion_point_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse_File, content_), @@ -77,6 +97,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, error_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(CodeGeneratorResponse, file_), 0, @@ -84,10 +105,10 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { - { 0, 8, sizeof(Version)}, - { 12, 20, sizeof(CodeGeneratorRequest)}, - { 24, 31, sizeof(CodeGeneratorResponse_File)}, - { 34, 40, sizeof(CodeGeneratorResponse)}, + { 0, 9, sizeof(Version)}, + { 13, 22, sizeof(CodeGeneratorRequest)}, + { 26, 34, sizeof(CodeGeneratorResponse_File)}, + { 37, 44, sizeof(CodeGeneratorResponse)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -246,7 +267,7 @@ void Version::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Version::descriptor() { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Version& Version::default_instance() { @@ -369,23 +390,27 @@ failure: void Version::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.Version) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 major = 1; - if (has_major()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->major(), output); } // optional int32 minor = 2; - if (has_minor()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->minor(), output); } // optional int32 patch = 3; - if (has_patch()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->patch(), output); } // optional string suffix = 4; - if (has_suffix()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->suffix().data(), this->suffix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -403,25 +428,28 @@ void Version::SerializeWithCachedSizes( ::google::protobuf::uint8* Version::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.Version) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 major = 1; - if (has_major()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->major(), target); } // optional int32 minor = 2; - if (has_minor()) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->minor(), target); } // optional int32 patch = 3; - if (has_patch()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->patch(), target); } // optional string suffix = 4; - if (has_suffix()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->suffix().data(), this->suffix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -504,20 +532,25 @@ void Version::MergeFrom(const Version& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.Version) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 15u) { - if (from.has_suffix()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 15u) { + if (cached_has_bits & 0x00000001u) { set_has_suffix(); suffix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.suffix_); } - if (from.has_major()) { - set_major(from.major()); + if (cached_has_bits & 0x00000002u) { + major_ = from.major_; } - if (from.has_minor()) { - set_minor(from.minor()); + if (cached_has_bits & 0x00000004u) { + minor_ = from.minor_; } - if (from.has_patch()) { - set_patch(from.patch()); + if (cached_has_bits & 0x00000008u) { + patch_ = from.patch_; } + _has_bits_[0] |= cached_has_bits; } } @@ -555,7 +588,7 @@ void Version::InternalSwap(Version* other) { ::google::protobuf::Metadata Version::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -665,6 +698,7 @@ void Version::set_suffix(::std::string&& value) { } #endif void Version::set_suffix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_suffix(); suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix) @@ -759,7 +793,7 @@ void CodeGeneratorRequest::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* CodeGeneratorRequest::descriptor() { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorRequest& CodeGeneratorRequest::default_instance() { @@ -852,13 +886,11 @@ bool CodeGeneratorRequest::MergePartialFromCodedStream( case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(122u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_proto_file())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -887,6 +919,9 @@ failure: void CodeGeneratorRequest::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated string file_to_generate = 1; for (int i = 0, n = this->file_to_generate_size(); i < n; i++) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -897,8 +932,9 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( 1, this->file_to_generate(i), output); } + cached_has_bits = _has_bits_[0]; // optional string parameter = 2; - if (has_parameter()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->parameter().data(), this->parameter().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -908,7 +944,7 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( } // optional .google.protobuf.compiler.Version compiler_version = 3; - if (has_compiler_version()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, *this->compiler_version_, output); } @@ -928,8 +964,10 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( ::google::protobuf::uint8* CodeGeneratorRequest::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorRequest) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated string file_to_generate = 1; for (int i = 0, n = this->file_to_generate_size(); i < n; i++) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( @@ -940,8 +978,9 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( WriteStringToArray(1, this->file_to_generate(i), target); } + cached_has_bits = _has_bits_[0]; // optional string parameter = 2; - if (has_parameter()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->parameter().data(), this->parameter().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -952,17 +991,17 @@ void CodeGeneratorRequest::SerializeWithCachedSizes( } // optional .google.protobuf.compiler.Version compiler_version = 3; - if (has_compiler_version()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, *this->compiler_version_, false, target); + 3, *this->compiler_version_, deterministic, target); } // repeated .google.protobuf.FileDescriptorProto proto_file = 15; for (unsigned int i = 0, n = this->proto_file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 15, this->proto_file(i), false, target); + 15, this->proto_file(i), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -1043,14 +1082,18 @@ void CodeGeneratorRequest::MergeFrom(const CodeGeneratorRequest& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorRequest) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + file_to_generate_.MergeFrom(from.file_to_generate_); proto_file_.MergeFrom(from.proto_file_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_parameter()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_parameter(); parameter_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.parameter_); } - if (from.has_compiler_version()) { + if (cached_has_bits & 0x00000002u) { mutable_compiler_version()->::google::protobuf::compiler::Version::MergeFrom(from.compiler_version()); } } @@ -1080,8 +1123,8 @@ void CodeGeneratorRequest::Swap(CodeGeneratorRequest* other) { InternalSwap(other); } void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { - file_to_generate_.UnsafeArenaSwap(&other->file_to_generate_); - proto_file_.UnsafeArenaSwap(&other->proto_file_); + file_to_generate_.InternalSwap(&other->file_to_generate_); + proto_file_.InternalSwap(&other->proto_file_); parameter_.Swap(&other->parameter_); std::swap(compiler_version_, other->compiler_version_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -1091,7 +1134,7 @@ void CodeGeneratorRequest::InternalSwap(CodeGeneratorRequest* other) { ::google::protobuf::Metadata CodeGeneratorRequest::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1123,6 +1166,7 @@ void CodeGeneratorRequest::set_file_to_generate(int index, ::std::string&& value } #endif void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); file_to_generate_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } @@ -1141,11 +1185,12 @@ void CodeGeneratorRequest::add_file_to_generate(const ::std::string& value) { } #if LANG_CXX11 void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) { - file_to_generate_.Add()->assign(std::move(value)); + file_to_generate_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } #endif void CodeGeneratorRequest::add_file_to_generate(const char* value) { + GOOGLE_DCHECK(value != NULL); file_to_generate_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } @@ -1196,6 +1241,7 @@ void CodeGeneratorRequest::set_parameter(::std::string&& value) { } #endif void CodeGeneratorRequest::set_parameter(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_parameter(); parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1365,7 +1411,7 @@ void CodeGeneratorResponse_File::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* CodeGeneratorResponse_File::descriptor() { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorResponse_File& CodeGeneratorResponse_File::default_instance() { @@ -1484,8 +1530,12 @@ failure: void CodeGeneratorResponse_File::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse.File) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1495,7 +1545,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string insertion_point = 2; - if (has_insertion_point()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->insertion_point().data(), this->insertion_point().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1505,7 +1555,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string content = 15; - if (has_content()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->content().data(), this->content().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1523,10 +1573,13 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( ::google::protobuf::uint8* CodeGeneratorResponse_File::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse.File) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1537,7 +1590,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string insertion_point = 2; - if (has_insertion_point()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->insertion_point().data(), this->insertion_point().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1548,7 +1601,7 @@ void CodeGeneratorResponse_File::SerializeWithCachedSizes( } // optional string content = 15; - if (has_content()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->content().data(), this->content().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1624,16 +1677,20 @@ void CodeGeneratorResponse_File::MergeFrom(const CodeGeneratorResponse_File& fro // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse.File) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 7u) { - if (from.has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_insertion_point()) { + if (cached_has_bits & 0x00000002u) { set_has_insertion_point(); insertion_point_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.insertion_point_); } - if (from.has_content()) { + if (cached_has_bits & 0x00000004u) { set_has_content(); content_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.content_); } @@ -1673,7 +1730,7 @@ void CodeGeneratorResponse_File::InternalSwap(CodeGeneratorResponse_File* other) ::google::protobuf::Metadata CodeGeneratorResponse_File::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1711,6 +1768,7 @@ void CodeGeneratorResponse_File::set_name(::std::string&& value) { } #endif void CodeGeneratorResponse_File::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1773,6 +1831,7 @@ void CodeGeneratorResponse_File::set_insertion_point(::std::string&& value) { } #endif void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_insertion_point(); insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1835,6 +1894,7 @@ void CodeGeneratorResponse_File::set_content(::std::string&& value) { } #endif void CodeGeneratorResponse_File::set_content(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_content(); content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1917,7 +1977,7 @@ void CodeGeneratorResponse::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* CodeGeneratorResponse::descriptor() { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[3].descriptor; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const CodeGeneratorResponse& CodeGeneratorResponse::default_instance() { @@ -1974,13 +2034,11 @@ bool CodeGeneratorResponse::MergePartialFromCodedStream( case 15: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(122u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_file())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -2009,8 +2067,12 @@ failure: void CodeGeneratorResponse::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.CodeGeneratorResponse) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string error = 1; - if (has_error()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->error().data(), this->error().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -2034,10 +2096,13 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( ::google::protobuf::uint8* CodeGeneratorResponse::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.CodeGeneratorResponse) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string error = 1; - if (has_error()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->error().data(), this->error().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -2051,7 +2116,7 @@ void CodeGeneratorResponse::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 15, this->file(i), false, target); + 15, this->file(i), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -2115,6 +2180,9 @@ void CodeGeneratorResponse::MergeFrom(const CodeGeneratorResponse& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.CodeGeneratorResponse) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + file_.MergeFrom(from.file_); if (from.has_error()) { set_has_error(); @@ -2145,7 +2213,7 @@ void CodeGeneratorResponse::Swap(CodeGeneratorResponse* other) { InternalSwap(other); } void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { - file_.UnsafeArenaSwap(&other->file_); + file_.InternalSwap(&other->file_); error_.Swap(&other->error_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); @@ -2154,7 +2222,7 @@ void CodeGeneratorResponse::InternalSwap(CodeGeneratorResponse* other) { ::google::protobuf::Metadata CodeGeneratorResponse::GetMetadata() const { protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[3]; + return protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2192,6 +2260,7 @@ void CodeGeneratorResponse::set_error(::std::string&& value) { } #endif void CodeGeneratorResponse::set_error(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_error(); error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index ff8b949f..c9abc256 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -137,6 +138,9 @@ namespace compiler { namespace protobuf_google_2fprotobuf_2fcompiler_2fplugin_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOC_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -174,6 +178,8 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast( &_Version_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void Swap(Version* other); @@ -196,11 +202,6 @@ class LIBPROTOC_EXPORT Version : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -307,6 +308,8 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message return reinterpret_cast( &_CodeGeneratorRequest_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void Swap(CodeGeneratorRequest* other); @@ -329,11 +332,6 @@ class LIBPROTOC_EXPORT CodeGeneratorRequest : public ::google::protobuf::Message ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -458,6 +456,8 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M return reinterpret_cast( &_CodeGeneratorResponse_File_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void Swap(CodeGeneratorResponse_File* other); @@ -480,11 +480,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse_File : public ::google::protobuf::M ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -597,6 +592,8 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag return reinterpret_cast( &_CodeGeneratorResponse_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 3; void Swap(CodeGeneratorResponse* other); @@ -619,11 +616,6 @@ class LIBPROTOC_EXPORT CodeGeneratorResponse : public ::google::protobuf::Messag ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -798,6 +790,7 @@ inline void Version::set_suffix(::std::string&& value) { } #endif inline void Version::set_suffix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_suffix(); suffix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.Version.suffix) @@ -858,6 +851,7 @@ inline void CodeGeneratorRequest::set_file_to_generate(int index, ::std::string& } #endif inline void CodeGeneratorRequest::set_file_to_generate(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); file_to_generate_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } @@ -876,11 +870,12 @@ inline void CodeGeneratorRequest::add_file_to_generate(const ::std::string& valu } #if LANG_CXX11 inline void CodeGeneratorRequest::add_file_to_generate(::std::string&& value) { - file_to_generate_.Add()->assign(std::move(value)); + file_to_generate_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } #endif inline void CodeGeneratorRequest::add_file_to_generate(const char* value) { + GOOGLE_DCHECK(value != NULL); file_to_generate_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.compiler.CodeGeneratorRequest.file_to_generate) } @@ -931,6 +926,7 @@ inline void CodeGeneratorRequest::set_parameter(::std::string&& value) { } #endif inline void CodeGeneratorRequest::set_parameter(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_parameter(); parameter_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorRequest.parameter) @@ -1072,6 +1068,7 @@ inline void CodeGeneratorResponse_File::set_name(::std::string&& value) { } #endif inline void CodeGeneratorResponse_File::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.name) @@ -1134,6 +1131,7 @@ inline void CodeGeneratorResponse_File::set_insertion_point(::std::string&& valu } #endif inline void CodeGeneratorResponse_File::set_insertion_point(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_insertion_point(); insertion_point_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point) @@ -1196,6 +1194,7 @@ inline void CodeGeneratorResponse_File::set_content(::std::string&& value) { } #endif inline void CodeGeneratorResponse_File::set_content(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_content(); content_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.File.content) @@ -1262,6 +1261,7 @@ inline void CodeGeneratorResponse::set_error(::std::string&& value) { } #endif inline void CodeGeneratorResponse::set_error(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_error(); error_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.CodeGeneratorResponse.error) diff --git a/src/google/protobuf/compiler/plugin.proto b/src/google/protobuf/compiler/plugin.proto index bf91d76e..f04dc73c 100644 --- a/src/google/protobuf/compiler/plugin.proto +++ b/src/google/protobuf/compiler/plugin.proto @@ -84,6 +84,9 @@ message CodeGeneratorRequest { // the entire set into memory at once. However, as of this writing, this // is not similarly optimized on protoc's end -- it will store all fields in // memory at once before sending them to the plugin. + // + // Type names of fields and extensions in the FileDescriptorProto are always + // fully qualified. repeated FileDescriptorProto proto_file = 15; // The version number of protocol compiler. diff --git a/src/google/protobuf/compiler/profile.pb.cc b/src/google/protobuf/compiler/profile.pb.cc new file mode 100644 index 00000000..c185e4f9 --- /dev/null +++ b/src/google/protobuf/compiler/profile.pb.cc @@ -0,0 +1,1442 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/profile.proto + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace google { +namespace protobuf { +namespace compiler { +class FieldAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { +} _FieldAccessInfo_default_instance_; +class MessageAccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { +} _MessageAccessInfo_default_instance_; +class AccessInfoDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { +} _AccessInfo_default_instance_; + +namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto { + + +namespace { + +::google::protobuf::Metadata file_level_metadata[3]; + +} // namespace + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + +const ::google::protobuf::uint32 TableStruct::offsets[] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, getters_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, setters_count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldAccessInfo, configs_count_), + 0, + 1, + 2, + 3, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, name_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, count_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageAccessInfo, field_), + 0, + 1, + ~0u, + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, _internal_metadata_), + ~0u, // no _extensions_ + ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(AccessInfo, message_), + ~0u, +}; + +static const ::google::protobuf::internal::MigrationSchema schemas[] = { + { 0, 9, sizeof(FieldAccessInfo)}, + { 13, 21, sizeof(MessageAccessInfo)}, + { 24, 30, sizeof(AccessInfo)}, +}; + +static ::google::protobuf::Message const * const file_default_instances[] = { + reinterpret_cast(&_FieldAccessInfo_default_instance_), + reinterpret_cast(&_MessageAccessInfo_default_instance_), + reinterpret_cast(&_AccessInfo_default_instance_), +}; + +namespace { + +void protobuf_AssignDescriptors() { + AddDescriptors(); + ::google::protobuf::MessageFactory* factory = NULL; + AssignDescriptors( + "google/protobuf/compiler/profile.proto", schemas, file_default_instances, TableStruct::offsets, factory, + file_level_metadata, NULL, NULL); +} + +void protobuf_AssignDescriptorsOnce() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors); +} + +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); + ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 3); +} + +} // namespace + +void TableStruct::Shutdown() { + _FieldAccessInfo_default_instance_.Shutdown(); + delete file_level_metadata[0].reflection; + _MessageAccessInfo_default_instance_.Shutdown(); + delete file_level_metadata[1].reflection; + _AccessInfo_default_instance_.Shutdown(); + delete file_level_metadata[2].reflection; +} + +void TableStruct::InitDefaultsImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::internal::InitProtobufDefaults(); + _FieldAccessInfo_default_instance_.DefaultConstruct(); + _MessageAccessInfo_default_instance_.DefaultConstruct(); + _AccessInfo_default_instance_.DefaultConstruct(); +} + +void InitDefaults() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl); +} +void AddDescriptorsImpl() { + InitDefaults(); + static const char descriptor[] = { + "\n&google/protobuf/compiler/profile.proto" + "\022\030google.protobuf.compiler\"d\n\017FieldAcces" + "sInfo\022\014\n\004name\030\001 \001(\t\022\025\n\rgetters_count\030\002 \001" + "(\004\022\025\n\rsetters_count\030\003 \001(\004\022\025\n\rconfigs_cou" + "nt\030\004 \001(\004\"j\n\021MessageAccessInfo\022\014\n\004name\030\001 " + "\001(\t\022\r\n\005count\030\002 \001(\004\0228\n\005field\030\003 \003(\0132).goog" + "le.protobuf.compiler.FieldAccessInfo\"J\n\n" + "AccessInfo\022<\n\007message\030\001 \003(\0132+.google.pro" + "tobuf.compiler.MessageAccessInfo" + }; + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + descriptor, 352); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "google/protobuf/compiler/profile.proto", &protobuf_RegisterTypes); + ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); +} + +void AddDescriptors() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); +} +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer { + StaticDescriptorInitializer() { + AddDescriptors(); + } +} static_descriptor_initializer; + +} // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto + + +// =================================================================== + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int FieldAccessInfo::kNameFieldNumber; +const int FieldAccessInfo::kGettersCountFieldNumber; +const int FieldAccessInfo::kSettersCountFieldNumber; +const int FieldAccessInfo::kConfigsCountFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +FieldAccessInfo::FieldAccessInfo() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + } + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.compiler.FieldAccessInfo) +} +FieldAccessInfo::FieldAccessInfo(const FieldAccessInfo& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL), + _has_bits_(from._has_bits_), + _cached_size_(0) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.has_name()) { + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + ::memcpy(&getters_count_, &from.getters_count_, + reinterpret_cast(&configs_count_) - + reinterpret_cast(&getters_count_) + sizeof(configs_count_)); + // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.FieldAccessInfo) +} + +void FieldAccessInfo::SharedCtor() { + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + ::memset(&getters_count_, 0, reinterpret_cast(&configs_count_) - + reinterpret_cast(&getters_count_) + sizeof(configs_count_)); +} + +FieldAccessInfo::~FieldAccessInfo() { + // @@protoc_insertion_point(destructor:google.protobuf.compiler.FieldAccessInfo) + SharedDtor(); +} + +void FieldAccessInfo::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void FieldAccessInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* FieldAccessInfo::descriptor() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const FieldAccessInfo& FieldAccessInfo::default_instance() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + return *internal_default_instance(); +} + +FieldAccessInfo* FieldAccessInfo::New(::google::protobuf::Arena* arena) const { + FieldAccessInfo* n = new FieldAccessInfo; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void FieldAccessInfo::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.FieldAccessInfo) + if (has_name()) { + GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); + (*name_.UnsafeRawStringPointer())->clear(); + } + if (_has_bits_[0 / 32] & 14u) { + ::memset(&getters_count_, 0, reinterpret_cast(&configs_count_) - + reinterpret_cast(&getters_count_) + sizeof(configs_count_)); + } + _has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +bool FieldAccessInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.compiler.FieldAccessInfo) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.compiler.FieldAccessInfo.name"); + } else { + goto handle_unusual; + } + break; + } + + // optional uint64 getters_count = 2; + case 2: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(16u)) { + set_has_getters_count(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &getters_count_))); + } else { + goto handle_unusual; + } + break; + } + + // optional uint64 setters_count = 3; + case 3: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(24u)) { + set_has_setters_count(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &setters_count_))); + } else { + goto handle_unusual; + } + break; + } + + // optional uint64 configs_count = 4; + case 4: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(32u)) { + set_has_configs_count(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &configs_count_))); + } else { + goto handle_unusual; + } + 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::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.compiler.FieldAccessInfo) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.FieldAccessInfo) + return false; +#undef DO_ +} + +void FieldAccessInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.FieldAccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.compiler.FieldAccessInfo.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional uint64 getters_count = 2; + if (cached_has_bits & 0x00000002u) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->getters_count(), output); + } + + // optional uint64 setters_count = 3; + if (cached_has_bits & 0x00000004u) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(3, this->setters_count(), output); + } + + // optional uint64 configs_count = 4; + if (cached_has_bits & 0x00000008u) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->configs_count(), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.FieldAccessInfo) +} + +::google::protobuf::uint8* FieldAccessInfo::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.FieldAccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.compiler.FieldAccessInfo.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional uint64 getters_count = 2; + if (cached_has_bits & 0x00000002u) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->getters_count(), target); + } + + // optional uint64 setters_count = 3; + if (cached_has_bits & 0x00000004u) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(3, this->setters_count(), target); + } + + // optional uint64 configs_count = 4; + if (cached_has_bits & 0x00000008u) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->configs_count(), target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.FieldAccessInfo) + return target; +} + +size_t FieldAccessInfo::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.FieldAccessInfo) + size_t total_size = 0; + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + if (_has_bits_[0 / 32] & 15u) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional uint64 getters_count = 2; + if (has_getters_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->getters_count()); + } + + // optional uint64 setters_count = 3; + if (has_setters_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->setters_count()); + } + + // optional uint64 configs_count = 4; + if (has_configs_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->configs_count()); + } + + } + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = cached_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void FieldAccessInfo::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.FieldAccessInfo) + GOOGLE_DCHECK_NE(&from, this); + const FieldAccessInfo* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.FieldAccessInfo) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.FieldAccessInfo) + MergeFrom(*source); + } +} + +void FieldAccessInfo::MergeFrom(const FieldAccessInfo& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.FieldAccessInfo) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 15u) { + if (cached_has_bits & 0x00000001u) { + set_has_name(); + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (cached_has_bits & 0x00000002u) { + getters_count_ = from.getters_count_; + } + if (cached_has_bits & 0x00000004u) { + setters_count_ = from.setters_count_; + } + if (cached_has_bits & 0x00000008u) { + configs_count_ = from.configs_count_; + } + _has_bits_[0] |= cached_has_bits; + } +} + +void FieldAccessInfo::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.FieldAccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void FieldAccessInfo::CopyFrom(const FieldAccessInfo& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.FieldAccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool FieldAccessInfo::IsInitialized() const { + return true; +} + +void FieldAccessInfo::Swap(FieldAccessInfo* other) { + if (other == this) return; + InternalSwap(other); +} +void FieldAccessInfo::InternalSwap(FieldAccessInfo* other) { + name_.Swap(&other->name_); + std::swap(getters_count_, other->getters_count_); + std::swap(setters_count_, other->setters_count_); + std::swap(configs_count_, other->configs_count_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata FieldAccessInfo::GetMetadata() const { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// FieldAccessInfo + +// optional string name = 1; +bool FieldAccessInfo::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void FieldAccessInfo::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +void FieldAccessInfo::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +void FieldAccessInfo::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +const ::std::string& FieldAccessInfo::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name) + return name_.GetNoArena(); +} +void FieldAccessInfo::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name) +} +#if LANG_CXX11 +void FieldAccessInfo::set_name(::std::string&& value) { + set_has_name(); + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name) +} +#endif +void FieldAccessInfo::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name) +} +void FieldAccessInfo::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.FieldAccessInfo.name) +} +::std::string* FieldAccessInfo::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +::std::string* FieldAccessInfo::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +void FieldAccessInfo::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.FieldAccessInfo.name) +} + +// optional uint64 getters_count = 2; +bool FieldAccessInfo::has_getters_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void FieldAccessInfo::set_has_getters_count() { + _has_bits_[0] |= 0x00000002u; +} +void FieldAccessInfo::clear_has_getters_count() { + _has_bits_[0] &= ~0x00000002u; +} +void FieldAccessInfo::clear_getters_count() { + getters_count_ = GOOGLE_ULONGLONG(0); + clear_has_getters_count(); +} +::google::protobuf::uint64 FieldAccessInfo::getters_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count) + return getters_count_; +} +void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) { + set_has_getters_count(); + getters_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count) +} + +// optional uint64 setters_count = 3; +bool FieldAccessInfo::has_setters_count() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +void FieldAccessInfo::set_has_setters_count() { + _has_bits_[0] |= 0x00000004u; +} +void FieldAccessInfo::clear_has_setters_count() { + _has_bits_[0] &= ~0x00000004u; +} +void FieldAccessInfo::clear_setters_count() { + setters_count_ = GOOGLE_ULONGLONG(0); + clear_has_setters_count(); +} +::google::protobuf::uint64 FieldAccessInfo::setters_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count) + return setters_count_; +} +void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) { + set_has_setters_count(); + setters_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count) +} + +// optional uint64 configs_count = 4; +bool FieldAccessInfo::has_configs_count() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +void FieldAccessInfo::set_has_configs_count() { + _has_bits_[0] |= 0x00000008u; +} +void FieldAccessInfo::clear_has_configs_count() { + _has_bits_[0] &= ~0x00000008u; +} +void FieldAccessInfo::clear_configs_count() { + configs_count_ = GOOGLE_ULONGLONG(0); + clear_has_configs_count(); +} +::google::protobuf::uint64 FieldAccessInfo::configs_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count) + return configs_count_; +} +void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) { + set_has_configs_count(); + configs_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count) +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int MessageAccessInfo::kNameFieldNumber; +const int MessageAccessInfo::kCountFieldNumber; +const int MessageAccessInfo::kFieldFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +MessageAccessInfo::MessageAccessInfo() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + } + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.compiler.MessageAccessInfo) +} +MessageAccessInfo::MessageAccessInfo(const MessageAccessInfo& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL), + _has_bits_(from._has_bits_), + _cached_size_(0), + field_(from.field_) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.has_name()) { + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + count_ = from.count_; + // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.MessageAccessInfo) +} + +void MessageAccessInfo::SharedCtor() { + _cached_size_ = 0; + name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + count_ = GOOGLE_ULONGLONG(0); +} + +MessageAccessInfo::~MessageAccessInfo() { + // @@protoc_insertion_point(destructor:google.protobuf.compiler.MessageAccessInfo) + SharedDtor(); +} + +void MessageAccessInfo::SharedDtor() { + name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} + +void MessageAccessInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* MessageAccessInfo::descriptor() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const MessageAccessInfo& MessageAccessInfo::default_instance() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + return *internal_default_instance(); +} + +MessageAccessInfo* MessageAccessInfo::New(::google::protobuf::Arena* arena) const { + MessageAccessInfo* n = new MessageAccessInfo; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void MessageAccessInfo::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.MessageAccessInfo) + field_.Clear(); + if (has_name()) { + GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); + (*name_.UnsafeRawStringPointer())->clear(); + } + count_ = GOOGLE_ULONGLONG(0); + _has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +bool MessageAccessInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.compiler.MessageAccessInfo) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // optional string name = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadString( + input, this->mutable_name())); + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::PARSE, + "google.protobuf.compiler.MessageAccessInfo.name"); + } else { + goto handle_unusual; + } + break; + } + + // optional uint64 count = 2; + case 2: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(16u)) { + set_has_count(); + DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive< + ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>( + input, &count_))); + } else { + goto handle_unusual; + } + break; + } + + // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; + case 3: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(26u)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_field())); + } else { + goto handle_unusual; + } + 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::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.compiler.MessageAccessInfo) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.MessageAccessInfo) + return false; +#undef DO_ +} + +void MessageAccessInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.MessageAccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.compiler.MessageAccessInfo.name"); + ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased( + 1, this->name(), output); + } + + // optional uint64 count = 2; + if (cached_has_bits & 0x00000002u) { + ::google::protobuf::internal::WireFormatLite::WriteUInt64(2, this->count(), output); + } + + // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; + for (unsigned int i = 0, n = this->field_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 3, this->field(i), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.MessageAccessInfo) +} + +::google::protobuf::uint8* MessageAccessInfo::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.MessageAccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; + // optional string name = 1; + if (cached_has_bits & 0x00000001u) { + ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( + this->name().data(), this->name().length(), + ::google::protobuf::internal::WireFormat::SERIALIZE, + "google.protobuf.compiler.MessageAccessInfo.name"); + target = + ::google::protobuf::internal::WireFormatLite::WriteStringToArray( + 1, this->name(), target); + } + + // optional uint64 count = 2; + if (cached_has_bits & 0x00000002u) { + target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(2, this->count(), target); + } + + // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; + for (unsigned int i = 0, n = this->field_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 3, this->field(i), deterministic, target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.MessageAccessInfo) + return target; +} + +size_t MessageAccessInfo::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.MessageAccessInfo) + size_t total_size = 0; + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; + { + unsigned int count = this->field_size(); + total_size += 1UL * count; + for (unsigned int i = 0; i < count; i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->field(i)); + } + } + + if (_has_bits_[0 / 32] & 3u) { + // optional string name = 1; + if (has_name()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::StringSize( + this->name()); + } + + // optional uint64 count = 2; + if (has_count()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::UInt64Size( + this->count()); + } + + } + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = cached_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void MessageAccessInfo::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.MessageAccessInfo) + GOOGLE_DCHECK_NE(&from, this); + const MessageAccessInfo* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.MessageAccessInfo) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.MessageAccessInfo) + MergeFrom(*source); + } +} + +void MessageAccessInfo::MergeFrom(const MessageAccessInfo& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.MessageAccessInfo) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + field_.MergeFrom(from.field_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { + set_has_name(); + name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); + } + if (cached_has_bits & 0x00000002u) { + count_ = from.count_; + } + _has_bits_[0] |= cached_has_bits; + } +} + +void MessageAccessInfo::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.MessageAccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void MessageAccessInfo::CopyFrom(const MessageAccessInfo& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.MessageAccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool MessageAccessInfo::IsInitialized() const { + return true; +} + +void MessageAccessInfo::Swap(MessageAccessInfo* other) { + if (other == this) return; + InternalSwap(other); +} +void MessageAccessInfo::InternalSwap(MessageAccessInfo* other) { + field_.InternalSwap(&other->field_); + name_.Swap(&other->name_); + std::swap(count_, other->count_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata MessageAccessInfo::GetMetadata() const { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// MessageAccessInfo + +// optional string name = 1; +bool MessageAccessInfo::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +void MessageAccessInfo::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +void MessageAccessInfo::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +void MessageAccessInfo::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +const ::std::string& MessageAccessInfo::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name) + return name_.GetNoArena(); +} +void MessageAccessInfo::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name) +} +#if LANG_CXX11 +void MessageAccessInfo::set_name(::std::string&& value) { + set_has_name(); + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name) +} +#endif +void MessageAccessInfo::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name) +} +void MessageAccessInfo::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.MessageAccessInfo.name) +} +::std::string* MessageAccessInfo::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +::std::string* MessageAccessInfo::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +void MessageAccessInfo::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.MessageAccessInfo.name) +} + +// optional uint64 count = 2; +bool MessageAccessInfo::has_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +void MessageAccessInfo::set_has_count() { + _has_bits_[0] |= 0x00000002u; +} +void MessageAccessInfo::clear_has_count() { + _has_bits_[0] &= ~0x00000002u; +} +void MessageAccessInfo::clear_count() { + count_ = GOOGLE_ULONGLONG(0); + clear_has_count(); +} +::google::protobuf::uint64 MessageAccessInfo::count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count) + return count_; +} +void MessageAccessInfo::set_count(::google::protobuf::uint64 value) { + set_has_count(); + count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count) +} + +// repeated .google.protobuf.compiler.FieldAccessInfo field = 3; +int MessageAccessInfo::field_size() const { + return field_.size(); +} +void MessageAccessInfo::clear_field() { + field_.Clear(); +} +const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Get(index); +} +::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Mutable(index); +} +::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Add(); +} +::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* +MessageAccessInfo::mutable_field() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field) + return &field_; +} +const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& +MessageAccessInfo::field() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field) + return field_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// =================================================================== + +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int AccessInfo::kMessageFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +AccessInfo::AccessInfo() + : ::google::protobuf::Message(), _internal_metadata_(NULL) { + if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + } + SharedCtor(); + // @@protoc_insertion_point(constructor:google.protobuf.compiler.AccessInfo) +} +AccessInfo::AccessInfo(const AccessInfo& from) + : ::google::protobuf::Message(), + _internal_metadata_(NULL), + _has_bits_(from._has_bits_), + _cached_size_(0), + message_(from.message_) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + // @@protoc_insertion_point(copy_constructor:google.protobuf.compiler.AccessInfo) +} + +void AccessInfo::SharedCtor() { + _cached_size_ = 0; +} + +AccessInfo::~AccessInfo() { + // @@protoc_insertion_point(destructor:google.protobuf.compiler.AccessInfo) + SharedDtor(); +} + +void AccessInfo::SharedDtor() { +} + +void AccessInfo::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const ::google::protobuf::Descriptor* AccessInfo::descriptor() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; +} + +const AccessInfo& AccessInfo::default_instance() { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::InitDefaults(); + return *internal_default_instance(); +} + +AccessInfo* AccessInfo::New(::google::protobuf::Arena* arena) const { + AccessInfo* n = new AccessInfo; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void AccessInfo::Clear() { +// @@protoc_insertion_point(message_clear_start:google.protobuf.compiler.AccessInfo) + message_.Clear(); + _has_bits_.Clear(); + _internal_metadata_.Clear(); +} + +bool AccessInfo::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + // @@protoc_insertion_point(parse_start:google.protobuf.compiler.AccessInfo) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( + input, add_message())); + } else { + goto handle_unusual; + } + 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::WireFormat::SkipField( + input, tag, mutable_unknown_fields())); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:google.protobuf.compiler.AccessInfo) + return true; +failure: + // @@protoc_insertion_point(parse_failure:google.protobuf.compiler.AccessInfo) + return false; +#undef DO_ +} + +void AccessInfo::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:google.protobuf.compiler.AccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; + for (unsigned int i = 0, n = this->message_size(); i < n; i++) { + ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( + 1, this->message(i), output); + } + + if (_internal_metadata_.have_unknown_fields()) { + ::google::protobuf::internal::WireFormat::SerializeUnknownFields( + unknown_fields(), output); + } + // @@protoc_insertion_point(serialize_end:google.protobuf.compiler.AccessInfo) +} + +::google::protobuf::uint8* AccessInfo::InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const { + // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.compiler.AccessInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; + for (unsigned int i = 0, n = this->message_size(); i < n; i++) { + target = ::google::protobuf::internal::WireFormatLite:: + InternalWriteMessageNoVirtualToArray( + 1, this->message(i), deterministic, target); + } + + if (_internal_metadata_.have_unknown_fields()) { + target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray( + unknown_fields(), target); + } + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.compiler.AccessInfo) + return target; +} + +size_t AccessInfo::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:google.protobuf.compiler.AccessInfo) + size_t total_size = 0; + + if (_internal_metadata_.have_unknown_fields()) { + total_size += + ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize( + unknown_fields()); + } + // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; + { + unsigned int count = this->message_size(); + total_size += 1UL * count; + for (unsigned int i = 0; i < count; i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->message(i)); + } + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = cached_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void AccessInfo::MergeFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_merge_from_start:google.protobuf.compiler.AccessInfo) + GOOGLE_DCHECK_NE(&from, this); + const AccessInfo* source = + ::google::protobuf::internal::DynamicCastToGenerated( + &from); + if (source == NULL) { + // @@protoc_insertion_point(generalized_merge_from_cast_fail:google.protobuf.compiler.AccessInfo) + ::google::protobuf::internal::ReflectionOps::Merge(from, this); + } else { + // @@protoc_insertion_point(generalized_merge_from_cast_success:google.protobuf.compiler.AccessInfo) + MergeFrom(*source); + } +} + +void AccessInfo::MergeFrom(const AccessInfo& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.compiler.AccessInfo) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + message_.MergeFrom(from.message_); +} + +void AccessInfo::CopyFrom(const ::google::protobuf::Message& from) { +// @@protoc_insertion_point(generalized_copy_from_start:google.protobuf.compiler.AccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +void AccessInfo::CopyFrom(const AccessInfo& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:google.protobuf.compiler.AccessInfo) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool AccessInfo::IsInitialized() const { + return true; +} + +void AccessInfo::Swap(AccessInfo* other) { + if (other == this) return; + InternalSwap(other); +} +void AccessInfo::InternalSwap(AccessInfo* other) { + message_.InternalSwap(&other->message_); + std::swap(_has_bits_[0], other->_has_bits_[0]); + _internal_metadata_.Swap(&other->_internal_metadata_); + std::swap(_cached_size_, other->_cached_size_); +} + +::google::protobuf::Metadata AccessInfo::GetMetadata() const { + protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::file_level_metadata[kIndexInFileMessages]; +} + +#if PROTOBUF_INLINE_NOT_IN_HEADERS +// AccessInfo + +// repeated .google.protobuf.compiler.MessageAccessInfo message = 1; +int AccessInfo::message_size() const { + return message_.size(); +} +void AccessInfo::clear_message() { + message_.Clear(); +} +const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message) + return message_.Get(index); +} +::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message) + return message_.Mutable(index); +} +::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message) + return message_.Add(); +} +::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* +AccessInfo::mutable_message() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message) + return &message_; +} +const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& +AccessInfo::message() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message) + return message_; +} + +#endif // PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + +} // namespace compiler +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) diff --git a/src/google/protobuf/compiler/profile.pb.h b/src/google/protobuf/compiler/profile.pb.h new file mode 100644 index 00000000..c2ce5efc --- /dev/null +++ b/src/google/protobuf/compiler/profile.pb.h @@ -0,0 +1,728 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/protobuf/compiler/profile.proto + +#ifndef PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED +#define PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3002000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include +// @@protoc_insertion_point(includes) +namespace google { +namespace protobuf { +namespace compiler { +class AccessInfo; +class AccessInfoDefaultTypeInternal; +LIBPROTOC_EXPORT extern AccessInfoDefaultTypeInternal _AccessInfo_default_instance_; +class FieldAccessInfo; +class FieldAccessInfoDefaultTypeInternal; +LIBPROTOC_EXPORT extern FieldAccessInfoDefaultTypeInternal _FieldAccessInfo_default_instance_; +class MessageAccessInfo; +class MessageAccessInfoDefaultTypeInternal; +LIBPROTOC_EXPORT extern MessageAccessInfoDefaultTypeInternal _MessageAccessInfo_default_instance_; +} // namespace compiler +} // namespace protobuf +} // namespace google + +namespace google { +namespace protobuf { +namespace compiler { + +namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto { +// Internal implementation detail -- do not call these. +struct LIBPROTOC_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; + static const ::google::protobuf::uint32 offsets[]; + static void InitDefaultsImpl(); + static void Shutdown(); +}; +void LIBPROTOC_EXPORT AddDescriptors(); +void LIBPROTOC_EXPORT InitDefaults(); +} // namespace protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto + +// =================================================================== + +class LIBPROTOC_EXPORT FieldAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.FieldAccessInfo) */ { + public: + FieldAccessInfo(); + virtual ~FieldAccessInfo(); + + FieldAccessInfo(const FieldAccessInfo& from); + + inline FieldAccessInfo& operator=(const FieldAccessInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const FieldAccessInfo& default_instance(); + + static inline const FieldAccessInfo* internal_default_instance() { + return reinterpret_cast( + &_FieldAccessInfo_default_instance_); + } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; + + void Swap(FieldAccessInfo* other); + + // implements Message ---------------------------------------------- + + inline FieldAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } + + FieldAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const FieldAccessInfo& from); + void MergeFrom(const FieldAccessInfo& from); + void Clear() PROTOBUF_FINAL; + bool IsInitialized() const PROTOBUF_FINAL; + + size_t ByteSizeLong() const PROTOBUF_FINAL; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; + int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const PROTOBUF_FINAL; + void InternalSwap(FieldAccessInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + #if LANG_CXX11 + void set_name(::std::string&& value); + #endif + 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 uint64 getters_count = 2; + bool has_getters_count() const; + void clear_getters_count(); + static const int kGettersCountFieldNumber = 2; + ::google::protobuf::uint64 getters_count() const; + void set_getters_count(::google::protobuf::uint64 value); + + // optional uint64 setters_count = 3; + bool has_setters_count() const; + void clear_setters_count(); + static const int kSettersCountFieldNumber = 3; + ::google::protobuf::uint64 setters_count() const; + void set_setters_count(::google::protobuf::uint64 value); + + // optional uint64 configs_count = 4; + bool has_configs_count() const; + void clear_configs_count(); + static const int kConfigsCountFieldNumber = 4; + ::google::protobuf::uint64 configs_count() const; + void set_configs_count(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.FieldAccessInfo) + private: + void set_has_name(); + void clear_has_name(); + void set_has_getters_count(); + void clear_has_getters_count(); + void set_has_setters_count(); + void clear_has_setters_count(); + void set_has_configs_count(); + void clear_has_configs_count(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::HasBits<1> _has_bits_; + mutable int _cached_size_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::uint64 getters_count_; + ::google::protobuf::uint64 setters_count_; + ::google::protobuf::uint64 configs_count_; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT MessageAccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.MessageAccessInfo) */ { + public: + MessageAccessInfo(); + virtual ~MessageAccessInfo(); + + MessageAccessInfo(const MessageAccessInfo& from); + + inline MessageAccessInfo& operator=(const MessageAccessInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const MessageAccessInfo& default_instance(); + + static inline const MessageAccessInfo* internal_default_instance() { + return reinterpret_cast( + &_MessageAccessInfo_default_instance_); + } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; + + void Swap(MessageAccessInfo* other); + + // implements Message ---------------------------------------------- + + inline MessageAccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } + + MessageAccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const MessageAccessInfo& from); + void MergeFrom(const MessageAccessInfo& from); + void Clear() PROTOBUF_FINAL; + bool IsInitialized() const PROTOBUF_FINAL; + + size_t ByteSizeLong() const PROTOBUF_FINAL; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; + int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const PROTOBUF_FINAL; + void InternalSwap(MessageAccessInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.compiler.FieldAccessInfo field = 3; + int field_size() const; + void clear_field(); + static const int kFieldFieldNumber = 3; + const ::google::protobuf::compiler::FieldAccessInfo& field(int index) const; + ::google::protobuf::compiler::FieldAccessInfo* mutable_field(int index); + ::google::protobuf::compiler::FieldAccessInfo* add_field(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* + mutable_field(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& + field() const; + + // optional string name = 1; + bool has_name() const; + void clear_name(); + static const int kNameFieldNumber = 1; + const ::std::string& name() const; + void set_name(const ::std::string& value); + #if LANG_CXX11 + void set_name(::std::string&& value); + #endif + 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 uint64 count = 2; + bool has_count() const; + void clear_count(); + static const int kCountFieldNumber = 2; + ::google::protobuf::uint64 count() const; + void set_count(::google::protobuf::uint64 value); + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.MessageAccessInfo) + private: + void set_has_name(); + void clear_has_name(); + void set_has_count(); + void clear_has_count(); + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::HasBits<1> _has_bits_; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo > field_; + ::google::protobuf::internal::ArenaStringPtr name_; + ::google::protobuf::uint64 count_; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; +}; +// ------------------------------------------------------------------- + +class LIBPROTOC_EXPORT AccessInfo : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:google.protobuf.compiler.AccessInfo) */ { + public: + AccessInfo(); + virtual ~AccessInfo(); + + AccessInfo(const AccessInfo& from); + + inline AccessInfo& operator=(const AccessInfo& from) { + CopyFrom(from); + return *this; + } + + inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const { + return _internal_metadata_.unknown_fields(); + } + + inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() { + return _internal_metadata_.mutable_unknown_fields(); + } + + static const ::google::protobuf::Descriptor* descriptor(); + static const AccessInfo& default_instance(); + + static inline const AccessInfo* internal_default_instance() { + return reinterpret_cast( + &_AccessInfo_default_instance_); + } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; + + void Swap(AccessInfo* other); + + // implements Message ---------------------------------------------- + + inline AccessInfo* New() const PROTOBUF_FINAL { return New(NULL); } + + AccessInfo* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL; + void CopyFrom(const AccessInfo& from); + void MergeFrom(const AccessInfo& from); + void Clear() PROTOBUF_FINAL; + bool IsInitialized() const PROTOBUF_FINAL; + + size_t ByteSizeLong() const PROTOBUF_FINAL; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( + bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; + int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const PROTOBUF_FINAL; + void InternalSwap(AccessInfo* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::google::protobuf::Metadata GetMetadata() const PROTOBUF_FINAL; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // repeated .google.protobuf.compiler.MessageAccessInfo message = 1; + int message_size() const; + void clear_message(); + static const int kMessageFieldNumber = 1; + const ::google::protobuf::compiler::MessageAccessInfo& message(int index) const; + ::google::protobuf::compiler::MessageAccessInfo* mutable_message(int index); + ::google::protobuf::compiler::MessageAccessInfo* add_message(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* + mutable_message(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& + message() const; + + // @@protoc_insertion_point(class_scope:google.protobuf.compiler.AccessInfo) + private: + + ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; + ::google::protobuf::internal::HasBits<1> _has_bits_; + mutable int _cached_size_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo > message_; + friend struct protobuf_google_2fprotobuf_2fcompiler_2fprofile_2eproto::TableStruct; +}; +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +// FieldAccessInfo + +// optional string name = 1; +inline bool FieldAccessInfo::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void FieldAccessInfo::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void FieldAccessInfo::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void FieldAccessInfo::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& FieldAccessInfo::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.name) + return name_.GetNoArena(); +} +inline void FieldAccessInfo::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.name) +} +#if LANG_CXX11 +inline void FieldAccessInfo::set_name(::std::string&& value) { + set_has_name(); + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.FieldAccessInfo.name) +} +#endif +inline void FieldAccessInfo::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.FieldAccessInfo.name) +} +inline void FieldAccessInfo::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.FieldAccessInfo.name) +} +inline ::std::string* FieldAccessInfo::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.FieldAccessInfo.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* FieldAccessInfo::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.FieldAccessInfo.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void FieldAccessInfo::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.FieldAccessInfo.name) +} + +// optional uint64 getters_count = 2; +inline bool FieldAccessInfo::has_getters_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void FieldAccessInfo::set_has_getters_count() { + _has_bits_[0] |= 0x00000002u; +} +inline void FieldAccessInfo::clear_has_getters_count() { + _has_bits_[0] &= ~0x00000002u; +} +inline void FieldAccessInfo::clear_getters_count() { + getters_count_ = GOOGLE_ULONGLONG(0); + clear_has_getters_count(); +} +inline ::google::protobuf::uint64 FieldAccessInfo::getters_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.getters_count) + return getters_count_; +} +inline void FieldAccessInfo::set_getters_count(::google::protobuf::uint64 value) { + set_has_getters_count(); + getters_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.getters_count) +} + +// optional uint64 setters_count = 3; +inline bool FieldAccessInfo::has_setters_count() const { + return (_has_bits_[0] & 0x00000004u) != 0; +} +inline void FieldAccessInfo::set_has_setters_count() { + _has_bits_[0] |= 0x00000004u; +} +inline void FieldAccessInfo::clear_has_setters_count() { + _has_bits_[0] &= ~0x00000004u; +} +inline void FieldAccessInfo::clear_setters_count() { + setters_count_ = GOOGLE_ULONGLONG(0); + clear_has_setters_count(); +} +inline ::google::protobuf::uint64 FieldAccessInfo::setters_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.setters_count) + return setters_count_; +} +inline void FieldAccessInfo::set_setters_count(::google::protobuf::uint64 value) { + set_has_setters_count(); + setters_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.setters_count) +} + +// optional uint64 configs_count = 4; +inline bool FieldAccessInfo::has_configs_count() const { + return (_has_bits_[0] & 0x00000008u) != 0; +} +inline void FieldAccessInfo::set_has_configs_count() { + _has_bits_[0] |= 0x00000008u; +} +inline void FieldAccessInfo::clear_has_configs_count() { + _has_bits_[0] &= ~0x00000008u; +} +inline void FieldAccessInfo::clear_configs_count() { + configs_count_ = GOOGLE_ULONGLONG(0); + clear_has_configs_count(); +} +inline ::google::protobuf::uint64 FieldAccessInfo::configs_count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.FieldAccessInfo.configs_count) + return configs_count_; +} +inline void FieldAccessInfo::set_configs_count(::google::protobuf::uint64 value) { + set_has_configs_count(); + configs_count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.FieldAccessInfo.configs_count) +} + +// ------------------------------------------------------------------- + +// MessageAccessInfo + +// optional string name = 1; +inline bool MessageAccessInfo::has_name() const { + return (_has_bits_[0] & 0x00000001u) != 0; +} +inline void MessageAccessInfo::set_has_name() { + _has_bits_[0] |= 0x00000001u; +} +inline void MessageAccessInfo::clear_has_name() { + _has_bits_[0] &= ~0x00000001u; +} +inline void MessageAccessInfo::clear_name() { + name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + clear_has_name(); +} +inline const ::std::string& MessageAccessInfo::name() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.name) + return name_.GetNoArena(); +} +inline void MessageAccessInfo::set_name(const ::std::string& value) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value); + // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.name) +} +#if LANG_CXX11 +inline void MessageAccessInfo::set_name(::std::string&& value) { + set_has_name(); + name_.SetNoArena( + &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value)); + // @@protoc_insertion_point(field_set_rvalue:google.protobuf.compiler.MessageAccessInfo.name) +} +#endif +inline void MessageAccessInfo::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); + // @@protoc_insertion_point(field_set_char:google.protobuf.compiler.MessageAccessInfo.name) +} +inline void MessageAccessInfo::set_name(const char* value, size_t size) { + set_has_name(); + name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), + ::std::string(reinterpret_cast(value), size)); + // @@protoc_insertion_point(field_set_pointer:google.protobuf.compiler.MessageAccessInfo.name) +} +inline ::std::string* MessageAccessInfo::mutable_name() { + set_has_name(); + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.name) + return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline ::std::string* MessageAccessInfo::release_name() { + // @@protoc_insertion_point(field_release:google.protobuf.compiler.MessageAccessInfo.name) + clear_has_name(); + return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); +} +inline void MessageAccessInfo::set_allocated_name(::std::string* name) { + if (name != NULL) { + set_has_name(); + } else { + clear_has_name(); + } + name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name); + // @@protoc_insertion_point(field_set_allocated:google.protobuf.compiler.MessageAccessInfo.name) +} + +// optional uint64 count = 2; +inline bool MessageAccessInfo::has_count() const { + return (_has_bits_[0] & 0x00000002u) != 0; +} +inline void MessageAccessInfo::set_has_count() { + _has_bits_[0] |= 0x00000002u; +} +inline void MessageAccessInfo::clear_has_count() { + _has_bits_[0] &= ~0x00000002u; +} +inline void MessageAccessInfo::clear_count() { + count_ = GOOGLE_ULONGLONG(0); + clear_has_count(); +} +inline ::google::protobuf::uint64 MessageAccessInfo::count() const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.count) + return count_; +} +inline void MessageAccessInfo::set_count(::google::protobuf::uint64 value) { + set_has_count(); + count_ = value; + // @@protoc_insertion_point(field_set:google.protobuf.compiler.MessageAccessInfo.count) +} + +// repeated .google.protobuf.compiler.FieldAccessInfo field = 3; +inline int MessageAccessInfo::field_size() const { + return field_.size(); +} +inline void MessageAccessInfo::clear_field() { + field_.Clear(); +} +inline const ::google::protobuf::compiler::FieldAccessInfo& MessageAccessInfo::field(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Get(index); +} +inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::mutable_field(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Mutable(index); +} +inline ::google::protobuf::compiler::FieldAccessInfo* MessageAccessInfo::add_field() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.MessageAccessInfo.field) + return field_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >* +MessageAccessInfo::mutable_field() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.MessageAccessInfo.field) + return &field_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::FieldAccessInfo >& +MessageAccessInfo::field() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.MessageAccessInfo.field) + return field_; +} + +// ------------------------------------------------------------------- + +// AccessInfo + +// repeated .google.protobuf.compiler.MessageAccessInfo message = 1; +inline int AccessInfo::message_size() const { + return message_.size(); +} +inline void AccessInfo::clear_message() { + message_.Clear(); +} +inline const ::google::protobuf::compiler::MessageAccessInfo& AccessInfo::message(int index) const { + // @@protoc_insertion_point(field_get:google.protobuf.compiler.AccessInfo.message) + return message_.Get(index); +} +inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::mutable_message(int index) { + // @@protoc_insertion_point(field_mutable:google.protobuf.compiler.AccessInfo.message) + return message_.Mutable(index); +} +inline ::google::protobuf::compiler::MessageAccessInfo* AccessInfo::add_message() { + // @@protoc_insertion_point(field_add:google.protobuf.compiler.AccessInfo.message) + return message_.Add(); +} +inline ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >* +AccessInfo::mutable_message() { + // @@protoc_insertion_point(field_mutable_list:google.protobuf.compiler.AccessInfo.message) + return &message_; +} +inline const ::google::protobuf::RepeatedPtrField< ::google::protobuf::compiler::MessageAccessInfo >& +AccessInfo::message() const { + // @@protoc_insertion_point(field_list:google.protobuf.compiler.AccessInfo.message) + return message_; +} + +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS +// ------------------------------------------------------------------- + +// ------------------------------------------------------------------- + + +// @@protoc_insertion_point(namespace_scope) + + +} // namespace compiler +} // namespace protobuf +} // namespace google + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_google_2fprotobuf_2fcompiler_2fprofile_2eproto__INCLUDED diff --git a/src/google/protobuf/compiler/profile.proto b/src/google/protobuf/compiler/profile.proto new file mode 100644 index 00000000..09ebe091 --- /dev/null +++ b/src/google/protobuf/compiler/profile.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. + +// Author: seongkim@google.com (Seong Beom Kim) +// +// protoc (Protocol Compiler) can generate more efficient code +// if it knows how a workload accesses fields of a message; +// e.g. some much more frequently than others. +// +// Protos defined here describe the access information per message +// and per field. Note that one can use any methods to collect +// the access patterns like CPU profiling, instrumented build, etc. + +syntax = "proto2"; + +package google.protobuf.compiler; + +// To convey the access pattern of a field, it classifies +// the type of the accessor methods into getters, setters and +// configs. Getters and setters read and write the field +// respectively and other operations like checking if the field +// exists are considered as configs. +message FieldAccessInfo { + optional string name = 1; + optional uint64 getters_count = 2; + optional uint64 setters_count = 3; + optional uint64 configs_count = 4; +} + +// "count" correlates with how many samples an access info has +// for a message. High "count" means more confident optimization +// based on the info. +message MessageAccessInfo { + optional string name = 1; + optional uint64 count = 2; + repeated FieldAccessInfo field = 3; +} + +message AccessInfo { + repeated MessageAccessInfo message = 1; +} diff --git a/src/google/protobuf/compiler/test_plugin.cc b/src/google/protobuf/compiler/test_plugin.cc index 4830fd70..c676ce8c 100644 --- a/src/google/protobuf/compiler/test_plugin.cc +++ b/src/google/protobuf/compiler/test_plugin.cc @@ -37,7 +37,6 @@ #include #include #include -#include int main(int argc, char* argv[]) { #ifdef _MSC_VER diff --git a/src/google/protobuf/compiler/zip_writer.cc b/src/google/protobuf/compiler/zip_writer.cc index 07d52b18..458cced2 100644 --- a/src/google/protobuf/compiler/zip_writer.cc +++ b/src/google/protobuf/compiler/zip_writer.cc @@ -28,6 +28,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// 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: ambrose@google.com (Ambrose Feinstein), // kenton@google.com (Kenton Varda) // diff --git a/src/google/protobuf/compiler/zip_writer.h b/src/google/protobuf/compiler/zip_writer.h index 737f4d42..03db4d57 100644 --- a/src/google/protobuf/compiler/zip_writer.h +++ b/src/google/protobuf/compiler/zip_writer.h @@ -28,6 +28,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// 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) #include diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index c87327ce..6a807926 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -72,6 +72,79 @@ namespace google { namespace protobuf { +struct Symbol { + enum Type { + NULL_SYMBOL, + MESSAGE, + FIELD, + ONEOF, + ENUM, + ENUM_VALUE, + SERVICE, + METHOD, + PACKAGE + }; + Type type; + union { + const Descriptor* descriptor; + const FieldDescriptor* field_descriptor; + const OneofDescriptor* oneof_descriptor; + const EnumDescriptor* enum_descriptor; + const EnumValueDescriptor* enum_value_descriptor; + const ServiceDescriptor* service_descriptor; + const MethodDescriptor* method_descriptor; + const FileDescriptor* package_file_descriptor; + }; + + inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } + inline bool IsNull() const { return type == NULL_SYMBOL; } + inline bool IsType() const { return type == MESSAGE || type == ENUM; } + inline bool IsAggregate() const { + return type == MESSAGE || type == PACKAGE || type == ENUM || + type == SERVICE; + } + +#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ + inline explicit Symbol(const TYPE* value) { \ + type = TYPE_CONSTANT; \ + this->FIELD = value; \ + } + + CONSTRUCTOR(Descriptor, MESSAGE, descriptor) + CONSTRUCTOR(FieldDescriptor, FIELD, field_descriptor) + CONSTRUCTOR(OneofDescriptor, ONEOF, oneof_descriptor) + CONSTRUCTOR(EnumDescriptor, ENUM, enum_descriptor) + CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor) + CONSTRUCTOR(ServiceDescriptor, SERVICE, service_descriptor) + CONSTRUCTOR(MethodDescriptor, METHOD, method_descriptor) + CONSTRUCTOR(FileDescriptor, PACKAGE, package_file_descriptor) +#undef CONSTRUCTOR + + const FileDescriptor* GetFile() const { + switch (type) { + case NULL_SYMBOL: + return NULL; + case MESSAGE: + return descriptor->file(); + case FIELD: + return field_descriptor->file(); + case ONEOF: + return oneof_descriptor->containing_type()->file(); + case ENUM: + return enum_descriptor->file(); + case ENUM_VALUE: + return enum_value_descriptor->type()->file(); + case SERVICE: + return service_descriptor->file(); + case METHOD: + return method_descriptor->service()->file(); + case PACKAGE: + return package_file_descriptor; + } + return NULL; + } +}; + const FieldDescriptor::CppType FieldDescriptor::kTypeToCppTypeMap[MAX_TYPE + 1] = { static_cast(0), // 0 is reserved for errors @@ -369,65 +442,6 @@ struct PointerStringPairHash { }; -struct Symbol { - enum Type { - NULL_SYMBOL, MESSAGE, FIELD, ONEOF, ENUM, ENUM_VALUE, SERVICE, METHOD, - PACKAGE - }; - Type type; - union { - const Descriptor* descriptor; - const FieldDescriptor* field_descriptor; - const OneofDescriptor* oneof_descriptor; - const EnumDescriptor* enum_descriptor; - const EnumValueDescriptor* enum_value_descriptor; - const ServiceDescriptor* service_descriptor; - const MethodDescriptor* method_descriptor; - const FileDescriptor* package_file_descriptor; - }; - - inline Symbol() : type(NULL_SYMBOL) { descriptor = NULL; } - inline bool IsNull() const { return type == NULL_SYMBOL; } - inline bool IsType() const { - return type == MESSAGE || type == ENUM; - } - inline bool IsAggregate() const { - return type == MESSAGE || type == PACKAGE - || type == ENUM || type == SERVICE; - } - -#define CONSTRUCTOR(TYPE, TYPE_CONSTANT, FIELD) \ - inline explicit Symbol(const TYPE* value) { \ - type = TYPE_CONSTANT; \ - this->FIELD = value; \ - } - - CONSTRUCTOR(Descriptor , MESSAGE , descriptor ) - CONSTRUCTOR(FieldDescriptor , FIELD , field_descriptor ) - CONSTRUCTOR(OneofDescriptor , ONEOF , oneof_descriptor ) - CONSTRUCTOR(EnumDescriptor , ENUM , enum_descriptor ) - CONSTRUCTOR(EnumValueDescriptor, ENUM_VALUE, enum_value_descriptor ) - CONSTRUCTOR(ServiceDescriptor , SERVICE , service_descriptor ) - CONSTRUCTOR(MethodDescriptor , METHOD , method_descriptor ) - CONSTRUCTOR(FileDescriptor , PACKAGE , package_file_descriptor) -#undef CONSTRUCTOR - - const FileDescriptor* GetFile() const { - switch (type) { - case NULL_SYMBOL: return NULL; - case MESSAGE : return descriptor ->file(); - case FIELD : return field_descriptor ->file(); - case ONEOF : return oneof_descriptor ->containing_type()->file(); - case ENUM : return enum_descriptor ->file(); - case ENUM_VALUE : return enum_value_descriptor->type()->file(); - case SERVICE : return service_descriptor ->file(); - case METHOD : return method_descriptor ->service()->file(); - case PACKAGE : return package_file_descriptor; - } - return NULL; - } -}; - const Symbol kNullSymbol; typedef hash_map strings_; // All strings in the pool. std::vector messages_; // All messages in the pool. + std::vector + once_dynamics_; // All GoogleOnceDynamics in the pool. std::vector file_tables_; // All file tables in the pool. std::vector allocations_; // All other memory allocated in the pool. @@ -632,19 +652,20 @@ class DescriptorPool::Tables { struct CheckPoint { explicit CheckPoint(const Tables* tables) - : strings_before_checkpoint(tables->strings_.size()), - messages_before_checkpoint(tables->messages_.size()), - file_tables_before_checkpoint(tables->file_tables_.size()), - allocations_before_checkpoint(tables->allocations_.size()), - pending_symbols_before_checkpoint( - tables->symbols_after_checkpoint_.size()), - pending_files_before_checkpoint( - tables->files_after_checkpoint_.size()), - pending_extensions_before_checkpoint( - tables->extensions_after_checkpoint_.size()) { - } + : strings_before_checkpoint(tables->strings_.size()), + messages_before_checkpoint(tables->messages_.size()), + once_dynamics_before_checkpoint(tables->once_dynamics_.size()), + file_tables_before_checkpoint(tables->file_tables_.size()), + allocations_before_checkpoint(tables->allocations_.size()), + pending_symbols_before_checkpoint( + tables->symbols_after_checkpoint_.size()), + pending_files_before_checkpoint( + tables->files_after_checkpoint_.size()), + pending_extensions_before_checkpoint( + tables->extensions_after_checkpoint_.size()) {} int strings_before_checkpoint; int messages_before_checkpoint; + int once_dynamics_before_checkpoint; int file_tables_before_checkpoint; int allocations_before_checkpoint; int pending_symbols_before_checkpoint; @@ -767,6 +788,7 @@ DescriptorPool::Tables::~Tables() { } STLDeleteElements(&strings_); STLDeleteElements(&file_tables_); + STLDeleteElements(&once_dynamics_); } FileDescriptorTables::FileDescriptorTables() @@ -855,6 +877,9 @@ void DescriptorPool::Tables::RollbackToLastCheckpoint() { STLDeleteContainerPointers( messages_.begin() + checkpoint.messages_before_checkpoint, messages_.end()); + STLDeleteContainerPointers( + once_dynamics_.begin() + checkpoint.once_dynamics_before_checkpoint, + once_dynamics_.end()); STLDeleteContainerPointers( file_tables_.begin() + checkpoint.file_tables_before_checkpoint, file_tables_.end()); @@ -866,6 +891,7 @@ void DescriptorPool::Tables::RollbackToLastCheckpoint() { strings_.resize(checkpoint.strings_before_checkpoint); messages_.resize(checkpoint.messages_before_checkpoint); + once_dynamics_.resize(checkpoint.once_dynamics_before_checkpoint); file_tables_.resize(checkpoint.file_tables_before_checkpoint); allocations_.resize(checkpoint.allocations_before_checkpoint); checkpoints_.pop_back(); @@ -1104,6 +1130,12 @@ string* DescriptorPool::Tables::AllocateString(const string& value) { return result; } +GoogleOnceDynamic* DescriptorPool::Tables::AllocateOnceDynamic() { + GoogleOnceDynamic* result = new GoogleOnceDynamic(); + once_dynamics_.push_back(result); + return result; +} + template Type* DescriptorPool::Tables::AllocateMessage(Type* /* dummy */) { Type* result = new Type; @@ -1157,8 +1189,10 @@ DescriptorPool::DescriptorPool() underlay_(NULL), tables_(new Tables), enforce_dependencies_(true), + lazily_build_dependencies_(false), allow_unknown_(false), - enforce_weak_(false) {} + enforce_weak_(false), + disallow_enforce_utf8_(false) {} DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, ErrorCollector* error_collector) @@ -1168,8 +1202,10 @@ DescriptorPool::DescriptorPool(DescriptorDatabase* fallback_database, underlay_(NULL), tables_(new Tables), enforce_dependencies_(true), + lazily_build_dependencies_(false), allow_unknown_(false), - enforce_weak_(false) { + enforce_weak_(false), + disallow_enforce_utf8_(false) { } DescriptorPool::DescriptorPool(const DescriptorPool* underlay) @@ -1179,8 +1215,10 @@ DescriptorPool::DescriptorPool(const DescriptorPool* underlay) underlay_(underlay), tables_(new Tables), enforce_dependencies_(true), + lazily_build_dependencies_(false), allow_unknown_(false), - enforce_weak_(false) {} + enforce_weak_(false), + disallow_enforce_utf8_(false) {} DescriptorPool::~DescriptorPool() { if (mutex_ != NULL) delete mutex_; @@ -1225,6 +1263,7 @@ void DeleteGeneratedPool() { static void InitGeneratedPool() { generated_database_ = new EncodedDescriptorDatabase; generated_pool_ = new DescriptorPool(generated_database_); + generated_pool_->InternalSetLazilyBuildDependencies(); internal::OnShutdown(&DeleteGeneratedPool); } @@ -3023,15 +3062,16 @@ class DescriptorBuilder { // - Search the pool's underlay if not found in tables_. // - Insure that the resulting Symbol is from one of the file's declared // dependencies. - Symbol FindSymbol(const string& name); + Symbol FindSymbol(const string& name, bool build_it = true); // Like FindSymbol() but does not require that the symbol is in one of the // file's declared dependencies. - Symbol FindSymbolNotEnforcingDeps(const string& name); + Symbol FindSymbolNotEnforcingDeps(const string& name, bool build_it = true); // This implements the body of FindSymbolNotEnforcingDeps(). Symbol FindSymbolNotEnforcingDepsHelper(const DescriptorPool* pool, - const string& name); + const string& name, + bool build_it = true); // Like FindSymbol(), but looks up the name relative to some other symbol // name. This first searches siblings of relative_to, then siblings of its @@ -3047,31 +3087,21 @@ class DescriptorBuilder { // that LookupSymbol may still return a non-type symbol in LOOKUP_TYPES mode, // if it believes that's all it could refer to. The caller should always // check that it receives the type of symbol it was expecting. - enum PlaceholderType { - PLACEHOLDER_MESSAGE, - PLACEHOLDER_ENUM, - PLACEHOLDER_EXTENDABLE_MESSAGE - }; enum ResolveMode { LOOKUP_ALL, LOOKUP_TYPES }; Symbol LookupSymbol(const string& name, const string& relative_to, - PlaceholderType placeholder_type = PLACEHOLDER_MESSAGE, - ResolveMode resolve_mode = LOOKUP_ALL); + DescriptorPool::PlaceholderType placeholder_type = + DescriptorPool::PLACEHOLDER_MESSAGE, + ResolveMode resolve_mode = LOOKUP_ALL, + bool build_it = true); // Like LookupSymbol() but will not return a placeholder even if // AllowUnknownDependencies() has been used. Symbol LookupSymbolNoPlaceholder(const string& name, const string& relative_to, - ResolveMode resolve_mode = LOOKUP_ALL); - - // Creates a placeholder type suitable for return from LookupSymbol(). May - // return kNullSymbol if the name is not a valid type name. - Symbol NewPlaceholder(const string& name, PlaceholderType placeholder_type); - - // Creates a placeholder file. Never returns NULL. This is used when an - // import is not found and AllowUnknownDependencies() is enabled. - FileDescriptor* NewPlaceholderFile(const string& name); + ResolveMode resolve_mode = LOOKUP_ALL, + bool build_it = true); // Calls tables_->AddSymbol() and records an error if it fails. Returns // true if successful or false if failed, though most callers can ignore @@ -3093,10 +3123,6 @@ class DescriptorBuilder { void ValidateSymbolName(const string& name, const string& full_name, const Message& proto); - // Like ValidateSymbolName(), but the name is allowed to contain periods and - // an error is indicated by returning false (not recording the error). - bool ValidateQualifiedName(const string& name); - // Used by BUILD_ARRAY macro (below) to avoid having to have the type // specified as a macro parameter. template @@ -3495,7 +3521,7 @@ void DescriptorBuilder::RecordPublicDependencies(const FileDescriptor* file) { } Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( - const DescriptorPool* pool, const string& name) { + const DescriptorPool* pool, const string& name, bool build_it) { // If we are looking at an underlay, we must lock its mutex_, since we are // accessing the underlay's tables_ directly. MutexLockMaybe lock((pool == pool_) ? NULL : pool->mutex_); @@ -3507,12 +3533,14 @@ Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( } if (result.IsNull()) { - // In theory, we shouldn't need to check fallback_database_ because the - // symbol should be in one of its file's direct dependencies, and we have - // already loaded those by the time we get here. But we check anyway so - // that we can generate better error message when dependencies are missing - // (i.e., "missing dependency" rather than "type is not defined"). - if (pool->TryFindSymbolInFallbackDatabase(name)) { + // With lazily_build_dependencies_, a symbol lookup at cross link time is + // not guaranteed to be successful. In most cases, build_it will be false, + // which intentionally prevents us from building an import until it's + // actually needed. In some cases, like registering an extension, we want + // to build the file containing the symbol, and build_it will be set. + // Also, build_it will be true when !lazily_build_dependencies_, to provide + // better error reporting of missing dependencies. + if (build_it && pool->TryFindSymbolInFallbackDatabase(name)) { result = pool->tables_->FindSymbol(name); } } @@ -3520,17 +3548,18 @@ Symbol DescriptorBuilder::FindSymbolNotEnforcingDepsHelper( return result; } -Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name) { - return FindSymbolNotEnforcingDepsHelper(pool_, name); +Symbol DescriptorBuilder::FindSymbolNotEnforcingDeps(const string& name, + bool build_it) { + return FindSymbolNotEnforcingDepsHelper(pool_, name, build_it); } -Symbol DescriptorBuilder::FindSymbol(const string& name) { - Symbol result = FindSymbolNotEnforcingDeps(name); +Symbol DescriptorBuilder::FindSymbol(const string& name, bool build_it) { + Symbol result = FindSymbolNotEnforcingDeps(name, build_it); if (result.IsNull()) return result; if (!pool_->enforce_dependencies_) { - // Hack for CompilerUpgrader. + // Hack for CompilerUpgrader, and also used for lazily_build_dependencies_ return result; } @@ -3564,14 +3593,16 @@ Symbol DescriptorBuilder::FindSymbol(const string& name) { return kNullSymbol; } -Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( - const string& name, const string& relative_to, ResolveMode resolve_mode) { +Symbol DescriptorBuilder::LookupSymbolNoPlaceholder(const string& name, + const string& relative_to, + ResolveMode resolve_mode, + bool build_it) { possible_undeclared_dependency_ = NULL; undefine_resolved_name_.clear(); - if (name.size() > 0 && name[0] == '.') { + if (!name.empty() && name[0] == '.') { // Fully-qualified name. - return FindSymbol(name.substr(1)); + return FindSymbol(name.substr(1), build_it); } // If name is something like "Foo.Bar.baz", and symbols named "Foo" are @@ -3599,7 +3630,7 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( // Chop off the last component of the scope. string::size_type dot_pos = scope_to_try.find_last_of('.'); if (dot_pos == string::npos) { - return FindSymbol(name); + return FindSymbol(name, build_it); } else { scope_to_try.erase(dot_pos); } @@ -3608,7 +3639,7 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( string::size_type old_size = scope_to_try.size(); scope_to_try.append(1, '.'); scope_to_try.append(first_part_of_name); - Symbol result = FindSymbol(scope_to_try); + Symbol result = FindSymbol(scope_to_try, build_it); if (!result.IsNull()) { if (first_part_of_name.size() < name.size()) { // name is a compound symbol, of which we only found the first part. @@ -3616,7 +3647,7 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( if (result.IsAggregate()) { scope_to_try.append(name, first_part_of_name.size(), name.size() - first_part_of_name.size()); - result = FindSymbol(scope_to_try); + result = FindSymbol(scope_to_try, build_it); if (result.IsNull()) { undefine_resolved_name_ = scope_to_try; } @@ -3640,19 +3671,49 @@ Symbol DescriptorBuilder::LookupSymbolNoPlaceholder( Symbol DescriptorBuilder::LookupSymbol( const string& name, const string& relative_to, - PlaceholderType placeholder_type, ResolveMode resolve_mode) { - Symbol result = LookupSymbolNoPlaceholder( - name, relative_to, resolve_mode); + DescriptorPool::PlaceholderType placeholder_type, ResolveMode resolve_mode, + bool build_it) { + Symbol result = + LookupSymbolNoPlaceholder(name, relative_to, resolve_mode, build_it); if (result.IsNull() && pool_->allow_unknown_) { // Not found, but AllowUnknownDependencies() is enabled. Return a // placeholder instead. - result = NewPlaceholder(name, placeholder_type); + result = pool_->NewPlaceholderWithMutexHeld(name, placeholder_type); } return result; } -Symbol DescriptorBuilder::NewPlaceholder(const string& name, - PlaceholderType placeholder_type) { +static bool ValidateQualifiedName(const string& name) { + bool last_was_period = false; + + for (int i = 0; i < name.size(); i++) { + // I don't trust isalnum() due to locales. :( + if (('a' <= name[i] && name[i] <= 'z') || + ('A' <= name[i] && name[i] <= 'Z') || + ('0' <= name[i] && name[i] <= '9') || (name[i] == '_')) { + last_was_period = false; + } else if (name[i] == '.') { + if (last_was_period) return false; + last_was_period = true; + } else { + return false; + } + } + + return !name.empty() && !last_was_period; +} + +Symbol DescriptorPool::NewPlaceholder(const string& name, + PlaceholderType placeholder_type) const { + MutexLockMaybe lock(mutex_); + return NewPlaceholderWithMutexHeld(name, placeholder_type); +} + +Symbol DescriptorPool::NewPlaceholderWithMutexHeld( + const string& name, PlaceholderType placeholder_type) const { + if (mutex_) { + mutex_->AssertHeld(); + } // Compute names. const string* placeholder_full_name; const string* placeholder_name; @@ -3678,7 +3739,7 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name, } // Create the placeholders. - FileDescriptor* placeholder_file = NewPlaceholderFile( + FileDescriptor* placeholder_file = NewPlaceholderFileWithMutexHeld( *placeholder_full_name + ".placeholder.proto"); placeholder_file->package_ = placeholder_package; @@ -3744,19 +3805,28 @@ Symbol DescriptorBuilder::NewPlaceholder(const string& name, } } -FileDescriptor* DescriptorBuilder::NewPlaceholderFile( - const string& name) { +FileDescriptor* DescriptorPool::NewPlaceholderFile(const string& name) const { + MutexLockMaybe lock(mutex_); + return NewPlaceholderFileWithMutexHeld(name); +} + +FileDescriptor* DescriptorPool::NewPlaceholderFileWithMutexHeld( + const string& name) const { + if (mutex_) { + mutex_->AssertHeld(); + } FileDescriptor* placeholder = tables_->Allocate(); memset(placeholder, 0, sizeof(*placeholder)); placeholder->name_ = tables_->AllocateString(name); placeholder->package_ = &internal::GetEmptyString(); - placeholder->pool_ = pool_; + placeholder->pool_ = this; placeholder->options_ = &FileOptions::default_instance(); placeholder->tables_ = &FileDescriptorTables::GetEmptyInstance(); placeholder->source_code_info_ = &SourceCodeInfo::default_instance(); placeholder->is_placeholder_ = true; placeholder->syntax_ = FileDescriptor::SYNTAX_PROTO2; + placeholder->finished_building_ = true; // All other fields are zero or NULL. return placeholder; @@ -3850,27 +3920,6 @@ void DescriptorBuilder::ValidateSymbolName( } } -bool DescriptorBuilder::ValidateQualifiedName(const string& name) { - bool last_was_period = false; - - for (int i = 0; i < name.size(); i++) { - // I don't trust isalnum() due to locales. :( - if (('a' <= name[i] && name[i] <= 'z') || - ('A' <= name[i] && name[i] <= 'Z') || - ('0' <= name[i] && name[i] <= '9') || - (name[i] == '_')) { - last_was_period = false; - } else if (name[i] == '.') { - if (last_was_period) return false; - last_was_period = true; - } else { - return false; - } - } - - return !name.empty() && !last_was_period; -} - // ------------------------------------------------------------------- // This generic implementation is good for all descriptors except @@ -4014,20 +4063,22 @@ const FileDescriptor* DescriptorBuilder::BuildFile( } } - // If we have a fallback_database_, attempt to load all dependencies now, - // before checkpointing tables_. This avoids confusion with recursive - // checkpoints. - if (pool_->fallback_database_ != NULL) { - tables_->pending_files_.push_back(proto.name()); - for (int i = 0; i < proto.dependency_size(); i++) { - if (tables_->FindFile(proto.dependency(i)) == NULL && - (pool_->underlay_ == NULL || - pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { - // We don't care what this returns since we'll find out below anyway. - pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); + // If we have a fallback_database_, and we aren't doing lazy import building, + // attempt to load all dependencies now, before checkpointing tables_. This + // avoids confusion with recursive checkpoints. + if (!pool_->lazily_build_dependencies_) { + if (pool_->fallback_database_ != NULL) { + tables_->pending_files_.push_back(proto.name()); + for (int i = 0; i < proto.dependency_size(); i++) { + if (tables_->FindFile(proto.dependency(i)) == NULL && + (pool_->underlay_ == NULL || + pool_->underlay_->FindFileByName(proto.dependency(i)) == NULL)) { + // We don't care what this returns since we'll find out below anyway. + pool_->TryFindFileInFallbackDatabase(proto.dependency(i)); + } } + tables_->pending_files_.pop_back(); } - tables_->pending_files_.pop_back(); } return BuildFileImpl(proto); } @@ -4041,6 +4092,7 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( file_ = result; result->is_placeholder_ = false; + result->finished_building_ = false; if (proto.has_source_code_info()) { SourceCodeInfo *info = tables_->AllocateMessage(); info->CopyFrom(proto.source_code_info()); @@ -4098,7 +4150,17 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( std::set seen_dependencies; result->dependency_count_ = proto.dependency_size(); result->dependencies_ = - tables_->AllocateArray(proto.dependency_size()); + tables_->AllocateArray(proto.dependency_size()); + if (pool_->lazily_build_dependencies_) { + result->dependencies_once_ = tables_->AllocateOnceDynamic(); + result->dependencies_names_ = + tables_->AllocateArray(proto.dependency_size()); + memset(result->dependencies_names_, 0, + sizeof(*result->dependencies_names_) * proto.dependency_size()); + } else { + result->dependencies_once_ = NULL; + result->dependencies_names_ = NULL; + } unused_dependency_.clear(); std::set weak_deps; for (int i = 0; i < proto.weak_dependency_size(); ++i) { @@ -4125,9 +4187,12 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( if (dependency == NULL) { if (pool_->allow_unknown_ || (!pool_->enforce_weak_ && weak_deps.find(i) != weak_deps.end())) { - dependency = NewPlaceholderFile(proto.dependency(i)); + dependency = + pool_->NewPlaceholderFileWithMutexHeld(proto.dependency(i)); } else { - AddImportError(proto, i); + if (!pool_->lazily_build_dependencies_) { + AddImportError(proto, i); + } } } else { // Add to unused_dependency_ to track unused imported files. @@ -4141,6 +4206,10 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( } result->dependencies_[i] = dependency; + if (pool_->lazily_build_dependencies_ && !dependency) { + result->dependencies_names_[i] = + tables_->AllocateString(proto.dependency(i)); + } } // Check public dependencies. @@ -4153,7 +4222,12 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( if (index >= 0 && index < proto.dependency_size()) { result->public_dependencies_[public_dependency_count++] = index; // Do not track unused imported files for public import. - unused_dependency_.erase(result->dependency(index)); + // Calling dependency(i) builds that file when doing lazy imports, + // need to avoid doing this. Unused dependency detection isn't done + // when building lazily, anyways. + if (!pool_->lazily_build_dependencies_) { + unused_dependency_.erase(result->dependency(index)); + } } else { AddError(proto.name(), proto, DescriptorPool::ErrorCollector::OTHER, @@ -4164,8 +4238,13 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( // Build dependency set dependencies_.clear(); - for (int i = 0; i < result->dependency_count(); i++) { - RecordPublicDependencies(result->dependency(i)); + // We don't/can't do proper dependency error checking when + // lazily_build_dependencies_, and calling dependency(i) will force + // a dependency to be built, which we don't want. + if (!pool_->lazily_build_dependencies_) { + for (int i = 0; i < result->dependency_count(); i++) { + RecordPublicDependencies(result->dependency(i)); + } } // Check weak dependencies. @@ -4215,8 +4294,9 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( options_to_interpret_.clear(); } - // Validate options. - if (!had_errors_) { + // Validate options. See comments at InternalSetLazilyBuildDependencies about + // error checking and lazy import building. + if (!had_errors_ && !pool_->lazily_build_dependencies_) { ValidateFileOptions(result, proto); } @@ -4229,7 +4309,9 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( } - if (!unused_dependency_.empty()) { + // Again, see comments at InternalSetLazilyBuildDependencies about error + // checking. + if (!unused_dependency_.empty() && !pool_->lazily_build_dependencies_) { LogUnusedDependency(proto, result); } @@ -4238,6 +4320,7 @@ const FileDescriptor* DescriptorBuilder::BuildFileImpl( return NULL; } else { tables_->ClearLastCheckpoint(); + result->finished_building_ = true; return result; } } @@ -4447,6 +4530,10 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->extension_scope_ = NULL; result->message_type_ = NULL; result->enum_type_ = NULL; + result->type_name_ = NULL; + result->type_once_ = NULL; + result->default_value_enum_ = NULL; + result->default_value_enum_name_ = NULL; result->has_default_value_ = proto.has_default_value(); if (proto.has_default_value() && result->is_repeated()) { @@ -4947,8 +5034,8 @@ void DescriptorBuilder::BuildMethod(const MethodDescriptorProto& proto, ValidateSymbolName(proto.name(), *full_name, proto); // These will be filled in when cross-linking. - result->input_type_ = NULL; - result->output_type_ = NULL; + result->input_type_.Init(); + result->output_type_.Init(); // Copy options. if (!proto.has_options()) { @@ -5081,9 +5168,13 @@ void DescriptorBuilder::CrossLinkField( field->options_ = &FieldOptions::default_instance(); } + // Add the field to the lowercase-name and camelcase-name tables. + file_tables_->AddFieldByStylizedNames(field); + if (proto.has_extendee()) { - Symbol extendee = LookupSymbol(proto.extendee(), field->full_name(), - PLACEHOLDER_EXTENDABLE_MESSAGE); + Symbol extendee = + LookupSymbol(proto.extendee(), field->full_name(), + DescriptorPool::PLACEHOLDER_EXTENDABLE_MESSAGE); if (extendee.IsNull()) { AddNotDefinedError(field->full_name(), proto, DescriptorPool::ErrorCollector::EXTENDEE, @@ -5129,9 +5220,10 @@ void DescriptorBuilder::CrossLinkField( proto.has_default_value(); Symbol type = - LookupSymbol(proto.type_name(), field->full_name(), - expecting_enum ? PLACEHOLDER_ENUM : PLACEHOLDER_MESSAGE, - LOOKUP_TYPES); + LookupSymbol(proto.type_name(), field->full_name(), + expecting_enum ? DescriptorPool::PLACEHOLDER_ENUM + : DescriptorPool::PLACEHOLDER_MESSAGE, + LOOKUP_TYPES, !pool_->lazily_build_dependencies_); // If the type is a weak type, we change the type to a google.protobuf.Empty field. if (type.IsNull() && !pool_->enforce_weak_ && proto.options().weak()) { @@ -5139,10 +5231,35 @@ void DescriptorBuilder::CrossLinkField( } if (type.IsNull()) { - AddNotDefinedError(field->full_name(), proto, - DescriptorPool::ErrorCollector::TYPE, - proto.type_name()); - return; + if (pool_->lazily_build_dependencies_) { + // Save the symbol names for later for lookup, and allocate the once + // object needed for the accessors. + string name = proto.type_name(); + if (!pool_->enforce_weak_ && proto.options().weak()) { + name = kNonLinkedWeakMessageReplacementName; + } + field->type_once_ = tables_->AllocateOnceDynamic(); + field->type_name_ = tables_->AllocateString(name); + if (proto.has_default_value()) { + field->default_value_enum_name_ = + tables_->AllocateString(proto.default_value()); + } + // AddFieldByNumber and AddExtension are done later in this function, + // and can/must be done if the field type was not found. The related + // error checking is not necessary when in lazily_build_dependencies_ + // mode, and can't be done without building the type's descriptor, + // which we don't want to do. + file_tables_->AddFieldByNumber(field); + if (field->is_extension()) { + tables_->AddExtension(field); + } + return; + } else { + AddNotDefinedError(field->full_name(), proto, + DescriptorPool::ErrorCollector::TYPE, + proto.type_name()); + return; + } } if (!proto.has_type()) { @@ -5238,7 +5355,10 @@ void DescriptorBuilder::CrossLinkField( // Add the field to the fields-by-number table. // Note: We have to do this *after* cross-linking because extensions do not - // know their containing type until now. + // know their containing type until now. If we're in + // lazily_build_dependencies_ mode, we're guaranteed there's no errors, so no + // risk to calling containing_type() or other accessors that will build + // dependencies. if (!file_tables_->AddFieldByNumber(field)) { const FieldDescriptor* conflicting_field = file_tables_->FindFieldByNumber(field->containing_type(), @@ -5284,9 +5404,6 @@ void DescriptorBuilder::CrossLinkField( } } } - - // Add the field to the lowercase-name and camelcase-name tables. - file_tables_->AddFieldByStylizedNames(field); } void DescriptorBuilder::CrossLinkEnum( @@ -5325,30 +5442,44 @@ void DescriptorBuilder::CrossLinkMethod( method->options_ = &MethodOptions::default_instance(); } - Symbol input_type = LookupSymbol(proto.input_type(), method->full_name()); + Symbol input_type = + LookupSymbol(proto.input_type(), method->full_name(), + DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL, + !pool_->lazily_build_dependencies_); if (input_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::INPUT_TYPE, - proto.input_type()); + if (!pool_->lazily_build_dependencies_) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::INPUT_TYPE, + proto.input_type()); + } else { + method->input_type_.SetLazy(proto.input_type(), file_); + } } else if (input_type.type != Symbol::MESSAGE) { AddError(method->full_name(), proto, DescriptorPool::ErrorCollector::INPUT_TYPE, "\"" + proto.input_type() + "\" is not a message type."); } else { - method->input_type_ = input_type.descriptor; + method->input_type_.Set(input_type.descriptor); } - Symbol output_type = LookupSymbol(proto.output_type(), method->full_name()); + Symbol output_type = + LookupSymbol(proto.output_type(), method->full_name(), + DescriptorPool::PLACEHOLDER_MESSAGE, LOOKUP_ALL, + !pool_->lazily_build_dependencies_); if (output_type.IsNull()) { - AddNotDefinedError(method->full_name(), proto, - DescriptorPool::ErrorCollector::OUTPUT_TYPE, - proto.output_type()); + if (!pool_->lazily_build_dependencies_) { + AddNotDefinedError(method->full_name(), proto, + DescriptorPool::ErrorCollector::OUTPUT_TYPE, + proto.output_type()); + } else { + method->output_type_.SetLazy(proto.output_type(), file_); + } } else if (output_type.type != Symbol::MESSAGE) { AddError(method->full_name(), proto, DescriptorPool::ErrorCollector::OUTPUT_TYPE, "\"" + proto.output_type() + "\" is not a message type."); } else { - method->output_type_ = output_type.descriptor; + method->output_type_.Set(output_type.descriptor); } } @@ -5539,8 +5670,12 @@ void DescriptorBuilder::ValidateMessageOptions(Descriptor* message, } } + void DescriptorBuilder::ValidateFieldOptions(FieldDescriptor* field, const FieldDescriptorProto& proto) { + if (pool_->lazily_build_dependencies_ && (!field || !field->message_type())) { + return; + } // Only message type fields may be lazy. if (field->options().lazy()) { if (field->type() != FieldDescriptor::TYPE_MESSAGE) { @@ -6553,5 +6688,165 @@ void DescriptorBuilder::LogUnusedDependency(const FileDescriptorProto& proto, } } +Symbol DescriptorPool::CrossLinkOnDemandHelper(const string& name, + bool expecting_enum) const { + string lookup_name = name; + if (!lookup_name.empty() && lookup_name[0] == '.') { + lookup_name = lookup_name.substr(1); + } + Symbol result = tables_->FindByNameHelper(this, lookup_name); + return result; +} + +// Handle the lazy import building for a message field whose type wasn't built +// at cross link time. If that was the case, we saved the name of the type to +// be looked up when the accessor for the type was called. Set type_, +// enum_type_, message_type_, and default_value_enum_ appropriately. +void FieldDescriptor::InternalTypeOnceInit() const { + GOOGLE_CHECK(file()->finished_building_ == true); + if (type_name_) { + Symbol result = file()->pool()->CrossLinkOnDemandHelper( + *type_name_, type_ == FieldDescriptor::TYPE_ENUM); + if (result.type == Symbol::MESSAGE) { + type_ = FieldDescriptor::TYPE_MESSAGE; + message_type_ = result.descriptor; + } else if (result.type == Symbol::ENUM) { + type_ = FieldDescriptor::TYPE_ENUM; + enum_type_ = result.enum_descriptor; + } + } + if (enum_type_ && !default_value_enum_) { + if (default_value_enum_name_) { + // Have to build the full name now instead of at CrossLink time, + // because enum_type_ may not be known at the time. + string name = enum_type_->full_name(); + // Enum values reside in the same scope as the enum type. + string::size_type last_dot = name.find_last_of('.'); + if (last_dot != string::npos) { + name = name.substr(0, last_dot) + "." + *default_value_enum_name_; + } else { + name = *default_value_enum_name_; + } + Symbol result = file()->pool()->CrossLinkOnDemandHelper(name, true); + if (result.type == Symbol::ENUM_VALUE) { + default_value_enum_ = result.enum_value_descriptor; + } + } + if (!default_value_enum_) { + // We use the first defined value as the default + // if a default is not explicitly defined. + GOOGLE_CHECK(enum_type_->value_count()); + default_value_enum_ = enum_type_->value(0); + } + } +} + +void FieldDescriptor::TypeOnceInit(const FieldDescriptor* to_init) { + to_init->InternalTypeOnceInit(); +} + +// message_type(), enum_type(), default_value_enum(), and type() +// all share the same GoogleOnceDynamic init path to do lazy +// import building and cross linking of a field of a message. +const Descriptor* FieldDescriptor::message_type() const { + if (type_once_) { + type_once_->Init(&FieldDescriptor::TypeOnceInit, this); + } + return message_type_; +} + +const EnumDescriptor* FieldDescriptor::enum_type() const { + if (type_once_) { + type_once_->Init(&FieldDescriptor::TypeOnceInit, this); + } + return enum_type_; +} + +const EnumValueDescriptor* FieldDescriptor::default_value_enum() const { + if (type_once_) { + type_once_->Init(&FieldDescriptor::TypeOnceInit, this); + } + return default_value_enum_; +} + +FieldDescriptor::Type FieldDescriptor::type() const { + if (type_once_) { + type_once_->Init(&FieldDescriptor::TypeOnceInit, this); + } + return type_; +} + +void FileDescriptor::InternalDependenciesOnceInit() const { + GOOGLE_CHECK(finished_building_ == true); + for (int i = 0; i < dependency_count(); i++) { + if (dependencies_names_[i]) { + dependencies_[i] = pool_->FindFileByName(*dependencies_names_[i]); + } + } +} + +void FileDescriptor::DependenciesOnceInit(const FileDescriptor* to_init) { + to_init->InternalDependenciesOnceInit(); +} + +const FileDescriptor* FileDescriptor::dependency(int index) const { + if (dependencies_once_) { + // Do once init for all indicies, as it's unlikely only a single index would + // be called, and saves on GoogleOnceDynamic allocations. + dependencies_once_->Init(&FileDescriptor::DependenciesOnceInit, this); + } + return dependencies_[index]; +} + +const Descriptor* MethodDescriptor::input_type() const { + return input_type_.Get(); +} + +const Descriptor* MethodDescriptor::output_type() const { + return output_type_.Get(); +} + + +namespace internal { +void LazyDescriptor::Set(const Descriptor* descriptor) { + GOOGLE_CHECK(!name_); + GOOGLE_CHECK(!once_); + GOOGLE_CHECK(!file_); + descriptor_ = descriptor; +} + +void LazyDescriptor::SetLazy(const string& name, const FileDescriptor* file) { + // verify Init() has been called and Set hasn't been called yet. + GOOGLE_CHECK(!descriptor_); + GOOGLE_CHECK(!file_); + GOOGLE_CHECK(!name_); + GOOGLE_CHECK(!once_); + GOOGLE_CHECK(file && file->pool_); + GOOGLE_CHECK(file->pool_->lazily_build_dependencies_); + GOOGLE_CHECK(!file->finished_building_); + file_ = file; + name_ = file->pool_->tables_->AllocateString(name); + once_ = file->pool_->tables_->AllocateOnceDynamic(); +} + +void LazyDescriptor::Once() { + if (once_) { + once_->Init(&LazyDescriptor::OnceStatic, this); + } +} + +void LazyDescriptor::OnceStatic(LazyDescriptor* lazy) { lazy->OnceInternal(); } + +void LazyDescriptor::OnceInternal() { + GOOGLE_CHECK(file_->finished_building_); + if (!descriptor_ && name_) { + Symbol result = file_->pool_->CrossLinkOnDemandHelper(*name_, false); + if (!result.IsNull() && result.type == Symbol::MESSAGE) { + descriptor_ = result.descriptor; + } + } +} +} // namespace internal + } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/descriptor.h b/src/google/protobuf/descriptor.h index cc099693..7aea7344 100644 --- a/src/google/protobuf/descriptor.h +++ b/src/google/protobuf/descriptor.h @@ -63,6 +63,7 @@ #include #include #include +#include // TYPE_BOOL is defined in the MacOS's ConditionalMacros.h. #ifdef TYPE_BOOL @@ -110,6 +111,7 @@ class Message; // Defined in descriptor.cc class DescriptorBuilder; class FileDescriptorTables; +struct Symbol; // Defined in unknown_field_set.h. class UnknownField; @@ -165,6 +167,55 @@ struct DebugStringOptions { elide_oneof_body(false) {} }; +// A class to handle the simplest cases of a lazily linked descriptor +// for a message type that isn't built at the time of cross linking, +// which is needed when a pool has lazily_build_dependencies_ set. +// Must be instantiated as mutable in a descriptor. +namespace internal { +class LIBPROTOBUF_EXPORT LazyDescriptor { + public: + // Init function to be called at init time of a descriptor containing + // a LazyDescriptor. + void Init() { + descriptor_ = NULL; + name_ = NULL; + once_ = NULL; + file_ = NULL; + } + + // Sets the value of the descriptor if it is known during the descriptor + // building process. Not thread safe, should only be called during the + // descriptor build process. Should not be called after SetLazy has been + // called. + void Set(const Descriptor* descriptor); + + // Sets the information needed to lazily cross link the descriptor at a later + // time, SetLazy is not thread safe, should be called only once at descriptor + // build time if the symbol wasn't found and building of the file containing + // that type is delayed because lazily_build_dependencies_ is set on the pool. + // Should not be called after Set() has been called. + void SetLazy(const string& name, const FileDescriptor* file); + + // Returns the current value of the descriptor, thread-safe. If SetLazy(...) + // has been called, will do a one-time cross link of the type specified, + // building the descriptor file that contains the type if necessary. + inline const Descriptor* Get() { + Once(); + return descriptor_; + } + + private: + static void OnceStatic(LazyDescriptor* lazy); + void OnceInternal(); + void Once(); + + const Descriptor* descriptor_; + const string* name_; + GoogleOnceDynamic* once_; + const FileDescriptor* file_; +}; +} // namespace internal + // Describes a type of protocol message, or a particular group within a // message. To obtain the Descriptor for a given message object, call // Message::GetDescriptor(). Generated message classes also have a @@ -417,6 +468,7 @@ class LIBPROTOBUF_EXPORT Descriptor { // Must be constructed using DescriptorPool. Descriptor() {} friend class DescriptorBuilder; + friend class DescriptorPool; friend class EnumDescriptor; friend class FieldDescriptor; friend class OneofDescriptor; @@ -692,16 +744,21 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { const string* json_name_; const FileDescriptor* file_; int number_; - Type type_; + GoogleOnceDynamic* type_once_; + static void TypeOnceInit(const FieldDescriptor* to_init); + void InternalTypeOnceInit() const; + mutable Type type_; Label label_; bool is_extension_; int index_in_oneof_; const Descriptor* containing_type_; const OneofDescriptor* containing_oneof_; const Descriptor* extension_scope_; - const Descriptor* message_type_; - const EnumDescriptor* enum_type_; + mutable const Descriptor* message_type_; + mutable const EnumDescriptor* enum_type_; const FieldOptions* options_; + const string* type_name_; + const string* default_value_enum_name_; // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in // descriptor.cc and update them to initialize the field. @@ -716,7 +773,7 @@ class LIBPROTOBUF_EXPORT FieldDescriptor { double default_value_double_; bool default_value_bool_; - const EnumValueDescriptor* default_value_enum_; + mutable const EnumValueDescriptor* default_value_enum_; const string* default_value_string_; }; @@ -918,6 +975,7 @@ class LIBPROTOBUF_EXPORT EnumDescriptor { friend class FieldDescriptor; friend class EnumValueDescriptor; friend class FileDescriptor; + friend class DescriptorPool; friend class internal::GeneratedMessageReflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor); }; @@ -994,6 +1052,7 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptor { EnumValueDescriptor() {} friend class DescriptorBuilder; friend class EnumDescriptor; + friend class DescriptorPool; friend class FileDescriptorTables; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor); }; @@ -1144,8 +1203,8 @@ class LIBPROTOBUF_EXPORT MethodDescriptor { const string* name_; const string* full_name_; const ServiceDescriptor* service_; - const Descriptor* input_type_; - const Descriptor* output_type_; + mutable internal::LazyDescriptor input_type_; + mutable internal::LazyDescriptor output_type_; const MethodOptions* options_; bool client_streaming_; bool server_streaming_; @@ -1302,7 +1361,11 @@ class LIBPROTOBUF_EXPORT FileDescriptor { const string* package_; const DescriptorPool* pool_; int dependency_count_; - const FileDescriptor** dependencies_; + mutable const FileDescriptor** dependencies_; + const string** dependencies_names_; + GoogleOnceDynamic* dependencies_once_; + static void DependenciesOnceInit(const FileDescriptor* to_init); + void InternalDependenciesOnceInit() const; int public_dependency_count_; int* public_dependencies_; int weak_dependency_count_; @@ -1321,14 +1384,22 @@ class LIBPROTOBUF_EXPORT FileDescriptor { const FileDescriptorTables* tables_; const SourceCodeInfo* source_code_info_; + + // Indicates the FileDescriptor is completed building. Used to verify + // that type accessor functions that can possibly build a dependent file + // aren't called during the process of building the file. + bool finished_building_; + // IMPORTANT: If you add a new field, make sure to search for all instances // of Allocate() and AllocateArray() in // descriptor.cc and update them to initialize the field. FileDescriptor() {} friend class DescriptorBuilder; + friend class DescriptorPool; friend class Descriptor; friend class FieldDescriptor; + friend class internal::LazyDescriptor; friend class OneofDescriptor; friend class EnumDescriptor; friend class EnumValueDescriptor; @@ -1559,6 +1630,9 @@ class LIBPROTOBUF_EXPORT DescriptorPool { static void InternalAddGeneratedFile( const void* encoded_file_descriptor, int size); + // Disallow [enforce_utf8 = false] in .proto files. + void DisallowEnforceUtf8() { disallow_enforce_utf8_ = true; } + // For internal use only: Gets a non-const pointer to the generated pool. // This is called at static-initialization time only, so thread-safety is @@ -1571,6 +1645,21 @@ class LIBPROTOBUF_EXPORT DescriptorPool { // which it did not officially declare as dependencies. void InternalDontEnforceDependencies(); + // For internal use only: Enables lazy building of dependencies of a file. + // Delay the building of dependencies of a file descriptor until absolutely + // necessary, like when message_type() is called on a field that is defined + // in that dependency's file. This will cause functional issues if a proto + // or one of it's dependencies has errors. Should only be enabled for the + // generated_pool_ (because no descriptor build errors are guaranteed by + // the compilation generation process), testing, or if a lack of descriptor + // build errors can be guaranteed for a pool. + void InternalSetLazilyBuildDependencies() { + lazily_build_dependencies_ = true; + // This needs to be set when lazily building dependencies, as it breaks + // dependency checking. + InternalDontEnforceDependencies(); + } + // For internal use only. void internal_set_underlay(const DescriptorPool* underlay) { underlay_ = underlay; @@ -1589,10 +1678,13 @@ class LIBPROTOBUF_EXPORT DescriptorPool { private: friend class Descriptor; + friend class internal::LazyDescriptor; friend class FieldDescriptor; friend class EnumDescriptor; friend class ServiceDescriptor; + friend class MethodDescriptor; friend class FileDescriptor; + friend class StreamDescriptor; friend class DescriptorBuilder; friend class FileDescriptorTables; @@ -1616,6 +1708,28 @@ class LIBPROTOBUF_EXPORT DescriptorPool { const FileDescriptor* BuildFileFromDatabase( const FileDescriptorProto& proto) const; + // Helper for when lazily_build_dependencies_ is set, can look up a symbol + // after the file's descriptor is built, and can build the file where that + // symbol is defined if necessary. Will create a placeholder if the type + // doesn't exist in the fallback database, or the file doesn't build + // successfully. + Symbol CrossLinkOnDemandHelper(const string& name, bool expecting_enum) const; + + // Create a placeholder FileDescriptor of the specified name + FileDescriptor* NewPlaceholderFile(const string& name) const; + FileDescriptor* NewPlaceholderFileWithMutexHeld(const string& name) const; + + enum PlaceholderType { + PLACEHOLDER_MESSAGE, + PLACEHOLDER_ENUM, + PLACEHOLDER_EXTENDABLE_MESSAGE + }; + // Create a placeholder Descriptor of the specified name + Symbol NewPlaceholder(const string& name, + PlaceholderType placeholder_type) const; + Symbol NewPlaceholderWithMutexHeld(const string& name, + PlaceholderType placeholder_type) const; + // If fallback_database_ is NULL, this is NULL. Otherwise, this is a mutex // which must be locked while accessing tables_. Mutex* mutex_; @@ -1631,9 +1745,11 @@ class LIBPROTOBUF_EXPORT DescriptorPool { google::protobuf::scoped_ptr tables_; bool enforce_dependencies_; + bool lazily_build_dependencies_; bool allow_unknown_; bool enforce_weak_; std::set unused_import_track_files_; + bool disallow_enforce_utf8_; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorPool); }; @@ -1693,15 +1809,12 @@ PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, camelcase_name) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, file, const FileDescriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, number, int) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, is_extension, bool) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, type, FieldDescriptor::Type) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, label, FieldDescriptor::Label) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_type, const Descriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, containing_oneof, const OneofDescriptor*) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, index_in_oneof, int) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, extension_scope, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, message_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, enum_type, const EnumDescriptor*) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(FieldDescriptor, FieldOptions) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_default_value, bool) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, has_json_name, bool) @@ -1712,8 +1825,6 @@ PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_uint64, uint64) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_float , float ) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_double, double) PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_bool , bool ) -PROTOBUF_DEFINE_ACCESSOR(FieldDescriptor, default_value_enum, - const EnumValueDescriptor*) PROTOBUF_DEFINE_STRING_ACCESSOR(FieldDescriptor, default_value_string) PROTOBUF_DEFINE_STRING_ACCESSOR(OneofDescriptor, name) @@ -1749,8 +1860,6 @@ PROTOBUF_DEFINE_OPTIONS_ACCESSOR(ServiceDescriptor, ServiceOptions) PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, name) PROTOBUF_DEFINE_STRING_ACCESSOR(MethodDescriptor, full_name) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, service, const ServiceDescriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, input_type, const Descriptor*) -PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, output_type, const Descriptor*) PROTOBUF_DEFINE_OPTIONS_ACCESSOR(MethodDescriptor, MethodOptions) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, client_streaming, bool) PROTOBUF_DEFINE_ACCESSOR(MethodDescriptor, server_streaming, bool) @@ -1824,7 +1933,7 @@ inline bool FieldDescriptor::is_packable() const { // in the parent's array of children. inline int FieldDescriptor::index() const { if (!is_extension_) { - return static_cast(this - containing_type_->fields_); + return static_cast(this - containing_type()->fields_); } else if (extension_scope_ != NULL) { return static_cast(this - extension_scope_->extensions_); } else { @@ -1865,15 +1974,15 @@ inline int MethodDescriptor::index() const { } inline const char* FieldDescriptor::type_name() const { - return kTypeToName[type_]; + return kTypeToName[type()]; } inline FieldDescriptor::CppType FieldDescriptor::cpp_type() const { - return kTypeToCppTypeMap[type_]; + return kTypeToCppTypeMap[type()]; } inline const char* FieldDescriptor::cpp_type_name() const { - return kCppTypeToName[kTypeToCppTypeMap[type_]]; + return kCppTypeToName[kTypeToCppTypeMap[type()]]; } inline FieldDescriptor::CppType FieldDescriptor::TypeToCppType(Type type) { @@ -1895,18 +2004,14 @@ inline bool FieldDescriptor::IsTypePackable(Type field_type) { field_type != FieldDescriptor::TYPE_BYTES); } -inline const FileDescriptor* FileDescriptor::dependency(int index) const { - return dependencies_[index]; -} - inline const FileDescriptor* FileDescriptor::public_dependency( int index) const { - return dependencies_[public_dependencies_[index]]; + return dependency(public_dependencies_[index]); } inline const FileDescriptor* FileDescriptor::weak_dependency( int index) const { - return dependencies_[weak_dependencies_[index]]; + return dependency(weak_dependencies_[index]); } inline FileDescriptor::Syntax FileDescriptor::syntax() const { diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index 57fbfd86..56c395e6 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -80,17 +80,57 @@ const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[6]; } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_), ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_), @@ -119,6 +159,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_), 0, @@ -127,6 +168,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, start_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ReservedRange, end_), 0, @@ -135,6 +177,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_), @@ -159,6 +202,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_), @@ -173,8 +217,8 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { 6, 8, 9, - 1, 2, + 1, 3, 7, 4, @@ -183,6 +227,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofDescriptorProto, options_), 0, @@ -191,6 +236,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_), @@ -201,6 +247,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_), @@ -211,6 +258,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_), @@ -221,6 +269,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_), @@ -237,6 +286,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_), @@ -275,6 +325,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, deprecated_), @@ -289,6 +340,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, jstype_), @@ -297,22 +349,24 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_), 0, - 2, 1, + 5, + 2, 3, 4, - 5, ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(OneofOptions, uninterpreted_option_), ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_), @@ -323,6 +377,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_), 0, @@ -331,6 +386,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_), 0, @@ -339,6 +395,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _internal_metadata_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_), ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, deprecated_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, idempotency_level_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_), @@ -349,6 +406,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_), 0, @@ -357,6 +415,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_), @@ -375,6 +434,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_), @@ -389,12 +449,14 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_), ~0u, GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _has_bits_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, path_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, source_file_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo_Annotation, begin_), @@ -407,36 +469,37 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(GeneratedCodeInfo, annotation_), ~0u, }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { - { 0, 5, sizeof(FileDescriptorSet)}, - { 6, 22, sizeof(FileDescriptorProto)}, - { 34, 40, sizeof(DescriptorProto_ExtensionRange)}, - { 42, 48, sizeof(DescriptorProto_ReservedRange)}, - { 50, 64, sizeof(DescriptorProto)}, - { 74, 88, sizeof(FieldDescriptorProto)}, - { 98, 104, sizeof(OneofDescriptorProto)}, - { 106, 113, sizeof(EnumDescriptorProto)}, - { 116, 123, sizeof(EnumValueDescriptorProto)}, - { 126, 133, sizeof(ServiceDescriptorProto)}, - { 136, 146, sizeof(MethodDescriptorProto)}, - { 152, 173, sizeof(FileOptions)}, - { 190, 199, sizeof(MessageOptions)}, - { 204, 215, sizeof(FieldOptions)}, - { 222, 227, sizeof(OneofOptions)}, - { 228, 235, sizeof(EnumOptions)}, - { 238, 244, sizeof(EnumValueOptions)}, - { 246, 252, sizeof(ServiceOptions)}, - { 254, 261, sizeof(MethodOptions)}, - { 264, 270, sizeof(UninterpretedOption_NamePart)}, - { 272, 283, sizeof(UninterpretedOption)}, - { 290, 299, sizeof(SourceCodeInfo_Location)}, - { 304, 309, sizeof(SourceCodeInfo)}, - { 310, 318, sizeof(GeneratedCodeInfo_Annotation)}, - { 322, 327, sizeof(GeneratedCodeInfo)}, + { 0, 6, sizeof(FileDescriptorSet)}, + { 7, 24, sizeof(FileDescriptorProto)}, + { 36, 43, sizeof(DescriptorProto_ExtensionRange)}, + { 45, 52, sizeof(DescriptorProto_ReservedRange)}, + { 54, 69, sizeof(DescriptorProto)}, + { 79, 94, sizeof(FieldDescriptorProto)}, + { 104, 111, sizeof(OneofDescriptorProto)}, + { 113, 121, sizeof(EnumDescriptorProto)}, + { 124, 132, sizeof(EnumValueDescriptorProto)}, + { 135, 143, sizeof(ServiceDescriptorProto)}, + { 146, 157, sizeof(MethodDescriptorProto)}, + { 163, 185, sizeof(FileOptions)}, + { 202, 212, sizeof(MessageOptions)}, + { 217, 229, sizeof(FieldOptions)}, + { 236, 242, sizeof(OneofOptions)}, + { 243, 251, sizeof(EnumOptions)}, + { 254, 261, sizeof(EnumValueOptions)}, + { 263, 270, sizeof(ServiceOptions)}, + { 272, 280, sizeof(MethodOptions)}, + { 283, 290, sizeof(UninterpretedOption_NamePart)}, + { 292, 304, sizeof(UninterpretedOption)}, + { 311, 321, sizeof(SourceCodeInfo_Location)}, + { 326, 332, sizeof(SourceCodeInfo)}, + { 333, 342, sizeof(GeneratedCodeInfo_Annotation)}, + { 346, 352, sizeof(GeneratedCodeInfo)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -681,67 +744,67 @@ void AddDescriptorsImpl() { "\001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo" "gle.protobuf.UninterpretedOption\":\n\014Opti" "mizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LI" - "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\354\001\n\016Messag" + "TE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002J\004\010&\020\'\"\362\001\n\016Messag" "eOptions\022&\n\027message_set_wire_format\030\001 \001(" "\010:\005false\022.\n\037no_standard_descriptor_acces" "sor\030\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005fa" "lse\022\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_" "option\030\347\007 \003(\0132$.google.protobuf.Uninterp" - "retedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\t\"\236\003\n\014FieldOp" - "tions\022:\n\005ctype\030\001 \001(\0162#.google.protobuf.F" - "ieldOptions.CType:\006STRING\022\016\n\006packed\030\002 \001(" - "\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobuf.Fiel" - "dOptions.JSType:\tJS_NORMAL\022\023\n\004lazy\030\005 \001(\010" - ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004we" - "ak\030\n \001(\010:\005false\022C\n\024uninterpreted_option\030" - "\347\007 \003(\0132$.google.protobuf.UninterpretedOp" - "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S" - "TRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORMAL\020\000\022\r" - "\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020\200\200\200\200\002J" - "\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninterpreted_o" + "retedOption*\t\010\350\007\020\200\200\200\200\002J\004\010\010\020\tJ\004\010\t\020\n\"\236\003\n\014F" + "ieldOptions\022:\n\005ctype\030\001 \001(\0162#.google.prot" + "obuf.FieldOptions.CType:\006STRING\022\016\n\006packe" + "d\030\002 \001(\010\022\?\n\006jstype\030\006 \001(\0162$.google.protobu" + "f.FieldOptions.JSType:\tJS_NORMAL\022\023\n\004lazy" + "\030\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false" + "\022\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted_o" "ption\030\347\007 \003(\0132$.google.protobuf.Uninterpr" - "etedOption*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n" - "\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005" - "false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g" - "oogle.protobuf.UninterpretedOption*\t\010\350\007\020" - "\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecated\030" - "\001 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 " - "\003(\0132$.google.protobuf.UninterpretedOptio" - "n*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprec" - "ated\030! \001(\010:\005false\022C\n\024uninterpreted_optio" - "n\030\347\007 \003(\0132$.google.protobuf.Uninterpreted" - "Option*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethodOptions\022\031\n\nd" - "eprecated\030! \001(\010:\005false\022_\n\021idempotency_le" - "vel\030\" \001(\0162/.google.protobuf.MethodOption" - "s.IdempotencyLevel:\023IDEMPOTENCY_UNKNOWN\022" - "C\n\024uninterpreted_option\030\347\007 \003(\0132$.google." - "protobuf.UninterpretedOption\"P\n\020Idempote" - "ncyLevel\022\027\n\023IDEMPOTENCY_UNKNOWN\020\000\022\023\n\017NO_" - "SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT\020\002*\t\010\350\007\020\200\200\200\200" - "\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132" - "-.google.protobuf.UninterpretedOption.Na" - "mePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posi" - "tive_int_value\030\004 \001(\004\022\032\n\022negative_int_val" - "ue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string" - "_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n" - "\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exten" - "sion\030\002 \002(\010\"\325\001\n\016SourceCodeInfo\022:\n\010locatio" - "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo" - ".Location\032\206\001\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001" - "\022\020\n\004span\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\031leadi" - "ng_detached_comments\030\006 \003(\t\"\247\001\n\021Generated" - "CodeInfo\022A\n\nannotation\030\001 \003(\0132-.google.pr" - "otobuf.GeneratedCodeInfo.Annotation\032O\n\nA" - "nnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\023\n\013source_fi" - "le\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003end\030\004 \001(\005B\214\001\n" - "\023com.google.protobufB\020DescriptorProtosH\001" - "Z>github.com/golang/protobuf/protoc-gen-" - "go/descriptor;descriptor\242\002\003GPB\252\002\032Google." - "Protobuf.Reflection" + "etedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020" + "\001\022\020\n\014STRING_PIECE\020\002\"5\n\006JSType\022\r\n\tJS_NORM" + "AL\020\000\022\r\n\tJS_STRING\020\001\022\r\n\tJS_NUMBER\020\002*\t\010\350\007\020" + "\200\200\200\200\002J\004\010\004\020\005\"^\n\014OneofOptions\022C\n\024uninterpr" + "eted_option\030\347\007 \003(\0132$.google.protobuf.Uni" + "nterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\223\001\n\013EnumOpti" + "ons\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003" + " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "*\t\010\350\007\020\200\200\200\200\002J\004\010\005\020\006\"}\n\020EnumValueOptions\022\031\n" + "\ndeprecated\030\001 \001(\010:\005false\022C\n\024uninterprete" + "d_option\030\347\007 \003(\0132$.google.protobuf.Uninte" + "rpretedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptio" + "ns\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninter" + "preted_option\030\347\007 \003(\0132$.google.protobuf.U" + "ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\255\002\n\rMethod" + "Options\022\031\n\ndeprecated\030! \001(\010:\005false\022_\n\021id" + "empotency_level\030\" \001(\0162/.google.protobuf." + "MethodOptions.IdempotencyLevel:\023IDEMPOTE" + "NCY_UNKNOWN\022C\n\024uninterpreted_option\030\347\007 \003" + "(\0132$.google.protobuf.UninterpretedOption" + "\"P\n\020IdempotencyLevel\022\027\n\023IDEMPOTENCY_UNKN" + "OWN\020\000\022\023\n\017NO_SIDE_EFFECTS\020\001\022\016\n\nIDEMPOTENT" + "\020\002*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022;\n" + "\004name\030\002 \003(\0132-.google.protobuf.Uninterpre" + "tedOption.NamePart\022\030\n\020identifier_value\030\003" + " \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022nega" + "tive_int_value\030\005 \001(\003\022\024\n\014double_value\030\006 \001" + "(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_va" + "lue\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002(\t" + "\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016SourceCodeInf" + "o\022:\n\010location\030\001 \003(\0132(.google.protobuf.So" + "urceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004pa" + "th\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020leadin" + "g_comments\030\003 \001(\t\022\031\n\021trailing_comments\030\004 " + "\001(\t\022!\n\031leading_detached_comments\030\006 \003(\t\"\247" + "\001\n\021GeneratedCodeInfo\022A\n\nannotation\030\001 \003(\013" + "2-.google.protobuf.GeneratedCodeInfo.Ann" + "otation\032O\n\nAnnotation\022\020\n\004path\030\001 \003(\005B\002\020\001\022" + "\023\n\013source_file\030\002 \001(\t\022\r\n\005begin\030\003 \001(\005\022\013\n\003e" + "nd\030\004 \001(\005B\214\001\n\023com.google.protobufB\020Descri" + "ptorProtosH\001Z>github.com/golang/protobuf" + "/protoc-gen-go/descriptor;descriptor\242\002\003G" + "PB\252\002\032Google.Protobuf.Reflection" }; ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( - descriptor, 5579); + descriptor, 5591); ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( "google/protobuf/descriptor.proto", &protobuf_RegisterTypes); ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); @@ -972,7 +1035,7 @@ void FileDescriptorSet::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FileDescriptorSet& FileDescriptorSet::default_instance() { @@ -1009,13 +1072,11 @@ bool FileDescriptorSet::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(10u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_file())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1044,6 +1105,9 @@ failure: void FileDescriptorSet::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorSet) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.FileDescriptorProto file = 1; for (unsigned int i = 0, n = this->file_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -1059,13 +1123,15 @@ void FileDescriptorSet::SerializeWithCachedSizes( ::google::protobuf::uint8* FileDescriptorSet::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorSet) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.FileDescriptorProto file = 1; for (unsigned int i = 0, n = this->file_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 1, this->file(i), false, target); + 1, this->file(i), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -1122,6 +1188,9 @@ void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorSet) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + file_.MergeFrom(from.file_); } @@ -1149,7 +1218,7 @@ void FileDescriptorSet::Swap(FileDescriptorSet* other) { InternalSwap(other); } void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { - file_.UnsafeArenaSwap(&other->file_); + file_.InternalSwap(&other->file_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -1157,7 +1226,7 @@ void FileDescriptorSet::InternalSwap(FileDescriptorSet* other) { ::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1226,12 +1295,12 @@ FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from) _has_bits_(from._has_bits_), _cached_size_(0), dependency_(from.dependency_), - public_dependency_(from.public_dependency_), - weak_dependency_(from.weak_dependency_), message_type_(from.message_type_), enum_type_(from.enum_type_), service_(from.service_), - extension_(from.extension_) { + extension_(from.extension_), + public_dependency_(from.public_dependency_), + weak_dependency_(from.weak_dependency_) { _internal_metadata_.MergeFrom(from._internal_metadata_); name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (from.has_name()) { @@ -1291,7 +1360,7 @@ void FileDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FileDescriptorProto& FileDescriptorProto::default_instance() { @@ -1310,12 +1379,12 @@ FileDescriptorProto* FileDescriptorProto::New(::google::protobuf::Arena* arena) void FileDescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.FileDescriptorProto) dependency_.Clear(); - public_dependency_.Clear(); - weak_dependency_.Clear(); message_type_.Clear(); enum_type_.Clear(); service_.Clear(); extension_.Clear(); + public_dependency_.Clear(); + weak_dependency_.Clear(); if (_has_bits_[0 / 32] & 31u) { if (has_name()) { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); @@ -1405,13 +1474,11 @@ bool FileDescriptorProto::MergePartialFromCodedStream( case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(34u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_message_type())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1419,13 +1486,11 @@ bool FileDescriptorProto::MergePartialFromCodedStream( case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(42u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enum_type())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1433,13 +1498,11 @@ bool FileDescriptorProto::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(50u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_service())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1447,13 +1510,11 @@ bool FileDescriptorProto::MergePartialFromCodedStream( case 7: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(58u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1558,8 +1619,12 @@ failure: void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FileDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1569,7 +1634,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional string package = 2; - if (has_package()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->package().data(), this->package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1613,13 +1678,13 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions options = 8; - if (has_options()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, *this->options_, output); } // optional .google.protobuf.SourceCodeInfo source_code_info = 9; - if (has_source_code_info()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 9, *this->source_code_info_, output); } @@ -1637,7 +1702,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional string syntax = 12; - if (has_syntax()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->syntax().data(), this->syntax().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1655,10 +1720,13 @@ void FileDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* FileDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1669,7 +1737,7 @@ void FileDescriptorProto::SerializeWithCachedSizes( } // optional string package = 2; - if (has_package()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->package().data(), this->package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1693,58 +1761,54 @@ void FileDescriptorProto::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->message_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 4, this->message_type(i), false, target); + 4, this->message_type(i), deterministic, target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 5; for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 5, this->enum_type(i), false, target); + 5, this->enum_type(i), deterministic, target); } // repeated .google.protobuf.ServiceDescriptorProto service = 6; for (unsigned int i = 0, n = this->service_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 6, this->service(i), false, target); + 6, this->service(i), deterministic, target); } // repeated .google.protobuf.FieldDescriptorProto extension = 7; for (unsigned int i = 0, n = this->extension_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 7, this->extension(i), false, target); + 7, this->extension(i), deterministic, target); } // optional .google.protobuf.FileOptions options = 8; - if (has_options()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 8, *this->options_, false, target); + 8, *this->options_, deterministic, target); } // optional .google.protobuf.SourceCodeInfo source_code_info = 9; - if (has_source_code_info()) { + if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 9, *this->source_code_info_, false, target); + 9, *this->source_code_info_, deterministic, target); } // repeated int32 public_dependency = 10; - for (int i = 0, n = this->public_dependency_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteInt32ToArray(10, this->public_dependency(i), target); - } + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(10, this->public_dependency_, target); // repeated int32 weak_dependency = 11; - for (int i = 0, n = this->weak_dependency_size(); i < n; i++) { - target = ::google::protobuf::internal::WireFormatLite:: - WriteInt32ToArray(11, this->weak_dependency(i), target); - } + target = ::google::protobuf::internal::WireFormatLite:: + WriteInt32ToArray(11, this->weak_dependency_, target); // optional string syntax = 12; - if (has_syntax()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->syntax().data(), this->syntax().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -1779,24 +1843,6 @@ size_t FileDescriptorProto::ByteSizeLong() const { this->dependency(i)); } - // repeated int32 public_dependency = 10; - { - size_t data_size = ::google::protobuf::internal::WireFormatLite:: - Int32Size(this->public_dependency_); - total_size += 1 * - ::google::protobuf::internal::FromIntSize(this->public_dependency_size()); - total_size += data_size; - } - - // repeated int32 weak_dependency = 11; - { - size_t data_size = ::google::protobuf::internal::WireFormatLite:: - Int32Size(this->weak_dependency_); - total_size += 1 * - ::google::protobuf::internal::FromIntSize(this->weak_dependency_size()); - total_size += data_size; - } - // repeated .google.protobuf.DescriptorProto message_type = 4; { unsigned int count = this->message_type_size(); @@ -1841,6 +1887,24 @@ size_t FileDescriptorProto::ByteSizeLong() const { } } + // repeated int32 public_dependency = 10; + { + size_t data_size = ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->public_dependency_); + total_size += 1 * + ::google::protobuf::internal::FromIntSize(this->public_dependency_size()); + total_size += data_size; + } + + // repeated int32 weak_dependency = 11; + { + size_t data_size = ::google::protobuf::internal::WireFormatLite:: + Int32Size(this->weak_dependency_); + total_size += 1 * + ::google::protobuf::internal::FromIntSize(this->weak_dependency_size()); + total_size += data_size; + } + if (_has_bits_[0 / 32] & 31u) { // optional string name = 1; if (has_name()) { @@ -1904,30 +1968,34 @@ void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FileDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + dependency_.MergeFrom(from.dependency_); - public_dependency_.MergeFrom(from.public_dependency_); - weak_dependency_.MergeFrom(from.weak_dependency_); message_type_.MergeFrom(from.message_type_); enum_type_.MergeFrom(from.enum_type_); service_.MergeFrom(from.service_); extension_.MergeFrom(from.extension_); - if (from._has_bits_[0 / 32] & 31u) { - if (from.has_name()) { + public_dependency_.MergeFrom(from.public_dependency_); + weak_dependency_.MergeFrom(from.weak_dependency_); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 31u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_package()) { + if (cached_has_bits & 0x00000002u) { set_has_package(); package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.package_); } - if (from.has_syntax()) { + if (cached_has_bits & 0x00000004u) { set_has_syntax(); syntax_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.syntax_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000008u) { mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options()); } - if (from.has_source_code_info()) { + if (cached_has_bits & 0x00000010u) { mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info()); } } @@ -1963,13 +2031,13 @@ void FileDescriptorProto::Swap(FileDescriptorProto* other) { InternalSwap(other); } void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { - dependency_.UnsafeArenaSwap(&other->dependency_); - public_dependency_.UnsafeArenaSwap(&other->public_dependency_); - weak_dependency_.UnsafeArenaSwap(&other->weak_dependency_); - message_type_.UnsafeArenaSwap(&other->message_type_); - enum_type_.UnsafeArenaSwap(&other->enum_type_); - service_.UnsafeArenaSwap(&other->service_); - extension_.UnsafeArenaSwap(&other->extension_); + dependency_.InternalSwap(&other->dependency_); + message_type_.InternalSwap(&other->message_type_); + enum_type_.InternalSwap(&other->enum_type_); + service_.InternalSwap(&other->service_); + extension_.InternalSwap(&other->extension_); + public_dependency_.InternalSwap(&other->public_dependency_); + weak_dependency_.InternalSwap(&other->weak_dependency_); name_.Swap(&other->name_); package_.Swap(&other->package_); syntax_.Swap(&other->syntax_); @@ -1982,7 +2050,7 @@ void FileDescriptorProto::InternalSwap(FileDescriptorProto* other) { ::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2020,6 +2088,7 @@ void FileDescriptorProto::set_name(::std::string&& value) { } #endif void FileDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name) @@ -2082,6 +2151,7 @@ void FileDescriptorProto::set_package(::std::string&& value) { } #endif void FileDescriptorProto::set_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_package(); package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package) @@ -2138,6 +2208,7 @@ void FileDescriptorProto::set_dependency(int index, ::std::string&& value) { } #endif void FileDescriptorProto::set_dependency(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); dependency_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency) } @@ -2156,11 +2227,12 @@ void FileDescriptorProto::add_dependency(const ::std::string& value) { } #if LANG_CXX11 void FileDescriptorProto::add_dependency(::std::string&& value) { - dependency_.Add()->assign(std::move(value)); + dependency_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency) } #endif void FileDescriptorProto::add_dependency(const char* value) { + GOOGLE_DCHECK(value != NULL); dependency_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency) } @@ -2481,6 +2553,7 @@ void FileDescriptorProto::set_syntax(::std::string&& value) { } #endif void FileDescriptorProto::set_syntax(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_syntax(); syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax) @@ -2561,7 +2634,7 @@ void DescriptorProto_ExtensionRange::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() { @@ -2650,13 +2723,17 @@ failure: void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ExtensionRange) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (has_start()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); } // optional int32 end = 2; - if (has_end()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); } @@ -2669,15 +2746,18 @@ void DescriptorProto_ExtensionRange::SerializeWithCachedSizes( ::google::protobuf::uint8* DescriptorProto_ExtensionRange::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ExtensionRange) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (has_start()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); } // optional int32 end = 2; - if (has_end()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); } @@ -2740,13 +2820,18 @@ void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRa // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ExtensionRange) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_start()) { - set_start(from.start()); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { + start_ = from.start_; } - if (from.has_end()) { - set_end(from.end()); + if (cached_has_bits & 0x00000002u) { + end_ = from.end_; } + _has_bits_[0] |= cached_has_bits; } } @@ -2782,7 +2867,7 @@ void DescriptorProto_ExtensionRange::InternalSwap(DescriptorProto_ExtensionRange ::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2886,7 +2971,7 @@ void DescriptorProto_ReservedRange::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* DescriptorProto_ReservedRange::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[3].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::default_instance() { @@ -2975,13 +3060,17 @@ failure: void DescriptorProto_ReservedRange::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto.ReservedRange) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (has_start()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output); } // optional int32 end = 2; - if (has_end()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output); } @@ -2994,15 +3083,18 @@ void DescriptorProto_ReservedRange::SerializeWithCachedSizes( ::google::protobuf::uint8* DescriptorProto_ReservedRange::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto.ReservedRange) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional int32 start = 1; - if (has_start()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target); } // optional int32 end = 2; - if (has_end()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target); } @@ -3065,13 +3157,18 @@ void DescriptorProto_ReservedRange::MergeFrom(const DescriptorProto_ReservedRang // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto.ReservedRange) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_start()) { - set_start(from.start()); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { + start_ = from.start_; } - if (from.has_end()) { - set_end(from.end()); + if (cached_has_bits & 0x00000002u) { + end_ = from.end_; } + _has_bits_[0] |= cached_has_bits; } } @@ -3107,7 +3204,7 @@ void DescriptorProto_ReservedRange::InternalSwap(DescriptorProto_ReservedRange* ::google::protobuf::Metadata DescriptorProto_ReservedRange::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[3]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -3192,10 +3289,10 @@ DescriptorProto::DescriptorProto(const DescriptorProto& from) _has_bits_(from._has_bits_), _cached_size_(0), field_(from.field_), - extension_(from.extension_), nested_type_(from.nested_type_), enum_type_(from.enum_type_), extension_range_(from.extension_range_), + extension_(from.extension_), oneof_decl_(from.oneof_decl_), reserved_range_(from.reserved_range_), reserved_name_(from.reserved_name_) { @@ -3237,7 +3334,7 @@ void DescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* DescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[4].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const DescriptorProto& DescriptorProto::default_instance() { @@ -3256,10 +3353,10 @@ DescriptorProto* DescriptorProto::New(::google::protobuf::Arena* arena) const { void DescriptorProto::Clear() { // @@protoc_insertion_point(message_clear_start:google.protobuf.DescriptorProto) field_.Clear(); - extension_.Clear(); nested_type_.Clear(); enum_type_.Clear(); extension_range_.Clear(); + extension_.Clear(); oneof_decl_.Clear(); reserved_range_.Clear(); reserved_name_.Clear(); @@ -3307,13 +3404,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_field())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3321,13 +3416,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(26u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_nested_type())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3335,13 +3428,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(34u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enum_type())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3349,13 +3440,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 5: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(42u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension_range())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3363,13 +3452,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 6: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(50u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_extension())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3389,13 +3476,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 8: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(66u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_oneof_decl())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3403,13 +3488,11 @@ bool DescriptorProto::MergePartialFromCodedStream( case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(74u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_reserved_range())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -3455,8 +3538,12 @@ failure: void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.DescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -3496,7 +3583,7 @@ void DescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MessageOptions options = 7; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 7, *this->options_, output); } @@ -3532,10 +3619,13 @@ void DescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* DescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -3549,56 +3639,56 @@ void DescriptorProto::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->field_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->field(i), false, target); + 2, this->field(i), deterministic, target); } // repeated .google.protobuf.DescriptorProto nested_type = 3; for (unsigned int i = 0, n = this->nested_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, this->nested_type(i), false, target); + 3, this->nested_type(i), deterministic, target); } // repeated .google.protobuf.EnumDescriptorProto enum_type = 4; for (unsigned int i = 0, n = this->enum_type_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 4, this->enum_type(i), false, target); + 4, this->enum_type(i), deterministic, target); } // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5; for (unsigned int i = 0, n = this->extension_range_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 5, this->extension_range(i), false, target); + 5, this->extension_range(i), deterministic, target); } // repeated .google.protobuf.FieldDescriptorProto extension = 6; for (unsigned int i = 0, n = this->extension_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 6, this->extension(i), false, target); + 6, this->extension(i), deterministic, target); } // optional .google.protobuf.MessageOptions options = 7; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 7, *this->options_, false, target); + 7, *this->options_, deterministic, target); } // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; for (unsigned int i = 0, n = this->oneof_decl_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 8, this->oneof_decl(i), false, target); + 8, this->oneof_decl(i), deterministic, target); } // repeated .google.protobuf.DescriptorProto.ReservedRange reserved_range = 9; for (unsigned int i = 0, n = this->reserved_range_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 9, this->reserved_range(i), false, target); + 9, this->reserved_range(i), deterministic, target); } // repeated string reserved_name = 10; @@ -3639,17 +3729,6 @@ size_t DescriptorProto::ByteSizeLong() const { } } - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - { - unsigned int count = this->extension_size(); - total_size += 1UL * count; - for (unsigned int i = 0; i < count; i++) { - total_size += - ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( - this->extension(i)); - } - } - // repeated .google.protobuf.DescriptorProto nested_type = 3; { unsigned int count = this->nested_type_size(); @@ -3683,6 +3762,17 @@ size_t DescriptorProto::ByteSizeLong() const { } } + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + { + unsigned int count = this->extension_size(); + total_size += 1UL * count; + for (unsigned int i = 0; i < count; i++) { + total_size += + ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual( + this->extension(i)); + } + } + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; { unsigned int count = this->oneof_decl_size(); @@ -3755,20 +3845,24 @@ void DescriptorProto::MergeFrom(const DescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + field_.MergeFrom(from.field_); - extension_.MergeFrom(from.extension_); nested_type_.MergeFrom(from.nested_type_); enum_type_.MergeFrom(from.enum_type_); extension_range_.MergeFrom(from.extension_range_); + extension_.MergeFrom(from.extension_); oneof_decl_.MergeFrom(from.oneof_decl_); reserved_range_.MergeFrom(from.reserved_range_); reserved_name_.MergeFrom(from.reserved_name_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_name()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000002u) { mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options()); } } @@ -3790,9 +3884,9 @@ void DescriptorProto::CopyFrom(const DescriptorProto& from) { bool DescriptorProto::IsInitialized() const { if (!::google::protobuf::internal::AllAreInitialized(this->field())) return false; - if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->nested_type())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->enum_type())) return false; + if (!::google::protobuf::internal::AllAreInitialized(this->extension())) return false; if (!::google::protobuf::internal::AllAreInitialized(this->oneof_decl())) return false; if (has_options()) { if (!this->options_->IsInitialized()) return false; @@ -3805,14 +3899,14 @@ void DescriptorProto::Swap(DescriptorProto* other) { InternalSwap(other); } void DescriptorProto::InternalSwap(DescriptorProto* other) { - field_.UnsafeArenaSwap(&other->field_); - extension_.UnsafeArenaSwap(&other->extension_); - nested_type_.UnsafeArenaSwap(&other->nested_type_); - enum_type_.UnsafeArenaSwap(&other->enum_type_); - extension_range_.UnsafeArenaSwap(&other->extension_range_); - oneof_decl_.UnsafeArenaSwap(&other->oneof_decl_); - reserved_range_.UnsafeArenaSwap(&other->reserved_range_); - reserved_name_.UnsafeArenaSwap(&other->reserved_name_); + field_.InternalSwap(&other->field_); + nested_type_.InternalSwap(&other->nested_type_); + enum_type_.InternalSwap(&other->enum_type_); + extension_range_.InternalSwap(&other->extension_range_); + extension_.InternalSwap(&other->extension_); + oneof_decl_.InternalSwap(&other->oneof_decl_); + reserved_range_.InternalSwap(&other->reserved_range_); + reserved_name_.InternalSwap(&other->reserved_name_); name_.Swap(&other->name_); std::swap(options_, other->options_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -3822,7 +3916,7 @@ void DescriptorProto::InternalSwap(DescriptorProto* other) { ::google::protobuf::Metadata DescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[4]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -3860,6 +3954,7 @@ void DescriptorProto::set_name(::std::string&& value) { } #endif void DescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name) @@ -4171,6 +4266,7 @@ void DescriptorProto::set_reserved_name(int index, ::std::string&& value) { } #endif void DescriptorProto::set_reserved_name(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); reserved_name_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name) } @@ -4189,11 +4285,12 @@ void DescriptorProto::add_reserved_name(const ::std::string& value) { } #if LANG_CXX11 void DescriptorProto::add_reserved_name(::std::string&& value) { - reserved_name_.Add()->assign(std::move(value)); + reserved_name_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) } #endif void DescriptorProto::add_reserved_name(const char* value) { + GOOGLE_DCHECK(value != NULL); reserved_name_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name) } @@ -4247,14 +4344,14 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) if (from.has_name()) { name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - if (from.has_type_name()) { - type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_); - } extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (from.has_extendee()) { extendee_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.extendee_); } + type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + if (from.has_type_name()) { + type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_); + } default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (from.has_default_value()) { default_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value_); @@ -4277,8 +4374,8 @@ FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from) void FieldDescriptorProto::SharedCtor() { _cached_size_ = 0; name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); extendee_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); default_value_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); json_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); ::memset(&options_, 0, reinterpret_cast(&oneof_index_) - @@ -4294,8 +4391,8 @@ FieldDescriptorProto::~FieldDescriptorProto() { void FieldDescriptorProto::SharedDtor() { name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); - type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); extendee_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); + type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); default_value_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); json_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); if (this != internal_default_instance()) { @@ -4310,7 +4407,7 @@ void FieldDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[5].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FieldDescriptorProto& FieldDescriptorProto::default_instance() { @@ -4333,14 +4430,14 @@ void FieldDescriptorProto::Clear() { GOOGLE_DCHECK(!name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*name_.UnsafeRawStringPointer())->clear(); } - if (has_type_name()) { - GOOGLE_DCHECK(!type_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); - (*type_name_.UnsafeRawStringPointer())->clear(); - } if (has_extendee()) { GOOGLE_DCHECK(!extendee_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*extendee_.UnsafeRawStringPointer())->clear(); } + if (has_type_name()) { + GOOGLE_DCHECK(!type_name_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); + (*type_name_.UnsafeRawStringPointer())->clear(); + } if (has_default_value()) { GOOGLE_DCHECK(!default_value_.IsDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited())); (*default_value_.UnsafeRawStringPointer())->clear(); @@ -4559,8 +4656,12 @@ failure: void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FieldDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4570,7 +4671,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string extendee = 2; - if (has_extendee()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->extendee().data(), this->extendee().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4580,24 +4681,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 3; - if (has_number()) { + if (cached_has_bits & 0x00000040u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (has_label()) { + if (cached_has_bits & 0x00000100u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 4, this->label(), output); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (has_type()) { + if (cached_has_bits & 0x00000200u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 5, this->type(), output); } // optional string type_name = 6; - if (has_type_name()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->type_name().data(), this->type_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4607,7 +4708,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string default_value = 7; - if (has_default_value()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->default_value().data(), this->default_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4617,18 +4718,18 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FieldOptions options = 8; - if (has_options()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 8, *this->options_, output); } // optional int32 oneof_index = 9; - if (has_oneof_index()) { + if (cached_has_bits & 0x00000080u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(9, this->oneof_index(), output); } // optional string json_name = 10; - if (has_json_name()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->json_name().data(), this->json_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4646,10 +4747,13 @@ void FieldDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4660,7 +4764,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string extendee = 2; - if (has_extendee()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->extendee().data(), this->extendee().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4671,24 +4775,24 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 3; - if (has_number()) { + if (cached_has_bits & 0x00000040u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target); } // optional .google.protobuf.FieldDescriptorProto.Label label = 4; - if (has_label()) { + if (cached_has_bits & 0x00000100u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 4, this->label(), target); } // optional .google.protobuf.FieldDescriptorProto.Type type = 5; - if (has_type()) { + if (cached_has_bits & 0x00000200u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 5, this->type(), target); } // optional string type_name = 6; - if (has_type_name()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->type_name().data(), this->type_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4699,7 +4803,7 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional string default_value = 7; - if (has_default_value()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->default_value().data(), this->default_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4710,19 +4814,19 @@ void FieldDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.FieldOptions options = 8; - if (has_options()) { + if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 8, *this->options_, false, target); + 8, *this->options_, deterministic, target); } // optional int32 oneof_index = 9; - if (has_oneof_index()) { + if (cached_has_bits & 0x00000080u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(9, this->oneof_index(), target); } // optional string json_name = 10; - if (has_json_name()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->json_name().data(), this->json_name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -4757,18 +4861,18 @@ size_t FieldDescriptorProto::ByteSizeLong() const { this->name()); } - // optional string type_name = 6; - if (has_type_name()) { + // optional string extendee = 2; + if (has_extendee()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( - this->type_name()); + this->extendee()); } - // optional string extendee = 2; - if (has_extendee()) { + // optional string type_name = 6; + if (has_type_name()) { total_size += 1 + ::google::protobuf::internal::WireFormatLite::StringSize( - this->extendee()); + this->type_name()); } // optional string default_value = 7; @@ -4847,44 +4951,50 @@ void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 255u) { - if (from.has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 255u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_type_name()) { - set_has_type_name(); - type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_); - } - if (from.has_extendee()) { + if (cached_has_bits & 0x00000002u) { set_has_extendee(); extendee_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.extendee_); } - if (from.has_default_value()) { + if (cached_has_bits & 0x00000004u) { + set_has_type_name(); + type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.type_name_); + } + if (cached_has_bits & 0x00000008u) { set_has_default_value(); default_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.default_value_); } - if (from.has_json_name()) { + if (cached_has_bits & 0x00000010u) { set_has_json_name(); json_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.json_name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000020u) { mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options()); } - if (from.has_number()) { - set_number(from.number()); + if (cached_has_bits & 0x00000040u) { + number_ = from.number_; } - if (from.has_oneof_index()) { - set_oneof_index(from.oneof_index()); + if (cached_has_bits & 0x00000080u) { + oneof_index_ = from.oneof_index_; } + _has_bits_[0] |= cached_has_bits; } - if (from._has_bits_[8 / 32] & 768u) { - if (from.has_label()) { - set_label(from.label()); + if (cached_has_bits & 768u) { + if (cached_has_bits & 0x00000100u) { + label_ = from.label_; } - if (from.has_type()) { - set_type(from.type()); + if (cached_has_bits & 0x00000200u) { + type_ = from.type_; } + _has_bits_[0] |= cached_has_bits; } } @@ -4915,8 +5025,8 @@ void FieldDescriptorProto::Swap(FieldDescriptorProto* other) { } void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { name_.Swap(&other->name_); - type_name_.Swap(&other->type_name_); extendee_.Swap(&other->extendee_); + type_name_.Swap(&other->type_name_); default_value_.Swap(&other->default_value_); json_name_.Swap(&other->json_name_); std::swap(options_, other->options_); @@ -4931,7 +5041,7 @@ void FieldDescriptorProto::InternalSwap(FieldDescriptorProto* other) { ::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[5]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -4969,6 +5079,7 @@ void FieldDescriptorProto::set_name(::std::string&& value) { } #endif void FieldDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name) @@ -5075,13 +5186,13 @@ void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorProto_Typ // optional string type_name = 6; bool FieldDescriptorProto::has_type_name() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } void FieldDescriptorProto::set_has_type_name() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000004u; } void FieldDescriptorProto::clear_has_type_name() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000004u; } void FieldDescriptorProto::clear_type_name() { type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -5105,6 +5216,7 @@ void FieldDescriptorProto::set_type_name(::std::string&& value) { } #endif void FieldDescriptorProto::set_type_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_type_name(); type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name) @@ -5137,13 +5249,13 @@ void FieldDescriptorProto::set_allocated_type_name(::std::string* type_name) { // optional string extendee = 2; bool FieldDescriptorProto::has_extendee() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } void FieldDescriptorProto::set_has_extendee() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000002u; } void FieldDescriptorProto::clear_has_extendee() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000002u; } void FieldDescriptorProto::clear_extendee() { extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -5167,6 +5279,7 @@ void FieldDescriptorProto::set_extendee(::std::string&& value) { } #endif void FieldDescriptorProto::set_extendee(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_extendee(); extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee) @@ -5229,6 +5342,7 @@ void FieldDescriptorProto::set_default_value(::std::string&& value) { } #endif void FieldDescriptorProto::set_default_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_default_value(); default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value) @@ -5315,6 +5429,7 @@ void FieldDescriptorProto::set_json_name(::std::string&& value) { } #endif void FieldDescriptorProto::set_json_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_json_name(); json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name) @@ -5450,7 +5565,7 @@ void OneofDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* OneofDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[6].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const OneofDescriptorProto& OneofDescriptorProto::default_instance() { @@ -5545,8 +5660,12 @@ failure: void OneofDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.OneofDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -5556,7 +5675,7 @@ void OneofDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.OneofOptions options = 2; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, *this->options_, output); } @@ -5570,10 +5689,13 @@ void OneofDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* OneofDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -5584,10 +5706,10 @@ void OneofDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.OneofOptions options = 2; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, *this->options_, false, target); + 2, *this->options_, deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -5649,12 +5771,16 @@ void OneofDescriptorProto::MergeFrom(const OneofDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.OneofDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000002u) { mutable_options()->::google::protobuf::OneofOptions::MergeFrom(from.options()); } } @@ -5695,7 +5821,7 @@ void OneofDescriptorProto::InternalSwap(OneofDescriptorProto* other) { ::google::protobuf::Metadata OneofDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[6]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -5733,6 +5859,7 @@ void OneofDescriptorProto::set_name(::std::string&& value) { } #endif void OneofDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name) @@ -5870,7 +5997,7 @@ void EnumDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[7].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const EnumDescriptorProto& EnumDescriptorProto::default_instance() { @@ -5933,13 +6060,11 @@ bool EnumDescriptorProto::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_value())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -5980,8 +6105,12 @@ failure: void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.EnumDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -5997,7 +6126,7 @@ void EnumDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.EnumOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, *this->options_, output); } @@ -6011,10 +6140,13 @@ void EnumDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -6028,14 +6160,14 @@ void EnumDescriptorProto::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->value_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->value(i), false, target); + 2, this->value(i), deterministic, target); } // optional .google.protobuf.EnumOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, *this->options_, false, target); + 3, *this->options_, deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -6108,13 +6240,17 @@ void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + value_.MergeFrom(from.value_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_name()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000002u) { mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options()); } } @@ -6147,7 +6283,7 @@ void EnumDescriptorProto::Swap(EnumDescriptorProto* other) { InternalSwap(other); } void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { - value_.UnsafeArenaSwap(&other->value_); + value_.InternalSwap(&other->value_); name_.Swap(&other->name_); std::swap(options_, other->options_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -6157,7 +6293,7 @@ void EnumDescriptorProto::InternalSwap(EnumDescriptorProto* other) { ::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[7]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -6195,6 +6331,7 @@ void EnumDescriptorProto::set_name(::std::string&& value) { } #endif void EnumDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name) @@ -6363,7 +6500,7 @@ void EnumValueDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[8].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() { @@ -6473,8 +6610,12 @@ failure: void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -6484,12 +6625,12 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 2; - if (has_number()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output); } // optional .google.protobuf.EnumValueOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, *this->options_, output); } @@ -6503,10 +6644,13 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumValueDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -6517,15 +6661,15 @@ void EnumValueDescriptorProto::SerializeWithCachedSizes( } // optional int32 number = 2; - if (has_number()) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target); } // optional .google.protobuf.EnumValueOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, *this->options_, false, target); + 3, *this->options_, deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -6594,17 +6738,22 @@ void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValueDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 7u) { - if (from.has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000002u) { mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options()); } - if (from.has_number()) { - set_number(from.number()); + if (cached_has_bits & 0x00000004u) { + number_ = from.number_; } + _has_bits_[0] |= cached_has_bits; } } @@ -6644,7 +6793,7 @@ void EnumValueDescriptorProto::InternalSwap(EnumValueDescriptorProto* other) { ::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[8]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -6682,6 +6831,7 @@ void EnumValueDescriptorProto::set_name(::std::string&& value) { } #endif void EnumValueDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name) @@ -6843,7 +6993,7 @@ void ServiceDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[9].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() { @@ -6906,13 +7056,11 @@ bool ServiceDescriptorProto::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_method())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -6953,8 +7101,12 @@ failure: void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -6970,7 +7122,7 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.ServiceOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 3, *this->options_, output); } @@ -6984,10 +7136,13 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* ServiceDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7001,14 +7156,14 @@ void ServiceDescriptorProto::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->method_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->method(i), false, target); + 2, this->method(i), deterministic, target); } // optional .google.protobuf.ServiceOptions options = 3; - if (has_options()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, *this->options_, false, target); + 3, *this->options_, deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -7081,13 +7236,17 @@ void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ServiceDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + method_.MergeFrom(from.method_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_name()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000002u) { mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options()); } } @@ -7120,7 +7279,7 @@ void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) { InternalSwap(other); } void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { - method_.UnsafeArenaSwap(&other->method_); + method_.InternalSwap(&other->method_); name_.Swap(&other->name_); std::swap(options_, other->options_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -7130,7 +7289,7 @@ void ServiceDescriptorProto::InternalSwap(ServiceDescriptorProto* other) { ::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[9]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -7168,6 +7327,7 @@ void ServiceDescriptorProto::set_name(::std::string&& value) { } #endif void ServiceDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name) @@ -7353,7 +7513,7 @@ void MethodDescriptorProto::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[10].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const MethodDescriptorProto& MethodDescriptorProto::default_instance() { @@ -7520,8 +7680,12 @@ failure: void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.MethodDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7531,7 +7695,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string input_type = 2; - if (has_input_type()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->input_type().data(), this->input_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7541,7 +7705,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string output_type = 3; - if (has_output_type()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->output_type().data(), this->output_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7551,18 +7715,18 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MethodOptions options = 4; - if (has_options()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 4, *this->options_, output); } // optional bool client_streaming = 5 [default = false]; - if (has_client_streaming()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->client_streaming(), output); } // optional bool server_streaming = 6 [default = false]; - if (has_server_streaming()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormatLite::WriteBool(6, this->server_streaming(), output); } @@ -7575,10 +7739,13 @@ void MethodDescriptorProto::SerializeWithCachedSizes( ::google::protobuf::uint8* MethodDescriptorProto::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodDescriptorProto) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string name = 1; - if (has_name()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name().data(), this->name().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7589,7 +7756,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string input_type = 2; - if (has_input_type()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->input_type().data(), this->input_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7600,7 +7767,7 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional string output_type = 3; - if (has_output_type()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->output_type().data(), this->output_type().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -7611,19 +7778,19 @@ void MethodDescriptorProto::SerializeWithCachedSizes( } // optional .google.protobuf.MethodOptions options = 4; - if (has_options()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 4, *this->options_, false, target); + 4, *this->options_, deterministic, target); } // optional bool client_streaming = 5 [default = false]; - if (has_client_streaming()) { + if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->client_streaming(), target); } // optional bool server_streaming = 6 [default = false]; - if (has_server_streaming()) { + if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(6, this->server_streaming(), target); } @@ -7710,28 +7877,33 @@ void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.MethodDescriptorProto) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 63u) { - if (from.has_name()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 63u) { + if (cached_has_bits & 0x00000001u) { set_has_name(); name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_); } - if (from.has_input_type()) { + if (cached_has_bits & 0x00000002u) { set_has_input_type(); input_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.input_type_); } - if (from.has_output_type()) { + if (cached_has_bits & 0x00000004u) { set_has_output_type(); output_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.output_type_); } - if (from.has_options()) { + if (cached_has_bits & 0x00000008u) { mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options()); } - if (from.has_client_streaming()) { - set_client_streaming(from.client_streaming()); + if (cached_has_bits & 0x00000010u) { + client_streaming_ = from.client_streaming_; } - if (from.has_server_streaming()) { - set_server_streaming(from.server_streaming()); + if (cached_has_bits & 0x00000020u) { + server_streaming_ = from.server_streaming_; } + _has_bits_[0] |= cached_has_bits; } } @@ -7774,7 +7946,7 @@ void MethodDescriptorProto::InternalSwap(MethodDescriptorProto* other) { ::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[10]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -7812,6 +7984,7 @@ void MethodDescriptorProto::set_name(::std::string&& value) { } #endif void MethodDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name) @@ -7874,6 +8047,7 @@ void MethodDescriptorProto::set_input_type(::std::string&& value) { } #endif void MethodDescriptorProto::set_input_type(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_input_type(); input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type) @@ -7936,6 +8110,7 @@ void MethodDescriptorProto::set_output_type(::std::string&& value) { } #endif void MethodDescriptorProto::set_output_type(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_output_type(); output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type) @@ -8169,7 +8344,7 @@ void FileOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FileOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[11].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FileOptions& FileOptions::default_instance() { @@ -8486,13 +8661,11 @@ bool FileOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -8526,8 +8699,12 @@ failure: void FileOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FileOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string java_package = 1; - if (has_java_package()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->java_package().data(), this->java_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8537,7 +8714,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string java_outer_classname = 8; - if (has_java_outer_classname()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->java_outer_classname().data(), this->java_outer_classname().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8547,18 +8724,18 @@ void FileOptions::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (has_optimize_for()) { + if (cached_has_bits & 0x00008000u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 9, this->optimize_for(), output); } // optional bool java_multiple_files = 10 [default = false]; - if (has_java_multiple_files()) { + if (cached_has_bits & 0x00000080u) { ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output); } // optional string go_package = 11; - if (has_go_package()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->go_package().data(), this->go_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8568,42 +8745,42 @@ void FileOptions::SerializeWithCachedSizes( } // optional bool cc_generic_services = 16 [default = false]; - if (has_cc_generic_services()) { + if (cached_has_bits & 0x00000400u) { ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output); } // optional bool java_generic_services = 17 [default = false]; - if (has_java_generic_services()) { + if (cached_has_bits & 0x00000800u) { ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output); } // optional bool py_generic_services = 18 [default = false]; - if (has_py_generic_services()) { + if (cached_has_bits & 0x00001000u) { ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output); } // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; - if (has_java_generate_equals_and_hash()) { + if (cached_has_bits & 0x00000100u) { ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output); } // optional bool deprecated = 23 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00002000u) { ::google::protobuf::internal::WireFormatLite::WriteBool(23, this->deprecated(), output); } // optional bool java_string_check_utf8 = 27 [default = false]; - if (has_java_string_check_utf8()) { + if (cached_has_bits & 0x00000200u) { ::google::protobuf::internal::WireFormatLite::WriteBool(27, this->java_string_check_utf8(), output); } // optional bool cc_enable_arenas = 31 [default = false]; - if (has_cc_enable_arenas()) { + if (cached_has_bits & 0x00004000u) { ::google::protobuf::internal::WireFormatLite::WriteBool(31, this->cc_enable_arenas(), output); } // optional string objc_class_prefix = 36; - if (has_objc_class_prefix()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->objc_class_prefix().data(), this->objc_class_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8613,7 +8790,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string csharp_namespace = 37; - if (has_csharp_namespace()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->csharp_namespace().data(), this->csharp_namespace().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8623,7 +8800,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string swift_prefix = 39; - if (has_swift_prefix()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->swift_prefix().data(), this->swift_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8633,7 +8810,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string php_class_prefix = 40; - if (has_php_class_prefix()) { + if (cached_has_bits & 0x00000040u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->php_class_prefix().data(), this->php_class_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8661,10 +8838,13 @@ void FileOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* FileOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FileOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional string java_package = 1; - if (has_java_package()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->java_package().data(), this->java_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8675,7 +8855,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string java_outer_classname = 8; - if (has_java_outer_classname()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->java_outer_classname().data(), this->java_outer_classname().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8686,18 +8866,18 @@ void FileOptions::SerializeWithCachedSizes( } // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED]; - if (has_optimize_for()) { + if (cached_has_bits & 0x00008000u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 9, this->optimize_for(), target); } // optional bool java_multiple_files = 10 [default = false]; - if (has_java_multiple_files()) { + if (cached_has_bits & 0x00000080u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target); } // optional string go_package = 11; - if (has_go_package()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->go_package().data(), this->go_package().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8708,42 +8888,42 @@ void FileOptions::SerializeWithCachedSizes( } // optional bool cc_generic_services = 16 [default = false]; - if (has_cc_generic_services()) { + if (cached_has_bits & 0x00000400u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target); } // optional bool java_generic_services = 17 [default = false]; - if (has_java_generic_services()) { + if (cached_has_bits & 0x00000800u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target); } // optional bool py_generic_services = 18 [default = false]; - if (has_py_generic_services()) { + if (cached_has_bits & 0x00001000u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target); } // optional bool java_generate_equals_and_hash = 20 [deprecated = true]; - if (has_java_generate_equals_and_hash()) { + if (cached_has_bits & 0x00000100u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target); } // optional bool deprecated = 23 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00002000u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(23, this->deprecated(), target); } // optional bool java_string_check_utf8 = 27 [default = false]; - if (has_java_string_check_utf8()) { + if (cached_has_bits & 0x00000200u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(27, this->java_string_check_utf8(), target); } // optional bool cc_enable_arenas = 31 [default = false]; - if (has_cc_enable_arenas()) { + if (cached_has_bits & 0x00004000u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(31, this->cc_enable_arenas(), target); } // optional string objc_class_prefix = 36; - if (has_objc_class_prefix()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->objc_class_prefix().data(), this->objc_class_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8754,7 +8934,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string csharp_namespace = 37; - if (has_csharp_namespace()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->csharp_namespace().data(), this->csharp_namespace().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8765,7 +8945,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string swift_prefix = 39; - if (has_swift_prefix()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->swift_prefix().data(), this->swift_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8776,7 +8956,7 @@ void FileOptions::SerializeWithCachedSizes( } // optional string php_class_prefix = 40; - if (has_php_class_prefix()) { + if (cached_has_bits & 0x00000040u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->php_class_prefix().data(), this->php_class_prefix().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -8790,7 +8970,7 @@ void FileOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -8953,65 +9133,71 @@ void FileOptions::MergeFrom(const FileOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & 255u) { - if (from.has_java_package()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 255u) { + if (cached_has_bits & 0x00000001u) { set_has_java_package(); java_package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_package_); } - if (from.has_java_outer_classname()) { + if (cached_has_bits & 0x00000002u) { set_has_java_outer_classname(); java_outer_classname_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.java_outer_classname_); } - if (from.has_go_package()) { + if (cached_has_bits & 0x00000004u) { set_has_go_package(); go_package_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.go_package_); } - if (from.has_objc_class_prefix()) { + if (cached_has_bits & 0x00000008u) { set_has_objc_class_prefix(); objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_); } - if (from.has_csharp_namespace()) { + if (cached_has_bits & 0x00000010u) { set_has_csharp_namespace(); csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_); } - if (from.has_swift_prefix()) { + if (cached_has_bits & 0x00000020u) { set_has_swift_prefix(); swift_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.swift_prefix_); } - if (from.has_php_class_prefix()) { + if (cached_has_bits & 0x00000040u) { set_has_php_class_prefix(); php_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.php_class_prefix_); } - if (from.has_java_multiple_files()) { - set_java_multiple_files(from.java_multiple_files()); + if (cached_has_bits & 0x00000080u) { + java_multiple_files_ = from.java_multiple_files_; } + _has_bits_[0] |= cached_has_bits; } - if (from._has_bits_[8 / 32] & 65280u) { - if (from.has_java_generate_equals_and_hash()) { - set_java_generate_equals_and_hash(from.java_generate_equals_and_hash()); + if (cached_has_bits & 65280u) { + if (cached_has_bits & 0x00000100u) { + java_generate_equals_and_hash_ = from.java_generate_equals_and_hash_; } - if (from.has_java_string_check_utf8()) { - set_java_string_check_utf8(from.java_string_check_utf8()); + if (cached_has_bits & 0x00000200u) { + java_string_check_utf8_ = from.java_string_check_utf8_; } - if (from.has_cc_generic_services()) { - set_cc_generic_services(from.cc_generic_services()); + if (cached_has_bits & 0x00000400u) { + cc_generic_services_ = from.cc_generic_services_; } - if (from.has_java_generic_services()) { - set_java_generic_services(from.java_generic_services()); + if (cached_has_bits & 0x00000800u) { + java_generic_services_ = from.java_generic_services_; } - if (from.has_py_generic_services()) { - set_py_generic_services(from.py_generic_services()); + if (cached_has_bits & 0x00001000u) { + py_generic_services_ = from.py_generic_services_; } - if (from.has_deprecated()) { - set_deprecated(from.deprecated()); + if (cached_has_bits & 0x00002000u) { + deprecated_ = from.deprecated_; } - if (from.has_cc_enable_arenas()) { - set_cc_enable_arenas(from.cc_enable_arenas()); + if (cached_has_bits & 0x00004000u) { + cc_enable_arenas_ = from.cc_enable_arenas_; } - if (from.has_optimize_for()) { - set_optimize_for(from.optimize_for()); + if (cached_has_bits & 0x00008000u) { + optimize_for_ = from.optimize_for_; } + _has_bits_[0] |= cached_has_bits; } } @@ -9043,7 +9229,7 @@ void FileOptions::Swap(FileOptions* other) { InternalSwap(other); } void FileOptions::InternalSwap(FileOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); java_package_.Swap(&other->java_package_); java_outer_classname_.Swap(&other->java_outer_classname_); go_package_.Swap(&other->go_package_); @@ -9068,7 +9254,7 @@ void FileOptions::InternalSwap(FileOptions* other) { ::google::protobuf::Metadata FileOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[11]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -9106,6 +9292,7 @@ void FileOptions::set_java_package(::std::string&& value) { } #endif void FileOptions::set_java_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_java_package(); java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package) @@ -9168,6 +9355,7 @@ void FileOptions::set_java_outer_classname(::std::string&& value) { } #endif void FileOptions::set_java_outer_classname(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_java_outer_classname(); java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname) @@ -9327,6 +9515,7 @@ void FileOptions::set_go_package(::std::string&& value) { } #endif void FileOptions::set_go_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_go_package(); go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package) @@ -9509,6 +9698,7 @@ void FileOptions::set_objc_class_prefix(::std::string&& value) { } #endif void FileOptions::set_objc_class_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_objc_class_prefix(); objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix) @@ -9571,6 +9761,7 @@ void FileOptions::set_csharp_namespace(::std::string&& value) { } #endif void FileOptions::set_csharp_namespace(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_csharp_namespace(); csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) @@ -9633,6 +9824,7 @@ void FileOptions::set_swift_prefix(::std::string&& value) { } #endif void FileOptions::set_swift_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_swift_prefix(); swift_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix) @@ -9695,6 +9887,7 @@ void FileOptions::set_php_class_prefix(::std::string&& value) { } #endif void FileOptions::set_php_class_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_php_class_prefix(); php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) @@ -9810,7 +10003,7 @@ void MessageOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* MessageOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[12].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const MessageOptions& MessageOptions::default_instance() { @@ -9908,13 +10101,11 @@ bool MessageOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -9948,23 +10139,27 @@ failure: void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.MessageOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool message_set_wire_format = 1 [default = false]; - if (has_message_set_wire_format()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output); } // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (has_no_standard_descriptor_accessor()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); } // optional bool map_entry = 7; - if (has_map_entry()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteBool(7, this->map_entry(), output); } @@ -9987,25 +10182,28 @@ void MessageOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* MessageOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MessageOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool message_set_wire_format = 1 [default = false]; - if (has_message_set_wire_format()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target); } // optional bool no_standard_descriptor_accessor = 2 [default = false]; - if (has_no_standard_descriptor_accessor()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); } // optional bool map_entry = 7; - if (has_map_entry()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(7, this->map_entry(), target); } @@ -10013,7 +10211,7 @@ void MessageOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -10099,20 +10297,25 @@ void MessageOptions::MergeFrom(const MessageOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & 15u) { - if (from.has_message_set_wire_format()) { - set_message_set_wire_format(from.message_set_wire_format()); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 15u) { + if (cached_has_bits & 0x00000001u) { + message_set_wire_format_ = from.message_set_wire_format_; } - if (from.has_no_standard_descriptor_accessor()) { - set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor()); + if (cached_has_bits & 0x00000002u) { + no_standard_descriptor_accessor_ = from.no_standard_descriptor_accessor_; } - if (from.has_deprecated()) { - set_deprecated(from.deprecated()); + if (cached_has_bits & 0x00000004u) { + deprecated_ = from.deprecated_; } - if (from.has_map_entry()) { - set_map_entry(from.map_entry()); + if (cached_has_bits & 0x00000008u) { + map_entry_ = from.map_entry_; } + _has_bits_[0] |= cached_has_bits; } } @@ -10144,7 +10347,7 @@ void MessageOptions::Swap(MessageOptions* other) { InternalSwap(other); } void MessageOptions::InternalSwap(MessageOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(message_set_wire_format_, other->message_set_wire_format_); std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_); std::swap(deprecated_, other->deprecated_); @@ -10157,7 +10360,7 @@ void MessageOptions::InternalSwap(MessageOptions* other) { ::google::protobuf::Metadata MessageOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[12]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -10320,15 +10523,15 @@ FieldOptions::FieldOptions(const FieldOptions& from) _internal_metadata_.MergeFrom(from._internal_metadata_); _extensions_.MergeFrom(from._extensions_); ::memcpy(&ctype_, &from.ctype_, - reinterpret_cast(&weak_) - - reinterpret_cast(&ctype_) + sizeof(weak_)); + reinterpret_cast(&jstype_) - + reinterpret_cast(&ctype_) + sizeof(jstype_)); // @@protoc_insertion_point(copy_constructor:google.protobuf.FieldOptions) } void FieldOptions::SharedCtor() { _cached_size_ = 0; - ::memset(&ctype_, 0, reinterpret_cast(&weak_) - - reinterpret_cast(&ctype_) + sizeof(weak_)); + ::memset(&ctype_, 0, reinterpret_cast(&jstype_) - + reinterpret_cast(&ctype_) + sizeof(jstype_)); } FieldOptions::~FieldOptions() { @@ -10346,7 +10549,7 @@ void FieldOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FieldOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[13].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FieldOptions& FieldOptions::default_instance() { @@ -10367,8 +10570,8 @@ void FieldOptions::Clear() { _extensions_.Clear(); uninterpreted_option_.Clear(); if (_has_bits_[0 / 32] & 63u) { - ::memset(&ctype_, 0, reinterpret_cast(&weak_) - - reinterpret_cast(&ctype_) + sizeof(weak_)); + ::memset(&ctype_, 0, reinterpret_cast(&jstype_) - + reinterpret_cast(&ctype_) + sizeof(jstype_)); } _has_bits_.Clear(); _internal_metadata_.Clear(); @@ -10482,13 +10685,11 @@ bool FieldOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -10522,35 +10723,39 @@ failure: void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FieldOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (has_ctype()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 1, this->ctype(), output); } // optional bool packed = 2; - if (has_packed()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); } // optional bool lazy = 5 [default = false]; - if (has_lazy()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output); } // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; - if (has_jstype()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 6, this->jstype(), output); } // optional bool weak = 10 [default = false]; - if (has_weak()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output); } @@ -10573,37 +10778,40 @@ void FieldOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING]; - if (has_ctype()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 1, this->ctype(), target); } // optional bool packed = 2; - if (has_packed()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); } // optional bool lazy = 5 [default = false]; - if (has_lazy()) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target); } // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; - if (has_jstype()) { + if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 6, this->jstype(), target); } // optional bool weak = 10 [default = false]; - if (has_weak()) { + if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target); } @@ -10611,7 +10819,7 @@ void FieldOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -10655,12 +10863,6 @@ size_t FieldOptions::ByteSizeLong() const { ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype()); } - // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; - if (has_jstype()) { - total_size += 1 + - ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype()); - } - // optional bool packed = 2; if (has_packed()) { total_size += 1 + 1; @@ -10681,6 +10883,12 @@ size_t FieldOptions::ByteSizeLong() const { total_size += 1 + 1; } + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + if (has_jstype()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::EnumSize(this->jstype()); + } + } int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); @@ -10709,26 +10917,31 @@ void FieldOptions::MergeFrom(const FieldOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & 63u) { - if (from.has_ctype()) { - set_ctype(from.ctype()); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 63u) { + if (cached_has_bits & 0x00000001u) { + ctype_ = from.ctype_; } - if (from.has_jstype()) { - set_jstype(from.jstype()); + if (cached_has_bits & 0x00000002u) { + packed_ = from.packed_; } - if (from.has_packed()) { - set_packed(from.packed()); + if (cached_has_bits & 0x00000004u) { + lazy_ = from.lazy_; } - if (from.has_lazy()) { - set_lazy(from.lazy()); + if (cached_has_bits & 0x00000008u) { + deprecated_ = from.deprecated_; } - if (from.has_deprecated()) { - set_deprecated(from.deprecated()); + if (cached_has_bits & 0x00000010u) { + weak_ = from.weak_; } - if (from.has_weak()) { - set_weak(from.weak()); + if (cached_has_bits & 0x00000020u) { + jstype_ = from.jstype_; } + _has_bits_[0] |= cached_has_bits; } } @@ -10760,13 +10973,13 @@ void FieldOptions::Swap(FieldOptions* other) { InternalSwap(other); } void FieldOptions::InternalSwap(FieldOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(ctype_, other->ctype_); - std::swap(jstype_, other->jstype_); std::swap(packed_, other->packed_); std::swap(lazy_, other->lazy_); std::swap(deprecated_, other->deprecated_); std::swap(weak_, other->weak_); + std::swap(jstype_, other->jstype_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -10775,7 +10988,7 @@ void FieldOptions::InternalSwap(FieldOptions* other) { ::google::protobuf::Metadata FieldOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[13]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -10808,13 +11021,13 @@ void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value) { // optional bool packed = 2; bool FieldOptions::has_packed() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } void FieldOptions::set_has_packed() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000002u; } void FieldOptions::clear_has_packed() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000002u; } void FieldOptions::clear_packed() { packed_ = false; @@ -10832,13 +11045,13 @@ void FieldOptions::set_packed(bool value) { // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; bool FieldOptions::has_jstype() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000020u) != 0; } void FieldOptions::set_has_jstype() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000020u; } void FieldOptions::clear_has_jstype() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000020u; } void FieldOptions::clear_jstype() { jstype_ = 0; @@ -10857,13 +11070,13 @@ void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType value) { // optional bool lazy = 5 [default = false]; bool FieldOptions::has_lazy() const { - return (_has_bits_[0] & 0x00000008u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } void FieldOptions::set_has_lazy() { - _has_bits_[0] |= 0x00000008u; + _has_bits_[0] |= 0x00000004u; } void FieldOptions::clear_has_lazy() { - _has_bits_[0] &= ~0x00000008u; + _has_bits_[0] &= ~0x00000004u; } void FieldOptions::clear_lazy() { lazy_ = false; @@ -10881,13 +11094,13 @@ void FieldOptions::set_lazy(bool value) { // optional bool deprecated = 3 [default = false]; bool FieldOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } void FieldOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000008u; } void FieldOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000008u; } void FieldOptions::clear_deprecated() { deprecated_ = false; @@ -10905,13 +11118,13 @@ void FieldOptions::set_deprecated(bool value) { // optional bool weak = 10 [default = false]; bool FieldOptions::has_weak() const { - return (_has_bits_[0] & 0x00000020u) != 0; + return (_has_bits_[0] & 0x00000010u) != 0; } void FieldOptions::set_has_weak() { - _has_bits_[0] |= 0x00000020u; + _has_bits_[0] |= 0x00000010u; } void FieldOptions::clear_has_weak() { - _has_bits_[0] &= ~0x00000020u; + _has_bits_[0] &= ~0x00000010u; } void FieldOptions::clear_weak() { weak_ = false; @@ -11003,7 +11216,7 @@ void OneofOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* OneofOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[14].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const OneofOptions& OneofOptions::default_instance() { @@ -11041,13 +11254,11 @@ bool OneofOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -11081,6 +11292,9 @@ failure: void OneofOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.OneofOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -11100,13 +11314,15 @@ void OneofOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* OneofOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.OneofOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999; for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -11170,6 +11386,9 @@ void OneofOptions::MergeFrom(const OneofOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); } @@ -11201,7 +11420,7 @@ void OneofOptions::Swap(OneofOptions* other) { InternalSwap(other); } void OneofOptions::InternalSwap(OneofOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -11210,7 +11429,7 @@ void OneofOptions::InternalSwap(OneofOptions* other) { ::google::protobuf::Metadata OneofOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[14]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -11299,7 +11518,7 @@ void EnumOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* EnumOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[15].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const EnumOptions& EnumOptions::default_instance() { @@ -11369,13 +11588,11 @@ bool EnumOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -11409,13 +11626,17 @@ failure: void EnumOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.EnumOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool allow_alias = 2; - if (has_allow_alias()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output); } @@ -11438,15 +11659,18 @@ void EnumOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool allow_alias = 2; - if (has_allow_alias()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target); } // optional bool deprecated = 3 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target); } @@ -11454,7 +11678,7 @@ void EnumOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -11530,14 +11754,19 @@ void EnumOptions::MergeFrom(const EnumOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_allow_alias()) { - set_allow_alias(from.allow_alias()); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { + allow_alias_ = from.allow_alias_; } - if (from.has_deprecated()) { - set_deprecated(from.deprecated()); + if (cached_has_bits & 0x00000002u) { + deprecated_ = from.deprecated_; } + _has_bits_[0] |= cached_has_bits; } } @@ -11569,7 +11798,7 @@ void EnumOptions::Swap(EnumOptions* other) { InternalSwap(other); } void EnumOptions::InternalSwap(EnumOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(allow_alias_, other->allow_alias_); std::swap(deprecated_, other->deprecated_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -11580,7 +11809,7 @@ void EnumOptions::InternalSwap(EnumOptions* other) { ::google::protobuf::Metadata EnumOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[15]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -11713,7 +11942,7 @@ void EnumValueOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[16].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const EnumValueOptions& EnumValueOptions::default_instance() { @@ -11766,13 +11995,11 @@ bool EnumValueOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -11806,8 +12033,12 @@ failure: void EnumValueOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValueOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 1 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->deprecated(), output); } @@ -11830,10 +12061,13 @@ void EnumValueOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumValueOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValueOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 1 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->deprecated(), target); } @@ -11841,7 +12075,7 @@ void EnumValueOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -11910,6 +12144,9 @@ void EnumValueOptions::MergeFrom(const EnumValueOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); if (from.has_deprecated()) { set_deprecated(from.deprecated()); @@ -11944,7 +12181,7 @@ void EnumValueOptions::Swap(EnumValueOptions* other) { InternalSwap(other); } void EnumValueOptions::InternalSwap(EnumValueOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(deprecated_, other->deprecated_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); @@ -11954,7 +12191,7 @@ void EnumValueOptions::InternalSwap(EnumValueOptions* other) { ::google::protobuf::Metadata EnumValueOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[16]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -12063,7 +12300,7 @@ void ServiceOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* ServiceOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[17].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const ServiceOptions& ServiceOptions::default_instance() { @@ -12116,13 +12353,11 @@ bool ServiceOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -12156,8 +12391,12 @@ failure: void ServiceOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.ServiceOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 33 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output); } @@ -12180,10 +12419,13 @@ void ServiceOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* ServiceOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ServiceOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 33 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target); } @@ -12191,7 +12433,7 @@ void ServiceOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -12260,6 +12502,9 @@ void ServiceOptions::MergeFrom(const ServiceOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); if (from.has_deprecated()) { set_deprecated(from.deprecated()); @@ -12294,7 +12539,7 @@ void ServiceOptions::Swap(ServiceOptions* other) { InternalSwap(other); } void ServiceOptions::InternalSwap(ServiceOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(deprecated_, other->deprecated_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); @@ -12304,7 +12549,7 @@ void ServiceOptions::InternalSwap(ServiceOptions* other) { ::google::protobuf::Metadata ServiceOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[17]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -12417,7 +12662,7 @@ void MethodOptions::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* MethodOptions::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[18].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const MethodOptions& MethodOptions::default_instance() { @@ -12492,13 +12737,11 @@ bool MethodOptions::MergePartialFromCodedStream( case 999: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(7994u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_uninterpreted_option())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -12532,13 +12775,17 @@ failure: void MethodOptions::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.MethodOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 33 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormatLite::WriteBool(33, this->deprecated(), output); } // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; - if (has_idempotency_level()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteEnum( 34, this->idempotency_level(), output); } @@ -12562,15 +12809,18 @@ void MethodOptions::SerializeWithCachedSizes( ::google::protobuf::uint8* MethodOptions::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.MethodOptions) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // optional bool deprecated = 33 [default = false]; - if (has_deprecated()) { + if (cached_has_bits & 0x00000001u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(33, this->deprecated(), target); } // optional .google.protobuf.MethodOptions.IdempotencyLevel idempotency_level = 34 [default = IDEMPOTENCY_UNKNOWN]; - if (has_idempotency_level()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( 34, this->idempotency_level(), target); } @@ -12579,7 +12829,7 @@ void MethodOptions::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 999, this->uninterpreted_option(i), false, target); + 999, this->uninterpreted_option(i), deterministic, target); } // Extension range [1000, 536870912) @@ -12656,14 +12906,19 @@ void MethodOptions::MergeFrom(const MethodOptions& from) { GOOGLE_DCHECK_NE(&from, this); _extensions_.MergeFrom(from._extensions_); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + uninterpreted_option_.MergeFrom(from.uninterpreted_option_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_deprecated()) { - set_deprecated(from.deprecated()); + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { + deprecated_ = from.deprecated_; } - if (from.has_idempotency_level()) { - set_idempotency_level(from.idempotency_level()); + if (cached_has_bits & 0x00000002u) { + idempotency_level_ = from.idempotency_level_; } + _has_bits_[0] |= cached_has_bits; } } @@ -12695,7 +12950,7 @@ void MethodOptions::Swap(MethodOptions* other) { InternalSwap(other); } void MethodOptions::InternalSwap(MethodOptions* other) { - uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_); + uninterpreted_option_.InternalSwap(&other->uninterpreted_option_); std::swap(deprecated_, other->deprecated_); std::swap(idempotency_level_, other->idempotency_level_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -12706,7 +12961,7 @@ void MethodOptions::InternalSwap(MethodOptions* other) { ::google::protobuf::Metadata MethodOptions::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[18]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -12844,7 +13099,7 @@ void UninterpretedOption_NamePart::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[19].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() { @@ -12936,8 +13191,12 @@ failure: void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption.NamePart) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // required string name_part = 1; - if (has_name_part()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name_part().data(), this->name_part().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -12947,7 +13206,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( } // required bool is_extension = 2; - if (has_is_extension()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output); } @@ -12960,10 +13219,13 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( ::google::protobuf::uint8* UninterpretedOption_NamePart::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption.NamePart) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = _has_bits_[0]; // required string name_part = 1; - if (has_name_part()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->name_part().data(), this->name_part().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -12974,7 +13236,7 @@ void UninterpretedOption_NamePart::SerializeWithCachedSizes( } // required bool is_extension = 2; - if (has_is_extension()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target); } @@ -13051,14 +13313,19 @@ void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption.NamePart) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_name_part()) { + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_name_part(); name_part_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_part_); } - if (from.has_is_extension()) { - set_is_extension(from.is_extension()); + if (cached_has_bits & 0x00000002u) { + is_extension_ = from.is_extension_; } + _has_bits_[0] |= cached_has_bits; } } @@ -13095,7 +13362,7 @@ void UninterpretedOption_NamePart::InternalSwap(UninterpretedOption_NamePart* ot ::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[19]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -13133,6 +13400,7 @@ void UninterpretedOption_NamePart::set_name_part(::std::string&& value) { } #endif void UninterpretedOption_NamePart::set_name_part(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name_part(); name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part) @@ -13261,7 +13529,7 @@ void UninterpretedOption::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[20].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const UninterpretedOption& UninterpretedOption::default_instance() { @@ -13316,13 +13584,11 @@ bool UninterpretedOption::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_name())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -13437,14 +13703,18 @@ failure: void UninterpretedOption::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.UninterpretedOption) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (unsigned int i = 0, n = this->name_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( 2, this->name(i), output); } + cached_has_bits = _has_bits_[0]; // optional string identifier_value = 3; - if (has_identifier_value()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->identifier_value().data(), this->identifier_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -13454,28 +13724,28 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional uint64 positive_int_value = 4; - if (has_positive_int_value()) { + if (cached_has_bits & 0x00000008u) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output); } // optional int64 negative_int_value = 5; - if (has_negative_int_value()) { + if (cached_has_bits & 0x00000010u) { ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output); } // optional double double_value = 6; - if (has_double_value()) { + if (cached_has_bits & 0x00000020u) { ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output); } // optional bytes string_value = 7; - if (has_string_value()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( 7, this->string_value(), output); } // optional string aggregate_value = 8; - if (has_aggregate_value()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->aggregate_value().data(), this->aggregate_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -13493,17 +13763,20 @@ void UninterpretedOption::SerializeWithCachedSizes( ::google::protobuf::uint8* UninterpretedOption::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UninterpretedOption) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.UninterpretedOption.NamePart name = 2; for (unsigned int i = 0, n = this->name_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->name(i), false, target); + 2, this->name(i), deterministic, target); } + cached_has_bits = _has_bits_[0]; // optional string identifier_value = 3; - if (has_identifier_value()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->identifier_value().data(), this->identifier_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -13514,29 +13787,29 @@ void UninterpretedOption::SerializeWithCachedSizes( } // optional uint64 positive_int_value = 4; - if (has_positive_int_value()) { + if (cached_has_bits & 0x00000008u) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target); } // optional int64 negative_int_value = 5; - if (has_negative_int_value()) { + if (cached_has_bits & 0x00000010u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target); } // optional double double_value = 6; - if (has_double_value()) { + if (cached_has_bits & 0x00000020u) { target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target); } // optional bytes string_value = 7; - if (has_string_value()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteBytesToArray( 7, this->string_value(), target); } // optional string aggregate_value = 8; - if (has_aggregate_value()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->aggregate_value().data(), this->aggregate_value().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -13642,29 +13915,34 @@ void UninterpretedOption::MergeFrom(const UninterpretedOption& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UninterpretedOption) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + name_.MergeFrom(from.name_); - if (from._has_bits_[0 / 32] & 63u) { - if (from.has_identifier_value()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 63u) { + if (cached_has_bits & 0x00000001u) { set_has_identifier_value(); identifier_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.identifier_value_); } - if (from.has_string_value()) { + if (cached_has_bits & 0x00000002u) { set_has_string_value(); string_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.string_value_); } - if (from.has_aggregate_value()) { + if (cached_has_bits & 0x00000004u) { set_has_aggregate_value(); aggregate_value_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.aggregate_value_); } - if (from.has_positive_int_value()) { - set_positive_int_value(from.positive_int_value()); + if (cached_has_bits & 0x00000008u) { + positive_int_value_ = from.positive_int_value_; } - if (from.has_negative_int_value()) { - set_negative_int_value(from.negative_int_value()); + if (cached_has_bits & 0x00000010u) { + negative_int_value_ = from.negative_int_value_; } - if (from.has_double_value()) { - set_double_value(from.double_value()); + if (cached_has_bits & 0x00000020u) { + double_value_ = from.double_value_; } + _has_bits_[0] |= cached_has_bits; } } @@ -13692,7 +13970,7 @@ void UninterpretedOption::Swap(UninterpretedOption* other) { InternalSwap(other); } void UninterpretedOption::InternalSwap(UninterpretedOption* other) { - name_.UnsafeArenaSwap(&other->name_); + name_.InternalSwap(&other->name_); identifier_value_.Swap(&other->identifier_value_); string_value_.Swap(&other->string_value_); aggregate_value_.Swap(&other->aggregate_value_); @@ -13706,7 +13984,7 @@ void UninterpretedOption::InternalSwap(UninterpretedOption* other) { ::google::protobuf::Metadata UninterpretedOption::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[20]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -13774,6 +14052,7 @@ void UninterpretedOption::set_identifier_value(::std::string&& value) { } #endif void UninterpretedOption::set_identifier_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_identifier_value(); identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value) @@ -13908,6 +14187,7 @@ void UninterpretedOption::set_string_value(::std::string&& value) { } #endif void UninterpretedOption::set_string_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_string_value(); string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value) @@ -13970,6 +14250,7 @@ void UninterpretedOption::set_aggregate_value(::std::string&& value) { } #endif void UninterpretedOption::set_aggregate_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_aggregate_value(); aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value) @@ -14063,7 +14344,7 @@ void SourceCodeInfo_Location::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[21].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() { @@ -14218,6 +14499,9 @@ failure: void SourceCodeInfo_Location::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo.Location) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); @@ -14238,8 +14522,9 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( this->span(i), output); } + cached_has_bits = _has_bits_[0]; // optional string leading_comments = 3; - if (has_leading_comments()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->leading_comments().data(), this->leading_comments().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -14249,7 +14534,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( } // optional string trailing_comments = 4; - if (has_trailing_comments()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->trailing_comments().data(), this->trailing_comments().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -14277,8 +14562,10 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( ::google::protobuf::uint8* SourceCodeInfo_Location::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo.Location) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( @@ -14287,10 +14574,8 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( target); target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( _path_cached_byte_size_, target); - } - for (int i = 0, n = this->path_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteInt32NoTagToArray(this->path(i), target); + WriteInt32NoTagToArray(this->path_, target); } // repeated int32 span = 2 [packed = true]; @@ -14301,14 +14586,13 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( target); target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( _span_cached_byte_size_, target); - } - for (int i = 0, n = this->span_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteInt32NoTagToArray(this->span(i), target); + WriteInt32NoTagToArray(this->span_, target); } + cached_has_bits = _has_bits_[0]; // optional string leading_comments = 3; - if (has_leading_comments()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->leading_comments().data(), this->leading_comments().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -14319,7 +14603,7 @@ void SourceCodeInfo_Location::SerializeWithCachedSizes( } // optional string trailing_comments = 4; - if (has_trailing_comments()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->trailing_comments().data(), this->trailing_comments().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -14436,15 +14720,19 @@ void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo.Location) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + path_.MergeFrom(from.path_); span_.MergeFrom(from.span_); leading_detached_comments_.MergeFrom(from.leading_detached_comments_); - if (from._has_bits_[0 / 32] & 3u) { - if (from.has_leading_comments()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 3u) { + if (cached_has_bits & 0x00000001u) { set_has_leading_comments(); leading_comments_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.leading_comments_); } - if (from.has_trailing_comments()) { + if (cached_has_bits & 0x00000002u) { set_has_trailing_comments(); trailing_comments_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.trailing_comments_); } @@ -14474,9 +14762,9 @@ void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) { InternalSwap(other); } void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { - path_.UnsafeArenaSwap(&other->path_); - span_.UnsafeArenaSwap(&other->span_); - leading_detached_comments_.UnsafeArenaSwap(&other->leading_detached_comments_); + path_.InternalSwap(&other->path_); + span_.InternalSwap(&other->span_); + leading_detached_comments_.InternalSwap(&other->leading_detached_comments_); leading_comments_.Swap(&other->leading_comments_); trailing_comments_.Swap(&other->trailing_comments_); std::swap(_has_bits_[0], other->_has_bits_[0]); @@ -14486,7 +14774,7 @@ void SourceCodeInfo_Location::InternalSwap(SourceCodeInfo_Location* other) { ::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[21]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -14584,6 +14872,7 @@ void SourceCodeInfo_Location::set_leading_comments(::std::string&& value) { } #endif void SourceCodeInfo_Location::set_leading_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_leading_comments(); leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments) @@ -14646,6 +14935,7 @@ void SourceCodeInfo_Location::set_trailing_comments(::std::string&& value) { } #endif void SourceCodeInfo_Location::set_trailing_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_trailing_comments(); trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments) @@ -14702,6 +14992,7 @@ void SourceCodeInfo_Location::set_leading_detached_comments(int index, ::std::st } #endif void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); leading_detached_comments_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } @@ -14720,11 +15011,12 @@ void SourceCodeInfo_Location::add_leading_detached_comments(const ::std::string& } #if LANG_CXX11 void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) { - leading_detached_comments_.Add()->assign(std::move(value)); + leading_detached_comments_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } #endif void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); leading_detached_comments_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } @@ -14788,7 +15080,7 @@ void SourceCodeInfo::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[22].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const SourceCodeInfo& SourceCodeInfo::default_instance() { @@ -14825,13 +15117,11 @@ bool SourceCodeInfo::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(10u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_location())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -14860,6 +15150,9 @@ failure: void SourceCodeInfo::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.SourceCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; for (unsigned int i = 0, n = this->location_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -14875,13 +15168,15 @@ void SourceCodeInfo::SerializeWithCachedSizes( ::google::protobuf::uint8* SourceCodeInfo::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.SourceCodeInfo.Location location = 1; for (unsigned int i = 0, n = this->location_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 1, this->location(i), false, target); + 1, this->location(i), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -14938,6 +15233,9 @@ void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceCodeInfo) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + location_.MergeFrom(from.location_); } @@ -14964,7 +15262,7 @@ void SourceCodeInfo::Swap(SourceCodeInfo* other) { InternalSwap(other); } void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { - location_.UnsafeArenaSwap(&other->location_); + location_.InternalSwap(&other->location_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -14972,7 +15270,7 @@ void SourceCodeInfo::InternalSwap(SourceCodeInfo* other) { ::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[22]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -15067,7 +15365,7 @@ void GeneratedCodeInfo_Annotation::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* GeneratedCodeInfo_Annotation::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[23].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const GeneratedCodeInfo_Annotation& GeneratedCodeInfo_Annotation::default_instance() { @@ -15195,6 +15493,9 @@ failure: void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo.Annotation) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); @@ -15205,8 +15506,9 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( this->path(i), output); } + cached_has_bits = _has_bits_[0]; // optional string source_file = 2; - if (has_source_file()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->source_file().data(), this->source_file().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -15216,12 +15518,12 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( } // optional int32 begin = 3; - if (has_begin()) { + if (cached_has_bits & 0x00000002u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->begin(), output); } // optional int32 end = 4; - if (has_end()) { + if (cached_has_bits & 0x00000004u) { ::google::protobuf::internal::WireFormatLite::WriteInt32(4, this->end(), output); } @@ -15234,8 +15536,10 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( ::google::protobuf::uint8* GeneratedCodeInfo_Annotation::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo.Annotation) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated int32 path = 1 [packed = true]; if (this->path_size() > 0) { target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray( @@ -15244,14 +15548,13 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( target); target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray( _path_cached_byte_size_, target); - } - for (int i = 0, n = this->path_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: - WriteInt32NoTagToArray(this->path(i), target); + WriteInt32NoTagToArray(this->path_, target); } + cached_has_bits = _has_bits_[0]; // optional string source_file = 2; - if (has_source_file()) { + if (cached_has_bits & 0x00000001u) { ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField( this->source_file().data(), this->source_file().length(), ::google::protobuf::internal::WireFormat::SERIALIZE, @@ -15262,12 +15565,12 @@ void GeneratedCodeInfo_Annotation::SerializeWithCachedSizes( } // optional int32 begin = 3; - if (has_begin()) { + if (cached_has_bits & 0x00000002u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->begin(), target); } // optional int32 end = 4; - if (has_end()) { + if (cached_has_bits & 0x00000004u) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(4, this->end(), target); } @@ -15352,18 +15655,23 @@ void GeneratedCodeInfo_Annotation::MergeFrom(const GeneratedCodeInfo_Annotation& // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo.Annotation) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + path_.MergeFrom(from.path_); - if (from._has_bits_[0 / 32] & 7u) { - if (from.has_source_file()) { + cached_has_bits = from._has_bits_[0]; + if (cached_has_bits & 7u) { + if (cached_has_bits & 0x00000001u) { set_has_source_file(); source_file_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.source_file_); } - if (from.has_begin()) { - set_begin(from.begin()); + if (cached_has_bits & 0x00000002u) { + begin_ = from.begin_; } - if (from.has_end()) { - set_end(from.end()); + if (cached_has_bits & 0x00000004u) { + end_ = from.end_; } + _has_bits_[0] |= cached_has_bits; } } @@ -15390,7 +15698,7 @@ void GeneratedCodeInfo_Annotation::Swap(GeneratedCodeInfo_Annotation* other) { InternalSwap(other); } void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* other) { - path_.UnsafeArenaSwap(&other->path_); + path_.InternalSwap(&other->path_); source_file_.Swap(&other->source_file_); std::swap(begin_, other->begin_); std::swap(end_, other->end_); @@ -15401,7 +15709,7 @@ void GeneratedCodeInfo_Annotation::InternalSwap(GeneratedCodeInfo_Annotation* ot ::google::protobuf::Metadata GeneratedCodeInfo_Annotation::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[23]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -15469,6 +15777,7 @@ void GeneratedCodeInfo_Annotation::set_source_file(::std::string&& value) { } #endif void GeneratedCodeInfo_Annotation::set_source_file(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_source_file(); source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file) @@ -15592,7 +15901,7 @@ void GeneratedCodeInfo::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* GeneratedCodeInfo::descriptor() { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[24].descriptor; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const GeneratedCodeInfo& GeneratedCodeInfo::default_instance() { @@ -15629,13 +15938,11 @@ bool GeneratedCodeInfo::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(10u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_annotation())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -15664,6 +15971,9 @@ failure: void GeneratedCodeInfo::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.GeneratedCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -15679,13 +15989,15 @@ void GeneratedCodeInfo::SerializeWithCachedSizes( ::google::protobuf::uint8* GeneratedCodeInfo::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.GeneratedCodeInfo) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.GeneratedCodeInfo.Annotation annotation = 1; for (unsigned int i = 0, n = this->annotation_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 1, this->annotation(i), false, target); + 1, this->annotation(i), deterministic, target); } if (_internal_metadata_.have_unknown_fields()) { @@ -15742,6 +16054,9 @@ void GeneratedCodeInfo::MergeFrom(const GeneratedCodeInfo& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.GeneratedCodeInfo) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + annotation_.MergeFrom(from.annotation_); } @@ -15768,7 +16083,7 @@ void GeneratedCodeInfo::Swap(GeneratedCodeInfo* other) { InternalSwap(other); } void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { - annotation_.UnsafeArenaSwap(&other->annotation_); + annotation_.InternalSwap(&other->annotation_); std::swap(_has_bits_[0], other->_has_bits_[0]); _internal_metadata_.Swap(&other->_internal_metadata_); std::swap(_cached_size_, other->_cached_size_); @@ -15776,7 +16091,7 @@ void GeneratedCodeInfo::InternalSwap(GeneratedCodeInfo* other) { ::google::protobuf::Metadata GeneratedCodeInfo::GetMetadata() const { protobuf_google_2fprotobuf_2fdescriptor_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[24]; + return protobuf_google_2fprotobuf_2fdescriptor_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 10708963..b8c97a6d 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fdescriptor_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -288,6 +292,8 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message return reinterpret_cast( &_FileDescriptorSet_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void Swap(FileDescriptorSet* other); @@ -310,11 +316,6 @@ class LIBPROTOBUF_EXPORT FileDescriptorSet : public ::google::protobuf::Message ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -386,6 +387,8 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag return reinterpret_cast( &_FileDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void Swap(FileDescriptorProto* other); @@ -408,11 +411,6 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -456,30 +454,6 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag const ::google::protobuf::RepeatedPtrField< ::std::string>& dependency() const; ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_dependency(); - // repeated int32 public_dependency = 10; - int public_dependency_size() const; - void clear_public_dependency(); - static const int kPublicDependencyFieldNumber = 10; - ::google::protobuf::int32 public_dependency(int index) const; - void set_public_dependency(int index, ::google::protobuf::int32 value); - void add_public_dependency(::google::protobuf::int32 value); - const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& - public_dependency() const; - ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* - mutable_public_dependency(); - - // repeated int32 weak_dependency = 11; - int weak_dependency_size() const; - void clear_weak_dependency(); - static const int kWeakDependencyFieldNumber = 11; - ::google::protobuf::int32 weak_dependency(int index) const; - void set_weak_dependency(int index, ::google::protobuf::int32 value); - void add_weak_dependency(::google::protobuf::int32 value); - const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& - weak_dependency() const; - ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* - mutable_weak_dependency(); - // repeated .google.protobuf.DescriptorProto message_type = 4; int message_type_size() const; void clear_message_type(); @@ -528,6 +502,30 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& extension() const; + // repeated int32 public_dependency = 10; + int public_dependency_size() const; + void clear_public_dependency(); + static const int kPublicDependencyFieldNumber = 10; + ::google::protobuf::int32 public_dependency(int index) const; + void set_public_dependency(int index, ::google::protobuf::int32 value); + void add_public_dependency(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + public_dependency() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_public_dependency(); + + // repeated int32 weak_dependency = 11; + int weak_dependency_size() const; + void clear_weak_dependency(); + static const int kWeakDependencyFieldNumber = 11; + ::google::protobuf::int32 weak_dependency(int index) const; + void set_weak_dependency(int index, ::google::protobuf::int32 value); + void add_weak_dependency(::google::protobuf::int32 value); + const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& + weak_dependency() const; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 >* + mutable_weak_dependency(); + // optional string name = 1; bool has_name() const; void clear_name(); @@ -608,12 +606,12 @@ class LIBPROTOBUF_EXPORT FileDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::std::string> dependency_; - ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_; - ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > message_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::ServiceDescriptorProto > service_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > public_dependency_; + ::google::protobuf::RepeatedField< ::google::protobuf::int32 > weak_dependency_; ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::internal::ArenaStringPtr package_; ::google::protobuf::internal::ArenaStringPtr syntax_; @@ -650,6 +648,8 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto return reinterpret_cast( &_DescriptorProto_ExtensionRange_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void Swap(DescriptorProto_ExtensionRange* other); @@ -672,11 +672,6 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ExtensionRange : public ::google::proto ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -755,6 +750,8 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob return reinterpret_cast( &_DescriptorProto_ReservedRange_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 3; void Swap(DescriptorProto_ReservedRange* other); @@ -777,11 +774,6 @@ class LIBPROTOBUF_EXPORT DescriptorProto_ReservedRange : public ::google::protob ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -860,6 +852,8 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* return reinterpret_cast( &_DescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 4; void Swap(DescriptorProto* other); @@ -882,11 +876,6 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -923,18 +912,6 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& field() const; - // repeated .google.protobuf.FieldDescriptorProto extension = 6; - int extension_size() const; - void clear_extension(); - static const int kExtensionFieldNumber = 6; - const ::google::protobuf::FieldDescriptorProto& extension(int index) const; - ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); - ::google::protobuf::FieldDescriptorProto* add_extension(); - ::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; void clear_nested_type(); @@ -971,6 +948,18 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* const ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange >& extension_range() const; + // repeated .google.protobuf.FieldDescriptorProto extension = 6; + int extension_size() const; + void clear_extension(); + static const int kExtensionFieldNumber = 6; + const ::google::protobuf::FieldDescriptorProto& extension(int index) const; + ::google::protobuf::FieldDescriptorProto* mutable_extension(int index); + ::google::protobuf::FieldDescriptorProto* add_extension(); + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >* + mutable_extension(); + const ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto >& + extension() const; + // repeated .google.protobuf.OneofDescriptorProto oneof_decl = 8; int oneof_decl_size() const; void clear_oneof_decl(); @@ -1052,10 +1041,10 @@ class LIBPROTOBUF_EXPORT DescriptorProto : public ::google::protobuf::Message /* ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > field_; - ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto > nested_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::EnumDescriptorProto > enum_type_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ExtensionRange > extension_range_; + ::google::protobuf::RepeatedPtrField< ::google::protobuf::FieldDescriptorProto > extension_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::OneofDescriptorProto > oneof_decl_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::DescriptorProto_ReservedRange > reserved_range_; ::google::protobuf::RepeatedPtrField< ::std::string> reserved_name_; @@ -1092,6 +1081,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa return reinterpret_cast( &_FieldDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 5; void Swap(FieldDescriptorProto* other); @@ -1114,11 +1105,6 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1241,21 +1227,6 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::std::string* release_name(); void set_allocated_name(::std::string* name); - // optional string type_name = 6; - bool has_type_name() const; - void clear_type_name(); - static const int kTypeNameFieldNumber = 6; - const ::std::string& type_name() const; - void set_type_name(const ::std::string& value); - #if LANG_CXX11 - void set_type_name(::std::string&& value); - #endif - void set_type_name(const char* value); - void set_type_name(const char* value, size_t size); - ::std::string* mutable_type_name(); - ::std::string* release_type_name(); - void set_allocated_type_name(::std::string* type_name); - // optional string extendee = 2; bool has_extendee() const; void clear_extendee(); @@ -1271,6 +1242,21 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::std::string* release_extendee(); void set_allocated_extendee(::std::string* extendee); + // optional string type_name = 6; + bool has_type_name() const; + void clear_type_name(); + static const int kTypeNameFieldNumber = 6; + const ::std::string& type_name() const; + void set_type_name(const ::std::string& value); + #if LANG_CXX11 + void set_type_name(::std::string&& value); + #endif + void set_type_name(const char* value); + void set_type_name(const char* value, size_t size); + ::std::string* mutable_type_name(); + ::std::string* release_type_name(); + void set_allocated_type_name(::std::string* type_name); + // optional string default_value = 7; bool has_default_value() const; void clear_default_value(); @@ -1365,8 +1351,8 @@ class LIBPROTOBUF_EXPORT FieldDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::internal::HasBits<1> _has_bits_; mutable int _cached_size_; ::google::protobuf::internal::ArenaStringPtr name_; - ::google::protobuf::internal::ArenaStringPtr type_name_; ::google::protobuf::internal::ArenaStringPtr extendee_; + ::google::protobuf::internal::ArenaStringPtr type_name_; ::google::protobuf::internal::ArenaStringPtr default_value_; ::google::protobuf::internal::ArenaStringPtr json_name_; ::google::protobuf::FieldOptions* options_; @@ -1405,6 +1391,8 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa return reinterpret_cast( &_OneofDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 6; void Swap(OneofDescriptorProto* other); @@ -1427,11 +1415,6 @@ class LIBPROTOBUF_EXPORT OneofDescriptorProto : public ::google::protobuf::Messa ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1520,6 +1503,8 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag return reinterpret_cast( &_EnumDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 7; void Swap(EnumDescriptorProto* other); @@ -1542,11 +1527,6 @@ class LIBPROTOBUF_EXPORT EnumDescriptorProto : public ::google::protobuf::Messag ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1648,6 +1628,8 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M return reinterpret_cast( &_EnumValueDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 8; void Swap(EnumValueDescriptorProto* other); @@ -1670,11 +1652,6 @@ class LIBPROTOBUF_EXPORT EnumValueDescriptorProto : public ::google::protobuf::M ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1773,6 +1750,8 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes return reinterpret_cast( &_ServiceDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 9; void Swap(ServiceDescriptorProto* other); @@ -1795,11 +1774,6 @@ class LIBPROTOBUF_EXPORT ServiceDescriptorProto : public ::google::protobuf::Mes ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1901,6 +1875,8 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess return reinterpret_cast( &_MethodDescriptorProto_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 10; void Swap(MethodDescriptorProto* other); @@ -1923,11 +1899,6 @@ class LIBPROTOBUF_EXPORT MethodDescriptorProto : public ::google::protobuf::Mess ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2072,6 +2043,8 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_FileOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 11; void Swap(FileOptions* other); @@ -2094,11 +2067,6 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2417,6 +2385,8 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* return reinterpret_cast( &_MessageOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 12; void Swap(MessageOptions* other); @@ -2439,11 +2409,6 @@ class LIBPROTOBUF_EXPORT MessageOptions : public ::google::protobuf::Message /* ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2558,6 +2523,8 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ return reinterpret_cast( &_FieldOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 13; void Swap(FieldOptions* other); @@ -2580,11 +2547,6 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2681,13 +2643,6 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ ::google::protobuf::FieldOptions_CType ctype() const; void set_ctype(::google::protobuf::FieldOptions_CType value); - // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; - bool has_jstype() const; - void clear_jstype(); - static const int kJstypeFieldNumber = 6; - ::google::protobuf::FieldOptions_JSType jstype() const; - void set_jstype(::google::protobuf::FieldOptions_JSType value); - // optional bool packed = 2; bool has_packed() const; void clear_packed(); @@ -2716,6 +2671,13 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ bool weak() const; void set_weak(bool value); + // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; + bool has_jstype() const; + void clear_jstype(); + static const int kJstypeFieldNumber = 6; + ::google::protobuf::FieldOptions_JSType jstype() const; + void set_jstype(::google::protobuf::FieldOptions_JSType value); + GOOGLE_PROTOBUF_EXTENSION_ACCESSORS(FieldOptions) // @@protoc_insertion_point(class_scope:google.protobuf.FieldOptions) private: @@ -2739,11 +2701,11 @@ class LIBPROTOBUF_EXPORT FieldOptions : public ::google::protobuf::Message /* @@ mutable int _cached_size_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_; int ctype_; - int jstype_; bool packed_; bool lazy_; bool deprecated_; bool weak_; + int jstype_; friend struct protobuf_google_2fprotobuf_2fdescriptor_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -2775,6 +2737,8 @@ class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@ return reinterpret_cast( &_OneofOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 14; void Swap(OneofOptions* other); @@ -2797,11 +2761,6 @@ class LIBPROTOBUF_EXPORT OneofOptions : public ::google::protobuf::Message /* @@ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2876,6 +2835,8 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_EnumOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 15; void Swap(EnumOptions* other); @@ -2898,11 +2859,6 @@ class LIBPROTOBUF_EXPORT EnumOptions : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -2997,6 +2953,8 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message / return reinterpret_cast( &_EnumValueOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 16; void Swap(EnumValueOptions* other); @@ -3019,11 +2977,6 @@ class LIBPROTOBUF_EXPORT EnumValueOptions : public ::google::protobuf::Message / ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3108,6 +3061,8 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* return reinterpret_cast( &_ServiceOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 17; void Swap(ServiceOptions* other); @@ -3130,11 +3085,6 @@ class LIBPROTOBUF_EXPORT ServiceOptions : public ::google::protobuf::Message /* ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3219,6 +3169,8 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @ return reinterpret_cast( &_MethodOptions_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 18; void Swap(MethodOptions* other); @@ -3241,11 +3193,6 @@ class LIBPROTOBUF_EXPORT MethodOptions : public ::google::protobuf::Message /* @ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3368,6 +3315,8 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu return reinterpret_cast( &_UninterpretedOption_NamePart_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 19; void Swap(UninterpretedOption_NamePart* other); @@ -3390,11 +3339,6 @@ class LIBPROTOBUF_EXPORT UninterpretedOption_NamePart : public ::google::protobu ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3484,6 +3428,8 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag return reinterpret_cast( &_UninterpretedOption_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 20; void Swap(UninterpretedOption* other); @@ -3506,11 +3452,6 @@ class LIBPROTOBUF_EXPORT UninterpretedOption : public ::google::protobuf::Messag ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3668,6 +3609,8 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me return reinterpret_cast( &_SourceCodeInfo_Location_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 21; void Swap(SourceCodeInfo_Location* other); @@ -3690,11 +3633,6 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo_Location : public ::google::protobuf::Me ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3840,6 +3778,8 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* return reinterpret_cast( &_SourceCodeInfo_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 22; void Swap(SourceCodeInfo* other); @@ -3862,11 +3802,6 @@ class LIBPROTOBUF_EXPORT SourceCodeInfo : public ::google::protobuf::Message /* ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -3940,6 +3875,8 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu return reinterpret_cast( &_GeneratedCodeInfo_Annotation_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 23; void Swap(GeneratedCodeInfo_Annotation* other); @@ -3962,11 +3899,6 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo_Annotation : public ::google::protobu ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -4077,6 +4009,8 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message return reinterpret_cast( &_GeneratedCodeInfo_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 24; void Swap(GeneratedCodeInfo* other); @@ -4099,11 +4033,6 @@ class LIBPROTOBUF_EXPORT GeneratedCodeInfo : public ::google::protobuf::Message ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -4222,6 +4151,7 @@ inline void FileDescriptorProto::set_name(::std::string&& value) { } #endif inline void FileDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.name) @@ -4284,6 +4214,7 @@ inline void FileDescriptorProto::set_package(::std::string&& value) { } #endif inline void FileDescriptorProto::set_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_package(); package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.package) @@ -4340,6 +4271,7 @@ inline void FileDescriptorProto::set_dependency(int index, ::std::string&& value } #endif inline void FileDescriptorProto::set_dependency(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); dependency_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.dependency) } @@ -4358,11 +4290,12 @@ inline void FileDescriptorProto::add_dependency(const ::std::string& value) { } #if LANG_CXX11 inline void FileDescriptorProto::add_dependency(::std::string&& value) { - dependency_.Add()->assign(std::move(value)); + dependency_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.FileDescriptorProto.dependency) } #endif inline void FileDescriptorProto::add_dependency(const char* value) { + GOOGLE_DCHECK(value != NULL); dependency_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.FileDescriptorProto.dependency) } @@ -4683,6 +4616,7 @@ inline void FileDescriptorProto::set_syntax(::std::string&& value) { } #endif inline void FileDescriptorProto::set_syntax(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_syntax(); syntax_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileDescriptorProto.syntax) @@ -4853,6 +4787,7 @@ inline void DescriptorProto::set_name(::std::string&& value) { } #endif inline void DescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.name) @@ -5164,6 +5099,7 @@ inline void DescriptorProto::set_reserved_name(int index, ::std::string&& value) } #endif inline void DescriptorProto::set_reserved_name(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); reserved_name_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.DescriptorProto.reserved_name) } @@ -5182,11 +5118,12 @@ inline void DescriptorProto::add_reserved_name(const ::std::string& value) { } #if LANG_CXX11 inline void DescriptorProto::add_reserved_name(::std::string&& value) { - reserved_name_.Add()->assign(std::move(value)); + reserved_name_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.DescriptorProto.reserved_name) } #endif inline void DescriptorProto::add_reserved_name(const char* value) { + GOOGLE_DCHECK(value != NULL); reserved_name_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.DescriptorProto.reserved_name) } @@ -5241,6 +5178,7 @@ inline void FieldDescriptorProto::set_name(::std::string&& value) { } #endif inline void FieldDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.name) @@ -5347,13 +5285,13 @@ inline void FieldDescriptorProto::set_type(::google::protobuf::FieldDescriptorPr // optional string type_name = 6; inline bool FieldDescriptorProto::has_type_name() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } inline void FieldDescriptorProto::set_has_type_name() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000004u; } inline void FieldDescriptorProto::clear_has_type_name() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000004u; } inline void FieldDescriptorProto::clear_type_name() { type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -5377,6 +5315,7 @@ inline void FieldDescriptorProto::set_type_name(::std::string&& value) { } #endif inline void FieldDescriptorProto::set_type_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_type_name(); type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.type_name) @@ -5409,13 +5348,13 @@ inline void FieldDescriptorProto::set_allocated_type_name(::std::string* type_na // optional string extendee = 2; inline bool FieldDescriptorProto::has_extendee() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } inline void FieldDescriptorProto::set_has_extendee() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000002u; } inline void FieldDescriptorProto::clear_has_extendee() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000002u; } inline void FieldDescriptorProto::clear_extendee() { extendee_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited()); @@ -5439,6 +5378,7 @@ inline void FieldDescriptorProto::set_extendee(::std::string&& value) { } #endif inline void FieldDescriptorProto::set_extendee(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_extendee(); extendee_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.extendee) @@ -5501,6 +5441,7 @@ inline void FieldDescriptorProto::set_default_value(::std::string&& value) { } #endif inline void FieldDescriptorProto::set_default_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_default_value(); default_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.default_value) @@ -5587,6 +5528,7 @@ inline void FieldDescriptorProto::set_json_name(::std::string&& value) { } #endif inline void FieldDescriptorProto::set_json_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_json_name(); json_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldDescriptorProto.json_name) @@ -5698,6 +5640,7 @@ inline void OneofDescriptorProto::set_name(::std::string&& value) { } #endif inline void OneofDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.OneofDescriptorProto.name) @@ -5809,6 +5752,7 @@ inline void EnumDescriptorProto::set_name(::std::string&& value) { } #endif inline void EnumDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumDescriptorProto.name) @@ -5950,6 +5894,7 @@ inline void EnumValueDescriptorProto::set_name(::std::string&& value) { } #endif inline void EnumValueDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.EnumValueDescriptorProto.name) @@ -6085,6 +6030,7 @@ inline void ServiceDescriptorProto::set_name(::std::string&& value) { } #endif inline void ServiceDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.ServiceDescriptorProto.name) @@ -6226,6 +6172,7 @@ inline void MethodDescriptorProto::set_name(::std::string&& value) { } #endif inline void MethodDescriptorProto::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name(); name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.name) @@ -6288,6 +6235,7 @@ inline void MethodDescriptorProto::set_input_type(::std::string&& value) { } #endif inline void MethodDescriptorProto::set_input_type(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_input_type(); input_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.input_type) @@ -6350,6 +6298,7 @@ inline void MethodDescriptorProto::set_output_type(::std::string&& value) { } #endif inline void MethodDescriptorProto::set_output_type(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_output_type(); output_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.MethodDescriptorProto.output_type) @@ -6509,6 +6458,7 @@ inline void FileOptions::set_java_package(::std::string&& value) { } #endif inline void FileOptions::set_java_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_java_package(); java_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_package) @@ -6571,6 +6521,7 @@ inline void FileOptions::set_java_outer_classname(::std::string&& value) { } #endif inline void FileOptions::set_java_outer_classname(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_java_outer_classname(); java_outer_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.java_outer_classname) @@ -6730,6 +6681,7 @@ inline void FileOptions::set_go_package(::std::string&& value) { } #endif inline void FileOptions::set_go_package(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_go_package(); go_package_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.go_package) @@ -6912,6 +6864,7 @@ inline void FileOptions::set_objc_class_prefix(::std::string&& value) { } #endif inline void FileOptions::set_objc_class_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_objc_class_prefix(); objc_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.objc_class_prefix) @@ -6974,6 +6927,7 @@ inline void FileOptions::set_csharp_namespace(::std::string&& value) { } #endif inline void FileOptions::set_csharp_namespace(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_csharp_namespace(); csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace) @@ -7036,6 +6990,7 @@ inline void FileOptions::set_swift_prefix(::std::string&& value) { } #endif inline void FileOptions::set_swift_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_swift_prefix(); swift_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.swift_prefix) @@ -7098,6 +7053,7 @@ inline void FileOptions::set_php_class_prefix(::std::string&& value) { } #endif inline void FileOptions::set_php_class_prefix(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_php_class_prefix(); php_class_prefix_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.php_class_prefix) @@ -7319,13 +7275,13 @@ inline void FieldOptions::set_ctype(::google::protobuf::FieldOptions_CType value // optional bool packed = 2; inline bool FieldOptions::has_packed() const { - return (_has_bits_[0] & 0x00000004u) != 0; + return (_has_bits_[0] & 0x00000002u) != 0; } inline void FieldOptions::set_has_packed() { - _has_bits_[0] |= 0x00000004u; + _has_bits_[0] |= 0x00000002u; } inline void FieldOptions::clear_has_packed() { - _has_bits_[0] &= ~0x00000004u; + _has_bits_[0] &= ~0x00000002u; } inline void FieldOptions::clear_packed() { packed_ = false; @@ -7343,13 +7299,13 @@ inline void FieldOptions::set_packed(bool value) { // optional .google.protobuf.FieldOptions.JSType jstype = 6 [default = JS_NORMAL]; inline bool FieldOptions::has_jstype() const { - return (_has_bits_[0] & 0x00000002u) != 0; + return (_has_bits_[0] & 0x00000020u) != 0; } inline void FieldOptions::set_has_jstype() { - _has_bits_[0] |= 0x00000002u; + _has_bits_[0] |= 0x00000020u; } inline void FieldOptions::clear_has_jstype() { - _has_bits_[0] &= ~0x00000002u; + _has_bits_[0] &= ~0x00000020u; } inline void FieldOptions::clear_jstype() { jstype_ = 0; @@ -7368,13 +7324,13 @@ inline void FieldOptions::set_jstype(::google::protobuf::FieldOptions_JSType val // optional bool lazy = 5 [default = false]; inline bool FieldOptions::has_lazy() const { - return (_has_bits_[0] & 0x00000008u) != 0; + return (_has_bits_[0] & 0x00000004u) != 0; } inline void FieldOptions::set_has_lazy() { - _has_bits_[0] |= 0x00000008u; + _has_bits_[0] |= 0x00000004u; } inline void FieldOptions::clear_has_lazy() { - _has_bits_[0] &= ~0x00000008u; + _has_bits_[0] &= ~0x00000004u; } inline void FieldOptions::clear_lazy() { lazy_ = false; @@ -7392,13 +7348,13 @@ inline void FieldOptions::set_lazy(bool value) { // optional bool deprecated = 3 [default = false]; inline bool FieldOptions::has_deprecated() const { - return (_has_bits_[0] & 0x00000010u) != 0; + return (_has_bits_[0] & 0x00000008u) != 0; } inline void FieldOptions::set_has_deprecated() { - _has_bits_[0] |= 0x00000010u; + _has_bits_[0] |= 0x00000008u; } inline void FieldOptions::clear_has_deprecated() { - _has_bits_[0] &= ~0x00000010u; + _has_bits_[0] &= ~0x00000008u; } inline void FieldOptions::clear_deprecated() { deprecated_ = false; @@ -7416,13 +7372,13 @@ inline void FieldOptions::set_deprecated(bool value) { // optional bool weak = 10 [default = false]; inline bool FieldOptions::has_weak() const { - return (_has_bits_[0] & 0x00000020u) != 0; + return (_has_bits_[0] & 0x00000010u) != 0; } inline void FieldOptions::set_has_weak() { - _has_bits_[0] |= 0x00000020u; + _has_bits_[0] |= 0x00000010u; } inline void FieldOptions::clear_has_weak() { - _has_bits_[0] &= ~0x00000020u; + _has_bits_[0] &= ~0x00000010u; } inline void FieldOptions::clear_weak() { weak_ = false; @@ -7819,6 +7775,7 @@ inline void UninterpretedOption_NamePart::set_name_part(::std::string&& value) { } #endif inline void UninterpretedOption_NamePart::set_name_part(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_name_part(); name_part_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.NamePart.name_part) @@ -7939,6 +7896,7 @@ inline void UninterpretedOption::set_identifier_value(::std::string&& value) { } #endif inline void UninterpretedOption::set_identifier_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_identifier_value(); identifier_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.identifier_value) @@ -8073,6 +8031,7 @@ inline void UninterpretedOption::set_string_value(::std::string&& value) { } #endif inline void UninterpretedOption::set_string_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_string_value(); string_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.string_value) @@ -8135,6 +8094,7 @@ inline void UninterpretedOption::set_aggregate_value(::std::string&& value) { } #endif inline void UninterpretedOption::set_aggregate_value(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_aggregate_value(); aggregate_value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.UninterpretedOption.aggregate_value) @@ -8261,6 +8221,7 @@ inline void SourceCodeInfo_Location::set_leading_comments(::std::string&& value) } #endif inline void SourceCodeInfo_Location::set_leading_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_leading_comments(); leading_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_comments) @@ -8323,6 +8284,7 @@ inline void SourceCodeInfo_Location::set_trailing_comments(::std::string&& value } #endif inline void SourceCodeInfo_Location::set_trailing_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_trailing_comments(); trailing_comments_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.trailing_comments) @@ -8379,6 +8341,7 @@ inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, :: } #endif inline void SourceCodeInfo_Location::set_leading_detached_comments(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); leading_detached_comments_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } @@ -8397,11 +8360,12 @@ inline void SourceCodeInfo_Location::add_leading_detached_comments(const ::std:: } #if LANG_CXX11 inline void SourceCodeInfo_Location::add_leading_detached_comments(::std::string&& value) { - leading_detached_comments_.Add()->assign(std::move(value)); + leading_detached_comments_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } #endif inline void SourceCodeInfo_Location::add_leading_detached_comments(const char* value) { + GOOGLE_DCHECK(value != NULL); leading_detached_comments_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.SourceCodeInfo.Location.leading_detached_comments) } @@ -8520,6 +8484,7 @@ inline void GeneratedCodeInfo_Annotation::set_source_file(::std::string&& value) } #endif inline void GeneratedCodeInfo_Annotation::set_source_file(const char* value) { + GOOGLE_DCHECK(value != NULL); set_has_source_file(); source_file_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.GeneratedCodeInfo.Annotation.source_file) diff --git a/src/google/protobuf/descriptor.proto b/src/google/protobuf/descriptor.proto index be223683..f859c429 100644 --- a/src/google/protobuf/descriptor.proto +++ b/src/google/protobuf/descriptor.proto @@ -445,7 +445,7 @@ message MessageOptions { optional bool map_entry = 7; reserved 8; // javalite_serializable - + reserved 9; // javanano_as_lite // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; @@ -565,6 +565,7 @@ message EnumOptions { // is a formalization for deprecating enums. optional bool deprecated = 3 [default=false]; + reserved 5; // javanano_as_lite // The parser stores options it doesn't recognize here. See above. repeated UninterpretedOption uninterpreted_option = 999; diff --git a/src/google/protobuf/descriptor_database.cc b/src/google/protobuf/descriptor_database.cc index 57ae960f..4e46b2a8 100644 --- a/src/google/protobuf/descriptor_database.cc +++ b/src/google/protobuf/descriptor_database.cc @@ -199,7 +199,7 @@ template bool SimpleDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( const string& containing_type, std::vector* output) { - typename std::map, Value>::const_iterator it = + typename std::map, Value>::const_iterator it = by_extension_.lower_bound(std::make_pair(containing_type, 0)); bool success = false; @@ -213,7 +213,7 @@ bool SimpleDescriptorDatabase::DescriptorIndex::FindAllExtensionNumbers( } template -typename map::iterator +typename std::map::iterator SimpleDescriptorDatabase::DescriptorIndex::FindLastLessOrEqual( const string& name) { // Find the last key in the map which sorts less than or equal to the diff --git a/src/google/protobuf/descriptor_database.h b/src/google/protobuf/descriptor_database.h index be97a6d8..28f8af7a 100644 --- a/src/google/protobuf/descriptor_database.h +++ b/src/google/protobuf/descriptor_database.h @@ -102,6 +102,18 @@ class LIBPROTOBUF_EXPORT DescriptorDatabase { } + // Finds the file names and appends them to the output in an + // undefined order. This method is best-effort: it's not guaranteed that the + // database will find all files. Returns true if the database supports + // searching all file names, otherwise returns false and leaves output + // unchanged. + // + // This method has a default implementation that always returns + // false. + virtual bool FindAllFileNames(std::vector* output) { + return false; + } + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(DescriptorDatabase); }; diff --git a/src/google/protobuf/descriptor_database_unittest.cc b/src/google/protobuf/descriptor_database_unittest.cc index 05d67656..7e81d70a 100644 --- a/src/google/protobuf/descriptor_database_unittest.cc +++ b/src/google/protobuf/descriptor_database_unittest.cc @@ -44,7 +44,6 @@ #include #include #include -#include #include #include diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index 7ec75156..75238931 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +53,6 @@ #include #include #include -#include #include #include @@ -501,7 +501,7 @@ void ExtractDebugString( for (int i = 0; i < file->dependency_count(); ++i) { ExtractDebugString(file->dependency(i), visited, debug_strings); } - debug_strings->push_back(make_pair(file->name(), file->DebugString())); + debug_strings->push_back(std::make_pair(file->name(), file->DebugString())); } class SimpleErrorCollector : public google::protobuf::io::ErrorCollector { @@ -6066,6 +6066,7 @@ TEST_F(ValidationErrorTest, ValidateProto3JsonName) { "conflicts with field \"ab\". This is not allowed in proto3.\n"); } + // =================================================================== // DescriptorDatabase @@ -6824,6 +6825,360 @@ TEST_F(CopySourceCodeInfoToTest, CopySourceCodeInfoTo) { // =================================================================== +class LazilyBuildDependenciesTest : public testing::Test { + public: + LazilyBuildDependenciesTest() : pool_(&db_, NULL) { + pool_.InternalSetLazilyBuildDependencies(); + } + + void ParseProtoAndAddToDb(const char* proto) { + FileDescriptorProto tmp; + ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp)); + db_.Add(tmp); + } + + void ParseProtoAndAddToDb(const string& proto) { + FileDescriptorProto tmp; + ASSERT_TRUE(TextFormat::ParseFromString(proto, &tmp)); + db_.Add(tmp); + } + + void AddSimpleMessageProtoFileToDb(const char* file_name, + const char* message_name) { + ParseProtoAndAddToDb("name: '" + string(file_name) + + ".proto' " + "package: \"protobuf_unittest\" " + "message_type { " + " name:'" + + string(message_name) + + "' " + " field { name:'a' number:1 " + " label:LABEL_OPTIONAL " + " type_name:'int32' } " + "}"); + } + + void AddSimpleEnumProtoFileToDb(const char* file_name, const char* enum_name, + const char* enum_value_name) { + ParseProtoAndAddToDb("name: '" + string(file_name) + + ".proto' " + "package: 'protobuf_unittest' " + "enum_type { " + " name:'" + + string(enum_name) + + "' " + " value { name:'" + + string(enum_value_name) + + "' number:1 } " + "}"); + } + + protected: + SimpleDescriptorDatabase db_; + DescriptorPool pool_; +}; + +TEST_F(LazilyBuildDependenciesTest, Message) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'bar.proto' " + "message_type { " + " name:'Foo' " + " field { name:'bar' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Bar' } " + "}"); + AddSimpleMessageProtoFileToDb("bar", "Bar"); + + // Verify neither has been built yet. + EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto")); + + const FileDescriptor* file = pool_.FindFileByName("foo.proto"); + + // Verify only foo gets built when asking for foo.proto + EXPECT_TRUE(file != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto")); + + // Verify calling FindFieldBy* works when the type of the field was + // not built at cross link time. Verify this doesn't build the file + // the field's type is defined in, as well. + const Descriptor* desc = file->FindMessageTypeByName("Foo"); + const FieldDescriptor* field = desc->FindFieldByName("bar"); + EXPECT_TRUE(field != NULL); + EXPECT_EQ(field, desc->FindFieldByNumber(1)); + EXPECT_EQ(field, desc->FindFieldByLowercaseName("bar")); + EXPECT_EQ(field, desc->FindFieldByCamelcaseName("bar")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto")); + + // Finally, verify that if we call message_type() on the field, we will + // buid the file where the message is defined, and get a valid descriptor + EXPECT_TRUE(field->message_type() != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto")); +} + +TEST_F(LazilyBuildDependenciesTest, Enum) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'enum1.proto' " + "dependency: 'enum2.proto' " + "message_type { " + " name:'Lazy' " + " field { name:'enum1' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Enum1' } " + " field { name:'enum2' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Enum2' } " + "}"); + AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1"); + AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2"); + + const FileDescriptor* file = pool_.FindFileByName("foo.proto"); + + // Verify calling enum_type() on a field whose definition is not + // yet built will build the file and return a descriptor. + EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto")); + const Descriptor* desc = file->FindMessageTypeByName("Lazy"); + EXPECT_TRUE(desc != NULL); + const FieldDescriptor* field = desc->FindFieldByName("enum1"); + EXPECT_TRUE(field != NULL); + EXPECT_TRUE(field->enum_type() != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto")); + + // Verify calling default_value_enum() on a field whose definition is not + // yet built will build the file and return a descriptor to the value. + EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto")); + field = desc->FindFieldByName("enum2"); + EXPECT_TRUE(field != NULL); + EXPECT_TRUE(field->default_value_enum() != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto")); +} + +TEST_F(LazilyBuildDependenciesTest, Type) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'message1.proto' " + "dependency: 'message2.proto' " + "dependency: 'enum1.proto' " + "dependency: 'enum2.proto' " + "message_type { " + " name:'Lazy' " + " field { name:'message1' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Message1' } " + " field { name:'message2' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Message2' } " + " field { name:'enum1' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Enum1' } " + " field { name:'enum2' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Enum2' } " + "}"); + AddSimpleMessageProtoFileToDb("message1", "Message1"); + AddSimpleMessageProtoFileToDb("message2", "Message2"); + AddSimpleEnumProtoFileToDb("enum1", "Enum1", "ENUM1"); + AddSimpleEnumProtoFileToDb("enum2", "Enum2", "ENUM2"); + + const FileDescriptor* file = pool_.FindFileByName("foo.proto"); + + // Verify calling type() on a field that is a message type will + // build the type defined in another file. + EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto")); + const Descriptor* desc = file->FindMessageTypeByName("Lazy"); + EXPECT_TRUE(desc != NULL); + const FieldDescriptor* field = desc->FindFieldByName("message1"); + EXPECT_TRUE(field != NULL); + EXPECT_EQ(field->type(), FieldDescriptor::TYPE_MESSAGE); + EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto")); + + // Verify calling cpp_type() on a field that is a message type will + // build the type defined in another file. + EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto")); + field = desc->FindFieldByName("message2"); + EXPECT_TRUE(field != NULL); + EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_MESSAGE); + EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto")); + + // Verify calling type() on a field that is an enum type will + // build the type defined in another file. + EXPECT_FALSE(pool_.InternalIsFileLoaded("enum1.proto")); + field = desc->FindFieldByName("enum1"); + EXPECT_TRUE(field != NULL); + EXPECT_EQ(field->type(), FieldDescriptor::TYPE_ENUM); + EXPECT_TRUE(pool_.InternalIsFileLoaded("enum1.proto")); + + // Verify calling cpp_type() on a field that is an enum type will + // build the type defined in another file. + EXPECT_FALSE(pool_.InternalIsFileLoaded("enum2.proto")); + field = desc->FindFieldByName("enum2"); + EXPECT_TRUE(field != NULL); + EXPECT_EQ(field->cpp_type(), FieldDescriptor::CPPTYPE_ENUM); + EXPECT_TRUE(pool_.InternalIsFileLoaded("enum2.proto")); +} + +TEST_F(LazilyBuildDependenciesTest, Extension) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'bar.proto' " + "dependency: 'baz.proto' " + "extension { extendee: '.protobuf_unittest.Bar' name:'bar' number:11" + " label:LABEL_OPTIONAL type_name:'.protobuf_unittest.Baz' }"); + ParseProtoAndAddToDb( + "name: 'bar.proto' " + "package: 'protobuf_unittest' " + "message_type { " + " name:'Bar' " + " extension_range { start: 10 end: 20 }" + "}"); + AddSimpleMessageProtoFileToDb("baz", "Baz"); + + // Verify none have been built yet. + EXPECT_FALSE(pool_.InternalIsFileLoaded("foo.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto")); + + const FileDescriptor* file = pool_.FindFileByName("foo.proto"); + + // Verify foo.bar gets loaded, and bar.proto gets loaded + // to register the extension. baz.proto should not get loaded. + EXPECT_TRUE(file != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto")); + EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto")); +} + +TEST_F(LazilyBuildDependenciesTest, Service) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'message1.proto' " + "dependency: 'message2.proto' " + "dependency: 'message3.proto' " + "dependency: 'message4.proto' " + "service {" + " name: 'LazyService'" + " method { name: 'A' input_type: '.protobuf_unittest.Message1' " + " output_type: '.protobuf_unittest.Message2' }" + "}"); + AddSimpleMessageProtoFileToDb("message1", "Message1"); + AddSimpleMessageProtoFileToDb("message2", "Message2"); + AddSimpleMessageProtoFileToDb("message3", "Message3"); + AddSimpleMessageProtoFileToDb("message4", "Message4"); + + const FileDescriptor* file = pool_.FindFileByName("foo.proto"); + + // Verify calling FindServiceByName or FindMethodByName doesn't build the + // files defining the input and output type, and input_type() and + // output_type() does indeed build the appropriate files. + const ServiceDescriptor* service = file->FindServiceByName("LazyService"); + EXPECT_TRUE(service != NULL); + const MethodDescriptor* method = service->FindMethodByName("A"); + EXPECT_FALSE(pool_.InternalIsFileLoaded("message1.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto")); + EXPECT_TRUE(method != NULL); + EXPECT_TRUE(method->input_type() != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("message1.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("message2.proto")); + EXPECT_TRUE(method->output_type() != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("message2.proto")); +} + + +TEST_F(LazilyBuildDependenciesTest, GeneratedFile) { + // Most testing is done with custom pools with lazy dependencies forced on, + // do some sanity checking that lazy imports is on by default for the + // generated pool, and do custom options testing with generated to + // be able to use the GetExtension ids for the custom options. + + // Verify none of the files are loaded yet. + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_custom_option.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_enum.proto")); + + // Verify calling autogenerated function to get a descriptor in the base + // file will build that file but none of it's imports. This verifies that + // lazily_build_dependencies_ is set on the generated pool, and also that + // the generated function "descriptor()" doesn't somehow subvert the laziness + // by manually loading the dependencies or something. + EXPECT_TRUE(protobuf_unittest::lazy_imports::ImportedMessage::descriptor() != + NULL); + EXPECT_TRUE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_custom_option.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_enum.proto")); + + // Verify custom options work when defined in an import that isn't loaded, + // and that a non-default value of a custom option doesn't load the file + // where that enum is defined. + const google::protobuf::MessageOptions& options = + protobuf_unittest::lazy_imports::MessageCustomOption::descriptor() + ->options(); + protobuf_unittest::lazy_imports::LazyEnum custom_option_value = + options.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option); + + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_custom_option.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_enum.proto")); + EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_1); + + const google::protobuf::MessageOptions& options2 = + protobuf_unittest::lazy_imports::MessageCustomOption2::descriptor() + ->options(); + custom_option_value = + options2.GetExtension(protobuf_unittest::lazy_imports::lazy_enum_option); + + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_custom_option.proto")); + EXPECT_FALSE(DescriptorPool::generated_pool()->InternalIsFileLoaded( + "google/protobuf/unittest_lazy_dependencies_enum.proto")); + EXPECT_EQ(custom_option_value, protobuf_unittest::lazy_imports::LAZY_ENUM_0); +} + +TEST_F(LazilyBuildDependenciesTest, Dependency) { + ParseProtoAndAddToDb( + "name: 'foo.proto' " + "package: 'protobuf_unittest' " + "dependency: 'bar.proto' " + "message_type { " + " name:'Foo' " + " field { name:'bar' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Bar' } " + "}"); + ParseProtoAndAddToDb( + "name: 'bar.proto' " + "package: 'protobuf_unittest' " + "dependency: 'baz.proto' " + "message_type { " + " name:'Bar' " + " field { name:'baz' number:1 label:LABEL_OPTIONAL " + "type_name:'.protobuf_unittest.Baz' } " + "}"); + AddSimpleMessageProtoFileToDb("baz", "Baz"); + + const FileDescriptor* foo_file = pool_.FindFileByName("foo.proto"); + EXPECT_TRUE(foo_file != NULL); + // As expected, requesting foo.proto shouldn't build it's dependencies + EXPECT_TRUE(pool_.InternalIsFileLoaded("foo.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("bar.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto")); + + // Verify calling dependency(N) will build the dependency, but + // not that file's dependencies. + const FileDescriptor* bar_file = foo_file->dependency(0); + EXPECT_TRUE(bar_file != NULL); + EXPECT_TRUE(pool_.InternalIsFileLoaded("bar.proto")); + EXPECT_FALSE(pool_.InternalIsFileLoaded("baz.proto")); +} + +// =================================================================== + } // namespace descriptor_unittest } // namespace protobuf diff --git a/src/google/protobuf/duration.pb.cc b/src/google/protobuf/duration.pb.cc index e046cc5a..ae1a5e08 100644 --- a/src/google/protobuf/duration.pb.cc +++ b/src/google/protobuf/duration.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, seconds_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Duration, nanos_), }; @@ -186,7 +201,7 @@ void Duration::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Duration::descriptor() { protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Duration& Duration::default_instance() { @@ -266,6 +281,9 @@ failure: void Duration::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Duration) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 seconds = 1; if (this->seconds() != 0) { ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output); @@ -281,8 +299,10 @@ void Duration::SerializeWithCachedSizes( ::google::protobuf::uint8* Duration::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Duration) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 seconds = 1; if (this->seconds() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target); @@ -341,6 +361,9 @@ void Duration::MergeFrom(const Duration& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Duration) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.seconds() != 0) { set_seconds(from.seconds()); } @@ -394,7 +417,7 @@ void Duration::InternalSwap(Duration* other) { ::google::protobuf::Metadata Duration::GetMetadata() const { protobuf_google_2fprotobuf_2fduration_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fduration_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 591c11d1..9de33fea 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fduration_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -78,6 +82,8 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot return reinterpret_cast( &_Duration_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void UnsafeArenaSwap(Duration* other); void Swap(Duration* other); @@ -101,11 +107,6 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -154,7 +155,7 @@ class LIBPROTOBUF_EXPORT Duration : public ::google::protobuf::Message /* @@prot ::google::protobuf::int64 seconds_; ::google::protobuf::int32 nanos_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fduration_2eproto::TableStruct; }; // =================================================================== diff --git a/src/google/protobuf/duration.proto b/src/google/protobuf/duration.proto index 7f461f40..975fce41 100644 --- a/src/google/protobuf/duration.proto +++ b/src/google/protobuf/duration.proto @@ -47,6 +47,8 @@ option objc_class_prefix = "GPB"; // two Timestamp values is a Duration and it can be added or subtracted // from a Timestamp. Range is approximately +-10,000 years. // +// # Examples +// // Example 1: Compute Duration from two Timestamps in pseudo code. // // Timestamp start = ...; @@ -87,11 +89,22 @@ option objc_class_prefix = "GPB"; // duration = Duration() // duration.FromTimedelta(td) // +// # JSON Mapping +// +// In JSON format, the Duration type is encoded as a string rather than an +// object, where the string ends in the suffix "s" (indicating seconds) and +// is preceded by the number of seconds, with nanoseconds expressed as +// fractional seconds. For example, 3 seconds with 0 nanoseconds should be +// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should +// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 +// microsecond should be expressed in JSON format as "3.000001s". +// // message Duration { // Signed seconds of the span of time. Must be from -315,576,000,000 - // to +315,576,000,000 inclusive. + // to +315,576,000,000 inclusive. Note: these bounds are computed from: + // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years int64 seconds = 1; // Signed fractions of a second at nanosecond resolution of the span diff --git a/src/google/protobuf/dynamic_message.cc b/src/google/protobuf/dynamic_message.cc index d6bde495..ee8113e3 100644 --- a/src/google/protobuf/dynamic_message.cc +++ b/src/google/protobuf/dynamic_message.cc @@ -77,13 +77,14 @@ #include #include #include +#include +#include #include +#include #include #include -#include -#include #include -#include + namespace google { namespace protobuf { @@ -239,6 +240,7 @@ class DynamicMessage : public Message { // looking back at this field. This would assume details about the // implementation of scoped_ptr. const DynamicMessage* prototype; + int weak_field_map_offset; // The offset for the weak_field_map; TypeInfo() : prototype(NULL) {} @@ -323,7 +325,6 @@ void DynamicMessage::SharedCtor() { // constructor.) const Descriptor* descriptor = type_info_->type; - // Initialize oneof cases. for (int i = 0 ; i < descriptor->oneof_decl_count(); ++i) { new (OffsetToPointer(type_info_->oneof_case_offset + sizeof(uint32) * i)) @@ -336,7 +337,6 @@ void DynamicMessage::SharedCtor() { if (type_info_->extensions_offset != -1) { new (OffsetToPointer(type_info_->extensions_offset)) ExtensionSet; } - for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); @@ -537,7 +537,6 @@ void DynamicMessage::CrossLinkPrototypes() { for (int i = 0; i < descriptor->field_count(); i++) { const FieldDescriptor* field = descriptor->field(i); void* field_ptr = OffsetToPointer(type_info_->offsets[i]); - if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !field->is_repeated()) { // For fields with message types, we need to cross-link with the @@ -694,6 +693,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( // All the fields. // // TODO(b/31226269): Optimize the order of fields to minimize padding. + int num_weak_fields = 0; for (int i = 0; i < type->field_count(); i++) { // Make sure field is aligned to avoid bus errors. // Oneof fields do not use any space. @@ -717,6 +717,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->internal_metadata_offset = size; size += sizeof(InternalMetadataWithArena); + type_info->weak_field_map_offset = -1; + // Align the final size to make sure no clever allocators think that // alignment is not necessary. type_info->size = size; @@ -738,7 +740,6 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( } } size = AlignOffset(size); - // Allocate the prototype + oneof fields. void* base = operator new(size); memset(base, 0, size); @@ -752,7 +753,7 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->prototype = static_cast(base); DynamicMessage* prototype = new(base) DynamicMessage(type_info); - if (type->oneof_decl_count() > 0) { + if (type->oneof_decl_count() > 0 || num_weak_fields > 0) { // Construct default oneof instance. ConstructDefaultOneofInstance(type_info->type, type_info->offsets.get(), @@ -767,7 +768,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( type_info->internal_metadata_offset, type_info->extensions_offset, type_info->oneof_case_offset, - type_info->size}; + type_info->size, + type_info->weak_field_map_offset}; type_info->reflection.reset(new GeneratedMessageReflection( type_info->type, schema, type_info->pool, this)); @@ -781,12 +783,12 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock( void DynamicMessageFactory::ConstructDefaultOneofInstance( const Descriptor* type, const uint32 offsets[], - void* default_oneof_instance) { + void* default_oneof_or_weak_instance) { for (int i = 0; i < type->oneof_decl_count(); i++) { for (int j = 0; j < type->oneof_decl(i)->field_count(); j++) { const FieldDescriptor* field = type->oneof_decl(i)->field(j); void* field_ptr = reinterpret_cast( - default_oneof_instance) + offsets[field->index()]; + default_oneof_or_weak_instance) + offsets[field->index()]; switch (field->cpp_type()) { #define HANDLE_TYPE(CPPTYPE, TYPE) \ case FieldDescriptor::CPPTYPE_##CPPTYPE: \ diff --git a/src/google/protobuf/empty.pb.cc b/src/google/protobuf/empty.pb.cc index 31cba097..71195056 100644 --- a/src/google/protobuf/empty.pb.cc +++ b/src/google/protobuf/empty.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Empty, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { @@ -176,7 +191,7 @@ void Empty::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Empty::descriptor() { protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Empty& Empty::default_instance() { @@ -221,13 +236,18 @@ failure: void Empty::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Empty) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // @@protoc_insertion_point(serialize_end:google.protobuf.Empty) } ::google::protobuf::uint8* Empty::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Empty) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Empty) return target; } @@ -262,6 +282,9 @@ void Empty::MergeFrom(const Empty& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Empty) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + } void Empty::CopyFrom(const ::google::protobuf::Message& from) { @@ -307,7 +330,7 @@ void Empty::InternalSwap(Empty* other) { ::google::protobuf::Metadata Empty::GetMetadata() const { protobuf_google_2fprotobuf_2fempty_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fempty_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index a75d6dd6..2c599554 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fempty_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -78,6 +82,8 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast( &_Empty_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void UnsafeArenaSwap(Empty* other); void Swap(Empty* other); @@ -101,11 +107,6 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -140,7 +141,7 @@ class LIBPROTOBUF_EXPORT Empty : public ::google::protobuf::Message /* @@protoc_ typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fempty_2eproto::TableStruct; }; // =================================================================== diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index f5aa8de9..cb8ed217 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -416,7 +416,8 @@ class LIBPROTOBUF_EXPORT ExtensionSet { uint8* target) const; // For backward-compatibility, versions of two of the above methods that - // are never forced to serialize deterministically. + // serialize deterministically iff SetDefaultSerializationDeterministic() + // has been called. uint8* SerializeWithCachedSizesToArray(int start_field_number, int end_field_number, uint8* target) const; @@ -435,7 +436,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // be linked in). It's up to the protocol compiler to avoid calling this on // such ExtensionSets (easy enough since lite messages don't implement // SpaceUsed()). - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::FromIntSize(SpaceUsedExcludingSelfLong()); + } private: @@ -457,7 +462,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { virtual bool IsInitialized() const = 0; virtual int ByteSize() const = 0; - virtual int SpaceUsed() const = 0; + virtual size_t SpaceUsedLong() const = 0; virtual void MergeFrom(const LazyMessageExtension& other) = 0; virtual void Clear() = 0; @@ -556,7 +561,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { void Clear(); int GetSize() const; void Free(); - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; }; typedef std::map ExtensionMap; @@ -620,7 +625,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // class. // Defined in extension_set_heavy.cc. - static inline int RepeatedMessage_SpaceUsedExcludingSelf( + static inline size_t RepeatedMessage_SpaceUsedExcludingSelfLong( RepeatedPtrFieldBase* field); // The Extension struct is small enough to be passed by value, so we use it @@ -1100,7 +1105,7 @@ template inline // parameter, and thus make an instance of ExtensionIdentifier have no // actual contents. However, if we did that, then using at extension // identifier would not necessarily cause the compiler to output any sort -// of reference to any simple defined in the extension's .pb.o file. Some +// of reference to any symbol defined in the extension's .pb.o file. Some // linkers will actually drop object files that are not explicitly referenced, // but that would be bad because it would cause this extension to not be // registered at static initialization, and therefore using it would crash. diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 8f8f180a..3649104f 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -340,32 +340,32 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, } } -int ExtensionSet::SpaceUsedExcludingSelf() const { - int total_size = +size_t ExtensionSet::SpaceUsedExcludingSelfLong() const { + size_t total_size = extensions_.size() * sizeof(ExtensionMap::value_type); for (ExtensionMap::const_iterator iter = extensions_.begin(), end = extensions_.end(); iter != end; ++iter) { - total_size += iter->second.SpaceUsedExcludingSelf(); + total_size += iter->second.SpaceUsedExcludingSelfLong(); } return total_size; } -inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf( +inline size_t ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelfLong( RepeatedPtrFieldBase* field) { - return field->SpaceUsedExcludingSelf >(); + return field->SpaceUsedExcludingSelfLong >(); } -int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { - int total_size = 0; +size_t ExtensionSet::Extension::SpaceUsedExcludingSelfLong() const { + size_t total_size = 0; if (is_repeated) { switch (cpp_type(type)) { -#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ - case FieldDescriptor::CPPTYPE_##UPPERCASE: \ - total_size += sizeof(*repeated_##LOWERCASE##_value) + \ - repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\ - break +#define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ + case FieldDescriptor::CPPTYPE_##UPPERCASE: \ + total_size += sizeof(*repeated_##LOWERCASE##_value) + \ + repeated_##LOWERCASE##_value->SpaceUsedExcludingSelfLong(); \ + break HANDLE_TYPE( INT32, int32); HANDLE_TYPE( INT64, int64); @@ -380,24 +380,25 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const { case FieldDescriptor::CPPTYPE_MESSAGE: // repeated_message_value is actually a RepeatedPtrField, - // but MessageLite has no SpaceUsed(), so we must directly call - // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type - // handler. - total_size += sizeof(*repeated_message_value) + - RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value); + // but MessageLite has no SpaceUsedLong(), so we must directly call + // RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() with a different + // type handler. + total_size += + sizeof(*repeated_message_value) + + RepeatedMessage_SpaceUsedExcludingSelfLong(repeated_message_value); break; } } else { switch (cpp_type(type)) { case FieldDescriptor::CPPTYPE_STRING: total_size += sizeof(*string_value) + - StringSpaceUsedExcludingSelf(*string_value); + StringSpaceUsedExcludingSelfLong(*string_value); break; case FieldDescriptor::CPPTYPE_MESSAGE: if (is_lazy) { - total_size += lazymessage_value->SpaceUsed(); + total_size += lazymessage_value->SpaceUsedLong(); } else { - total_size += down_cast(message_value)->SpaceUsed(); + total_size += down_cast(message_value)->SpaceUsedLong(); } break; default: diff --git a/src/google/protobuf/extension_set_unittest.cc b/src/google/protobuf/extension_set_unittest.cc index d6b823c0..772d2734 100644 --- a/src/google/protobuf/extension_set_unittest.cc +++ b/src/google/protobuf/extension_set_unittest.cc @@ -32,6 +32,7 @@ // Based on original Protocol Buffers design by // Sanjay Ghemawat, Jeff Dean, and others. +#include #include #include #include @@ -46,7 +47,6 @@ #include #include -#include #include #include #include diff --git a/src/google/protobuf/field_mask.pb.cc b/src/google/protobuf/field_mask.pb.cc index b054dffd..094c4cc9 100644 --- a/src/google/protobuf/field_mask.pb.cc +++ b/src/google/protobuf/field_mask.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldMask, paths_), }; @@ -159,7 +174,7 @@ void FieldMask::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FieldMask::descriptor() { protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FieldMask& FieldMask::default_instance() { @@ -231,6 +246,9 @@ failure: void FieldMask::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FieldMask) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated string paths = 1; for (int i = 0, n = this->paths_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -246,8 +264,10 @@ void FieldMask::SerializeWithCachedSizes( ::google::protobuf::uint8* FieldMask::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FieldMask) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated string paths = 1; for (int i = 0, n = this->paths_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -300,6 +320,9 @@ void FieldMask::MergeFrom(const FieldMask& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FieldMask) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + paths_.MergeFrom(from.paths_); } @@ -326,13 +349,13 @@ void FieldMask::Swap(FieldMask* other) { InternalSwap(other); } void FieldMask::InternalSwap(FieldMask* other) { - paths_.UnsafeArenaSwap(&other->paths_); + paths_.InternalSwap(&other->paths_); std::swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata FieldMask::GetMetadata() const { protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -364,6 +387,7 @@ void FieldMask::set_paths(int index, ::std::string&& value) { } #endif void FieldMask::set_paths(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); paths_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths) } @@ -382,11 +406,12 @@ void FieldMask::add_paths(const ::std::string& value) { } #if LANG_CXX11 void FieldMask::add_paths(::std::string&& value) { - paths_.Add()->assign(std::move(value)); + paths_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) } #endif void FieldMask::add_paths(const char* value) { + GOOGLE_DCHECK(value != NULL); paths_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths) } diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index b609f235..ca2cb25b 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2ffield_5fmask_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -72,6 +76,8 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro return reinterpret_cast( &_FieldMask_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void Swap(FieldMask* other); @@ -94,11 +100,6 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -148,7 +149,7 @@ class LIBPROTOBUF_EXPORT FieldMask : public ::google::protobuf::Message /* @@pro ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::RepeatedPtrField< ::std::string> paths_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ffield_5fmask_2eproto::TableStruct; }; // =================================================================== @@ -184,6 +185,7 @@ inline void FieldMask::set_paths(int index, ::std::string&& value) { } #endif inline void FieldMask::set_paths(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); paths_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.FieldMask.paths) } @@ -202,11 +204,12 @@ inline void FieldMask::add_paths(const ::std::string& value) { } #if LANG_CXX11 inline void FieldMask::add_paths(::std::string&& value) { - paths_.Add()->assign(std::move(value)); + paths_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.FieldMask.paths) } #endif inline void FieldMask::add_paths(const char* value) { + GOOGLE_DCHECK(value != NULL); paths_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.FieldMask.paths) } diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 2f8f8256..9aebd901 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -190,7 +190,9 @@ GeneratedMessageReflection::GeneratedMessageReflection( schema_(schema), descriptor_pool_((pool == NULL) ? DescriptorPool::generated_pool() : pool), - message_factory_(factory) { + message_factory_(factory), + last_non_weak_field_index_(-1) { + last_non_weak_field_index_ = descriptor_->field_count() - 1; } GeneratedMessageReflection::~GeneratedMessageReflection() {} @@ -231,28 +233,25 @@ UnknownFieldSet* GeneratedMessageReflection::MutableUnknownFields( return MutableInternalMetadataWithArena(message)->mutable_unknown_fields(); } -int GeneratedMessageReflection::SpaceUsed(const Message& message) const { +size_t GeneratedMessageReflection::SpaceUsedLong(const Message& message) const { // object_size_ already includes the in-memory representation of each field // in the message, so we only need to account for additional memory used by // the fields. - int total_size = schema_.GetObjectSize(); + size_t total_size = schema_.GetObjectSize(); - total_size += GetUnknownFields(message).SpaceUsedExcludingSelf(); + total_size += GetUnknownFields(message).SpaceUsedExcludingSelfLong(); if (schema_.HasExtensionSet()) { - total_size += GetExtensionSet(message).SpaceUsedExcludingSelf(); + total_size += GetExtensionSet(message).SpaceUsedExcludingSelfLong(); } - - const int field_count = descriptor_->field_count(); - for (int i = 0; i < field_count; i++) { + for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->is_repeated()) { switch (field->cpp_type()) { #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \ case FieldDescriptor::CPPTYPE_##UPPERCASE : \ total_size += GetRaw >(message, field) \ - .SpaceUsedExcludingSelf(); \ + .SpaceUsedExcludingSelfLong(); \ break HANDLE_TYPE( INT32, int32); @@ -270,21 +269,21 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { default: // TODO(kenton): Support other string reps. case FieldOptions::STRING: total_size += GetRaw >(message, field) - .SpaceUsedExcludingSelf(); + .SpaceUsedExcludingSelfLong(); break; } break; case FieldDescriptor::CPPTYPE_MESSAGE: if (IsMapFieldInApi(field)) { - total_size += - GetRaw(message, field).SpaceUsedExcludingSelf(); + total_size += GetRaw(message, field) + .SpaceUsedExcludingSelfLong(); } else { // We don't know which subclass of RepeatedPtrFieldBase the type is, // so we use RepeatedPtrFieldBase directly. total_size += GetRaw(message, field) - .SpaceUsedExcludingSelf >(); + .SpaceUsedExcludingSelfLong >(); } break; @@ -320,7 +319,8 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { if (ptr != default_ptr) { // string fields are represented by just a pointer, so also // include sizeof(string) as well. - total_size += sizeof(*ptr) + StringSpaceUsedExcludingSelf(*ptr); + total_size += + sizeof(*ptr) + StringSpaceUsedExcludingSelfLong(*ptr); } break; } @@ -335,14 +335,13 @@ int GeneratedMessageReflection::SpaceUsed(const Message& message) const { } else { const Message* sub_message = GetRaw(message, field); if (sub_message != NULL) { - total_size += sub_message->SpaceUsed(); + total_size += sub_message->SpaceUsedLong(); } } break; } } } - return total_size; } @@ -643,14 +642,11 @@ void GeneratedMessageReflection::Swap( } } - const int field_count = descriptor_->field_count(); - for (int i = 0; i < field_count; i++) { + for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); - if (!field->containing_oneof()) { - SwapField(message1, message2, field); - } + if (field->containing_oneof()) continue; + SwapField(message1, message2, field); } - const int oneof_decl_count = descriptor_->oneof_decl_count(); for (int i = 0; i < oneof_decl_count; i++) { SwapOneofField(message1, message2, descriptor_->oneof_decl(i)); @@ -782,7 +778,6 @@ void GeneratedMessageReflection::ClearField( ClearOneofField(message, field); return; } - if (HasBit(*message, field)) { ClearBit(message, field); @@ -1026,10 +1021,8 @@ void GeneratedMessageReflection::ListFields( const uint32* const has_bits_indices = schema_.has_bit_indices_; const uint32* const oneof_case_array = &GetConstRefAtOffset(message, schema_.oneof_case_offset_); - - const int field_count = descriptor_->field_count(); - output->reserve(field_count); - for (int i = 0; i < field_count; i++) { + output->reserve(descriptor_->field_count()); + for (int i = 0; i <= last_non_weak_field_index_; i++) { const FieldDescriptor* field = descriptor_->field(i); if (field->is_repeated()) { if (FieldSize(message, field) > 0) { @@ -1052,7 +1045,6 @@ void GeneratedMessageReflection::ListFields( } } } - if (schema_.HasExtensionSet()) { GetExtensionSet(message).AppendToList(descriptor_, descriptor_pool_, output); @@ -1458,8 +1450,7 @@ const Message& GeneratedMessageReflection::GetMessage( GetExtensionSet(message).GetMessage( field->number(), field->message_type(), factory)); } else { - const Message* result; - result = GetRaw(message, field); + const Message* result = GetRaw(message, field); if (result == NULL) { result = DefaultRaw(field); } @@ -1479,6 +1470,7 @@ Message* GeneratedMessageReflection::MutableMessage( MutableExtensionSet(message)->MutableMessage(field, factory)); } else { Message* result; + Message** result_holder = MutableRaw(message, field); if (field->containing_oneof()) { @@ -1976,6 +1968,7 @@ inline const Type& GeneratedMessageReflection::DefaultRaw( // Simple accessors for manipulating has_bits_. inline bool GeneratedMessageReflection::HasBit( const Message& message, const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); if (schema_.HasHasbits()) { return IsIndexInHasBitSet(GetHasBits(message), schema_.HasBitIndex(field)); } @@ -2031,6 +2024,7 @@ inline bool GeneratedMessageReflection::HasBit( inline void GeneratedMessageReflection::SetBit( Message* message, const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); if (!schema_.HasHasbits()) { return; } @@ -2041,6 +2035,7 @@ inline void GeneratedMessageReflection::SetBit( inline void GeneratedMessageReflection::ClearBit( Message* message, const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); if (!schema_.HasHasbits()) { return; } @@ -2051,6 +2046,7 @@ inline void GeneratedMessageReflection::ClearBit( inline void GeneratedMessageReflection::SwapBit( Message* message1, Message* message2, const FieldDescriptor* field) const { + GOOGLE_DCHECK(!field->options().weak()); if (!schema_.HasHasbits()) { return; } @@ -2236,16 +2232,16 @@ ReflectionSchema MigrationToReflectionSchema( MigrationSchema migration_schema) { ReflectionSchema result; result.default_instance_ = *default_instance; - // First 5 offsets are offsets to the special fields. The following offsets + // First 6 offsets are offsets to the special fields. The following offsets // are the proto fields. - result.offsets_ = offsets + migration_schema.offsets_index + 4; + result.offsets_ = offsets + migration_schema.offsets_index + 5; result.has_bit_indices_ = offsets + migration_schema.has_bit_indices_index; result.has_bits_offset_ = offsets[migration_schema.offsets_index + 0]; result.metadata_offset_ = offsets[migration_schema.offsets_index + 1]; result.extensions_offset_ = offsets[migration_schema.offsets_index + 2]; result.oneof_case_offset_ = offsets[migration_schema.offsets_index + 3]; result.object_size_ = migration_schema.object_size; - result.weak_field_map_offset_ = 0; + result.weak_field_map_offset_ = offsets[migration_schema.offsets_index + 4]; return result; } @@ -2275,7 +2271,7 @@ class AssignDescriptorsHelper { if (!descriptor->options().map_entry()) { // Only set reflection for non map types. file_level_metadata_->reflection = new GeneratedMessageReflection( - descriptor, MigrationToReflectionSchema(default_instance_data_++, + descriptor, MigrationToReflectionSchema(default_instance_data_, offsets_, *schemas_), ::google::protobuf::DescriptorPool::generated_pool(), factory_); for (int i = 0; i < descriptor->enum_type_count(); i++) { @@ -2283,6 +2279,7 @@ class AssignDescriptorsHelper { } schemas_++; } + default_instance_data_++; file_level_metadata_++; } diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index 8b1362a2..b4fdbb11 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -62,7 +62,15 @@ namespace protobuf { class DescriptorPool; class MapKey; class MapValueRef; -} +} // namespace protobuf + + +namespace protobuf { +namespace flat { +class MetadataBuilder; +} // namespace flat +} // namespace protobuf + namespace protobuf { namespace internal { @@ -73,6 +81,7 @@ class GeneratedMessageReflection; // Defined in other files. class ExtensionSet; // extension_set.h +class WeakFieldMap; // weak_field_map.h // This struct describes the internal layout of the message, hence this is // used to act on the message reflectively. @@ -83,17 +92,17 @@ class ExtensionSet; // extension_set.h // embedded message fields *must* have non-NULL pointers // in the default instance.) // offsets: An array of ints giving the byte offsets. -// For each oneof field, the offset is relative to the -// default_oneof_instance. These can be computed at compile -// time using the -// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() macro. -// For each none oneof field, the offset is related to -// the start of the message object. These can be computed -// at compile time using the +// For each oneof or weak field, the offset is relative to the +// default_instance. These can be computed at compile time +// using the +// GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET() +// macro. For each none oneof field, the offset is related to +// the start of the message object. These can be computed at +// compile time using the // GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET() macro. // Besides offsets for all fields, this array also contains -// offsets for oneof unions. The offset of the i-th oneof -// union is offsets[descriptor->field_count() + i]. +// offsets for oneof unions. The offset of the i-th oneof union +// is offsets[descriptor->field_count() + i]. // has_bit_indices: Mapping from field indexes to their index in the has // bit array. // has_bits_offset: Offset in the message of an array of uint32s of size @@ -114,6 +123,9 @@ class ExtensionSet; // extension_set.h // by sizeof(). // arena_offset: If a message doesn't have a unknown_field_set that stores // the arena, it must have a direct pointer to the arena. +// weak_field_map_offset: If the message proto has weak fields, this is the +// offset of _weak_field_map_ in the generated proto. Otherwise +// -1. struct ReflectionSchema { public: // Size of a google::protobuf::Message object of this type. @@ -187,6 +199,9 @@ struct ReflectionSchema { offsets_[field->index()]; } + + bool HasWeakFields() const { return weak_field_map_offset_ > 0; } + // These members are intended to be private, but we cannot actually make them // private because this prevents us from using aggregate initialization of // them, ie. @@ -240,8 +255,7 @@ struct MigrationSchema { // of whatever type the individual field would be. Strings and // Messages use RepeatedPtrFields while everything else uses // RepeatedFields. -class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL - : public Reflection { +class GeneratedMessageReflection PROTOBUF_FINAL : public Reflection { public: // Constructs a GeneratedMessageReflection. // Parameters: @@ -263,7 +277,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL const UnknownFieldSet& GetUnknownFields(const Message& message) const; UnknownFieldSet* MutableUnknownFields(Message* message) const; - int SpaceUsed(const Message& message) const; + size_t SpaceUsedLong(const Message& message) const; bool HasField(const Message& message, const FieldDescriptor* field) const; int FieldSize(const Message& message, const FieldDescriptor* field) const; @@ -481,7 +495,7 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL const Descriptor* message_type) const; private: - friend class GeneratedMessage; + friend class google::protobuf::flat::MetadataBuilder; friend class upb::google_opensource::GMR_Handlers; const Descriptor* const descriptor_; @@ -489,6 +503,11 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL const DescriptorPool* const descriptor_pool_; MessageFactory* const message_factory_; + // Last non weak field index. This is an optimization when most weak fields + // are at the end of the containing message. If a message proto doesn't + // contain weak fields, then this field equals descriptor_->field_count(). + int last_non_weak_field_index_; + template const T& GetRawNonOneof(const Message& message, const FieldDescriptor* field) const; @@ -614,40 +633,6 @@ class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection); }; -// Returns the offset of the given field within the given aggregate type. -// This is equivalent to the ANSI C offsetof() macro. However, according -// to the C++ standard, offsetof() only works on POD types, and GCC -// enforces this requirement with a warning. In practice, this rule is -// unnecessarily strict; there is probably no compiler or platform on -// which the offsets of the direct fields of a class are non-constant. -// Fields inherited from superclasses *can* have non-constant offsets, -// but that's not what this macro will be used for. -#if defined(__clang__) -// For Clang we use __builtin_offsetof() and suppress the warning, -// to avoid Control Flow Integrity and UBSan vptr sanitizers from -// crashing while trying to validate the invalid reinterpet_casts. -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ - __builtin_offsetof(TYPE, FIELD) \ - _Pragma("clang diagnostic pop") -#else -// Note that we calculate relative to the pointer value 16 here since if we -// just use zero, GCC complains about dereferencing a NULL pointer. We -// choose 16 rather than some other number just in case the compiler would -// be confused by an unaligned pointer. -#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ - static_cast< ::google::protobuf::uint32>( \ - reinterpret_cast( \ - &reinterpret_cast(16)->FIELD) - \ - reinterpret_cast(16)) -#endif - -#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ - static_cast< ::google::protobuf::uint32>( \ - reinterpret_cast(&(ONEOF->FIELD)) \ - - reinterpret_cast(ONEOF)) - // There are some places in proto2 where dynamic_cast would be useful as an // optimization. For example, take Message::MergeFrom(const Message& other). // For a given generated message FooMessage, we generate these two methods: diff --git a/src/google/protobuf/generated_message_table_driven.cc b/src/google/protobuf/generated_message_table_driven.cc new file mode 100644 index 00000000..e281266d --- /dev/null +++ b/src/google/protobuf/generated_message_table_driven.cc @@ -0,0 +1,676 @@ +// 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 + +#include + +#include +#include +#include +#include +#include + + +namespace google { +namespace protobuf { +namespace internal { + + +namespace { + +enum StringType { + StringType_STRING = 0, + StringType_CORD = 1, + StringType_STRING_PIECE = 2 +}; + +template +inline Type* Raw(MessageLite* msg, int64 offset) { + return reinterpret_cast(reinterpret_cast(msg) + offset); +} + +template +inline const Type* Raw(const MessageLite* msg, int64 offset) { + return reinterpret_cast(reinterpret_cast(msg) + + offset); +} + +inline Arena* GetArena(MessageLite* msg, int64 arena_offset) { + if (GOOGLE_PREDICT_FALSE(arena_offset == -1)) { + return NULL; + } + + return Raw(msg, arena_offset)->arena(); +} + +template +inline Type* AddField(MessageLite* msg, int64 offset) { +#if LANG_CXX11 + static_assert(std::is_trivially_copy_assignable::value, + "Do not assign"); +#endif + + google::protobuf::RepeatedField* repeated = + Raw >(msg, offset); + return repeated->Add(); +} + +template <> +inline string* AddField(MessageLite* msg, int64 offset) { + google::protobuf::RepeatedPtrField* repeated = + Raw >(msg, offset); + return repeated->Add(); +} + + +template +inline void AddField(MessageLite* msg, int64 offset, Type value) { +#if LANG_CXX11 + static_assert(std::is_trivially_copy_assignable::value, + "Do not assign"); +#endif + *AddField(msg, offset) = value; +} + +inline void SetBit(uint32* has_bits, uint32 has_bit_index) { + GOOGLE_DCHECK(has_bits != NULL); + + uint32 mask = static_cast(1u) << (has_bit_index % 32); + has_bits[has_bit_index / 32u] |= mask; +} + +template +inline Type* MutableField(MessageLite* msg, uint32* has_bits, + uint32 has_bit_index, int64 offset) { + SetBit(has_bits, has_bit_index); + return Raw(msg, offset); +} + +template +inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index, + int64 offset, Type value) { +#if LANG_CXX11 + static_assert(std::is_trivially_copy_assignable::value, + "Do not assign"); +#endif + *MutableField(msg, has_bits, has_bit_index, offset) = value; +} + +template +static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg, + Arena* arena, uint32* has_bits, + uint32 has_bit_index, int64 offset, + const void* default_ptr, bool strict_utf8, + const char* field_name) { +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + const char* sdata; + size_t size; +#endif + + string* value; + if (repeated) { + value = AddField(msg, offset); + GOOGLE_DCHECK(value != NULL); + } else { + // TODO(ckennelly): Is this optimal? + value = MutableField(msg, has_bits, has_bit_index, offset) + ->Mutable(static_cast(default_ptr), arena); + GOOGLE_DCHECK(value != NULL); + } + + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::ReadString(input, value))) { + return false; + } + +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + sdata = value->data(); + size = value->size(); +#endif + +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + if (validate) { + if (strict_utf8) { + if (GOOGLE_PREDICT_FALSE(!WireFormatLite::VerifyUtf8String( + sdata, size, WireFormatLite::PARSE, field_name))) { + return false; + } + } else { + WireFormatLite::VerifyUTF8String( + sdata, size, WireFormat::PARSE, field_name); + } + } +#endif + + return true; +} + +string* MutableUnknownFields(MessageLite* msg, int64 arena_offset) { + return Raw(msg, arena_offset) + ->mutable_unknown_fields(); +} + +// RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields +// without instantiating the specific template. +class RepeatedMessageTypeHandler { + public: + typedef MessageLite Type; + static Arena* GetArena(Type* t) { return t->GetArena(); } + static void* GetMaybeArenaPointer(Type* t) { + return t->GetMaybeArenaPointer(); + } + static inline Type* NewFromPrototype(const Type* prototype, + Arena* arena = NULL) { + return prototype->New(arena); + } + static void Delete(Type* t, Arena* arena = NULL) { + if (arena == NULL) { + delete t; + } + } +}; + +inline bool ReadGroup(int field_number, io::CodedInputStream* input, + MessageLite* value, const ParseTable& table) { + if (GOOGLE_PREDICT_FALSE(!input->IncrementRecursionDepth())) { + return false; + } + + if (GOOGLE_PREDICT_FALSE(!MergePartialFromCodedStream(value, table, input))) { + return false; + } + + input->DecrementRecursionDepth(); + // Make sure the last thing read was an end tag for this group. + if (GOOGLE_PREDICT_FALSE(!input->LastTagWas(WireFormatLite::MakeTag( + field_number, WireFormatLite::WIRETYPE_END_GROUP)))) { + return false; + } + + return true; +} + +inline bool ReadMessage(io::CodedInputStream* input, MessageLite* value, + const ParseTable& table) { + int length; + if (GOOGLE_PREDICT_FALSE(!input->ReadVarintSizeAsInt(&length))) { + return false; + } + + std::pair p = + input->IncrementRecursionDepthAndPushLimit(length); + if (GOOGLE_PREDICT_FALSE(p.second < 0 || + !MergePartialFromCodedStream(value, table, input))) { + return false; + } + + // Make sure that parsing stopped when the limit was hit, not at an endgroup + // tag. + return input->DecrementRecursionDepthAndPopLimit(p.first); +} + +} // namespace + +class MergePartialFromCodedStreamHelper { + public: + static MessageLite* Add(RepeatedPtrFieldBase* field, + const MessageLite* prototype) { + return field->Add( + const_cast(prototype)); + } +}; + +bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input) { + // We require that has_bits are present, as to avoid having to check for them + // for every field. + // + // TODO(ckennelly): Make this a compile-time parameter with templates. + GOOGLE_DCHECK_GE(table.has_bits_offset, 0); + uint32* has_bits = Raw(msg, table.has_bits_offset); + GOOGLE_DCHECK(has_bits != NULL); + + while (true) { + uint32 tag = input->ReadTag(); + + const WireFormatLite::WireType wire_type = + WireFormatLite::GetTagWireType(tag); + const int field_number = WireFormatLite::GetTagFieldNumber(tag); + + if (GOOGLE_PREDICT_FALSE(field_number > table.max_field_number)) { + GOOGLE_DCHECK(!table.unknown_field_set); + ::google::protobuf::io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string, false); + + if (!::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)) { + return false; + } + + continue; + } + + // We implicitly verify that data points to a valid field as we check the + // wire types. Entries in table.fields[i] that do not correspond to valid + // field numbers have their normal_wiretype and packed_wiretype fields set + // with the kInvalidMask value. As wire_type cannot take on that value, we + // will never match. + const ParseTableField* data = table.fields + field_number; + + // TODO(ckennelly): Avoid sign extension + const int64 has_bit_index = data->has_bit_index; + const int64 offset = data->offset; + const unsigned char processing_type = data->processing_type; + + if (data->normal_wiretype == static_cast(wire_type)) { + // TODO(ckennelly): Use a computed goto on GCC/LLVM or otherwise eliminate + // the bounds check on processing_type. + + switch (processing_type) { +#define STR(S) #S +#define HANDLE_TYPE(TYPE, CPPTYPE) \ + case (WireFormatLite::TYPE_##TYPE): { \ + CPPTYPE value; \ + if (GOOGLE_PREDICT_FALSE( \ + (!WireFormatLite::ReadPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \ + return false; \ + } \ + SetField(msg, has_bits, has_bit_index, offset, value); \ + break; \ + } \ + case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \ + google::protobuf::RepeatedField* values = \ + Raw >(msg, offset); \ + if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>( \ + data->tag_size, tag, input, values)))) { \ + return false; \ + } \ + break; \ + } + + HANDLE_TYPE(INT32, int32) + HANDLE_TYPE(INT64, int64) + HANDLE_TYPE(SINT32, int32) + HANDLE_TYPE(SINT64, int64) + HANDLE_TYPE(UINT32, uint32) + HANDLE_TYPE(UINT64, uint64) + + HANDLE_TYPE(FIXED32, uint32) + HANDLE_TYPE(FIXED64, uint64) + HANDLE_TYPE(SFIXED32, int32) + HANDLE_TYPE(SFIXED64, int64) + + HANDLE_TYPE(FLOAT, float) + HANDLE_TYPE(DOUBLE, double) + + HANDLE_TYPE(BOOL, bool) +#undef HANDLE_TYPE +#undef STR + case WireFormatLite::TYPE_BYTES: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case WireFormatLite::TYPE_STRING: +#endif + { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + + if (GOOGLE_PREDICT_FALSE((!HandleString( + input, msg, arena, has_bits, has_bit_index, offset, + default_ptr, false, NULL)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_BYTES) | kRepeatedMask: +#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: +#endif + { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const void* default_ptr = + table.aux[field_number].strings.default_ptr; + + if (GOOGLE_PREDICT_FALSE((!HandleString( + input, msg, arena, has_bits, has_bit_index, offset, + default_ptr, false, NULL)))) { + return false; + } + break; + } +#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED + case (WireFormatLite::TYPE_STRING): { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + const bool strict_utf8 = table.aux[field_number].strings.strict_utf8; + + if (GOOGLE_PREDICT_FALSE((!HandleString( + input, msg, arena, has_bits, has_bit_index, offset, + default_ptr, strict_utf8, field_name)))) { + return false; + } + break; + } + case (WireFormatLite::TYPE_STRING) | kRepeatedMask: { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const void* default_ptr = table.aux[field_number].strings.default_ptr; + const char* field_name = table.aux[field_number].strings.field_name; + const bool strict_utf8 = table.aux[field_number].strings.strict_utf8; + + if (GOOGLE_PREDICT_FALSE((!HandleString( + input, msg, arena, has_bits, has_bit_index, offset, + default_ptr, strict_utf8, field_name)))) { + return false; + } + break; + } +#endif + case WireFormatLite::TYPE_ENUM: { + int value; + if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)))) { + return false; + } + + AuxillaryParseTableField::EnumValidator validator = + table.aux[field_number].enums.validator; + if (validator(value)) { + SetField(msg, has_bits, has_bit_index, offset, value); + } else { + GOOGLE_DCHECK(!table.unknown_field_set); + + ::google::protobuf::io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string, false); + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + break; + } + case WireFormatLite::TYPE_ENUM | kRepeatedMask: { + int value; + if (GOOGLE_PREDICT_FALSE((!WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)))) { + return false; + } + + AuxillaryParseTableField::EnumValidator validator = + table.aux[field_number].enums.validator; + if (validator(value)) { + AddField(msg, offset, value); + } else { + GOOGLE_DCHECK(!table.unknown_field_set); + + ::google::protobuf::io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string, false); + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + + break; + } + case WireFormatLite::TYPE_GROUP: { + MessageLite** submsg_holder = + MutableField(msg, has_bits, has_bit_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == NULL) { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + const ParseTable* ptable = + table.aux[field_number].messages.parse_table; + + if (ptable) { + if (GOOGLE_PREDICT_FALSE( + !ReadGroup(field_number, input, submsg, *ptable))) { + return false; + } + } else if (!WireFormatLite::ReadGroup(field_number, input, submsg)) { + return false; + } + + break; + } + case WireFormatLite::TYPE_GROUP | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + GOOGLE_DCHECK(prototype != NULL); + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + const ParseTable* ptable = + table.aux[field_number].messages.parse_table; + + if (ptable) { + if (GOOGLE_PREDICT_FALSE( + !ReadGroup(field_number, input, submsg, *ptable))) { + return false; + } + } else if (!WireFormatLite::ReadGroup(field_number, input, submsg)) { + return false; + } + + break; + } + case WireFormatLite::TYPE_MESSAGE: { + MessageLite** submsg_holder = + MutableField(msg, has_bits, has_bit_index, offset); + MessageLite* submsg = *submsg_holder; + + if (submsg == NULL) { + GOOGLE_DCHECK(!table.unknown_field_set); + Arena* const arena = GetArena(msg, table.arena_offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + submsg = prototype->New(arena); + *submsg_holder = submsg; + } + + const ParseTable* ptable = + table.aux[field_number].messages.parse_table; + + if (ptable) { + if (GOOGLE_PREDICT_FALSE(!ReadMessage(input, submsg, *ptable))) { + return false; + } + } else if (!WireFormatLite::ReadMessage(input, submsg)) { + return false; + } + + break; + } + // TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and + // manage input->IncrementRecursionDepth() here. + case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: { + RepeatedPtrFieldBase* field = Raw(msg, offset); + const MessageLite* prototype = + table.aux[field_number].messages.default_message(); + GOOGLE_DCHECK(prototype != NULL); + + MessageLite* submsg = + MergePartialFromCodedStreamHelper::Add(field, prototype); + const ParseTable* ptable = + table.aux[field_number].messages.parse_table; + + if (ptable) { + if (GOOGLE_PREDICT_FALSE(!ReadMessage(input, submsg, *ptable))) { + return false; + } + } else if (!WireFormatLite::ReadMessage(input, submsg)) { + return false; + } + + break; + } + case 0: { + // Done. + return true; + } + default: + break; + } + } else if (data->packed_wiretype == static_cast(wire_type)) { + // Non-packable fields have their packed_wiretype masked with + // kNotPackedMask, which is impossible to match here. + GOOGLE_DCHECK(processing_type & kRepeatedMask); + GOOGLE_DCHECK_NE(processing_type, kRepeatedMask); + + + + // TODO(ckennelly): Use a computed goto on GCC/LLVM. + // + // Mask out kRepeatedMask bit, allowing the jump table to be smaller. + switch (static_cast( + processing_type ^ kRepeatedMask)) { +#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \ + case WireFormatLite::TYPE_##TYPE: { \ + google::protobuf::RepeatedField* values = \ + Raw >(msg, offset); \ + if (GOOGLE_PREDICT_FALSE( \ + (!WireFormatLite::ReadPackedPrimitive< \ + CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \ + return false; \ + } \ + break; \ + } + + HANDLE_PACKED_TYPE(INT32, int32, Int32) + HANDLE_PACKED_TYPE(INT64, int64, Int64) + HANDLE_PACKED_TYPE(SINT32, int32, Int32) + HANDLE_PACKED_TYPE(SINT64, int64, Int64) + HANDLE_PACKED_TYPE(UINT32, uint32, UInt32) + HANDLE_PACKED_TYPE(UINT64, uint64, UInt64) + + HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32) + HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64) + HANDLE_PACKED_TYPE(SFIXED32, int32, Int32) + HANDLE_PACKED_TYPE(SFIXED64, int64, Int64) + + HANDLE_PACKED_TYPE(FLOAT, float, Float) + HANDLE_PACKED_TYPE(DOUBLE, double, Double) + + HANDLE_PACKED_TYPE(BOOL, bool, Bool) +#undef HANDLE_PACKED_TYPE + case WireFormatLite::TYPE_ENUM: { + // To avoid unnecessarily calling MutableUnknownFields (which mutates + // InternalMetadataWithArena) when all inputs in the repeated series + // are valid, we implement our own parser rather than call + // WireFormat::ReadPackedEnumPreserveUnknowns. + uint32 length; + if (GOOGLE_PREDICT_FALSE(!input->ReadVarint32(&length))) { + return false; + } + + AuxillaryParseTableField::EnumValidator validator = + table.aux[field_number].enums.validator; + google::protobuf::RepeatedField* values = + Raw >(msg, offset); + string* unknown_fields = NULL; + + io::CodedInputStream::Limit limit = input->PushLimit(length); + while (input->BytesUntilLimit() > 0) { + int value; + if (GOOGLE_PREDICT_FALSE( + (!google::protobuf::internal::WireFormatLite::ReadPrimitive< + int, WireFormatLite::TYPE_ENUM>(input, &value)))) { + return false; + } + + if (validator(value)) { + values->Add(value); + } else { + if (GOOGLE_PREDICT_FALSE(unknown_fields == NULL)) { + GOOGLE_DCHECK(!table.unknown_field_set); + unknown_fields = MutableUnknownFields(msg, table.arena_offset); + } + + ::google::protobuf::io::StringOutputStream unknown_fields_string( + unknown_fields); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string, false); + unknown_fields_stream.WriteVarint32(tag); + unknown_fields_stream.WriteVarint32(value); + } + } + input->PopLimit(limit); + + break; + } + case WireFormatLite::TYPE_STRING: + case WireFormatLite::TYPE_GROUP: + case WireFormatLite::TYPE_MESSAGE: + case WireFormatLite::TYPE_BYTES: + GOOGLE_DCHECK(false); + return false; + default: + break; + } + } else { + if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) { + // Must be the end of the message. + return true; + } + + // process unknown field. + GOOGLE_DCHECK(!table.unknown_field_set); + ::google::protobuf::io::StringOutputStream unknown_fields_string( + MutableUnknownFields(msg, table.arena_offset)); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_string, false); + + if (!::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)) { + return false; + } + } + } +} + +} // namespace internal +} // namespace protobuf +} // namespace google diff --git a/src/google/protobuf/generated_message_table_driven.h b/src/google/protobuf/generated_message_table_driven.h new file mode 100644 index 00000000..557c57d3 --- /dev/null +++ b/src/google/protobuf/generated_message_table_driven.h @@ -0,0 +1,173 @@ +// 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_GENERATED_MESSAGE_TABLE_DRIVEN_H__ +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ + +#include + +#if LANG_CXX11 +#define PROTOBUF_CONSTEXPR constexpr + +// We require C++11 and Clang to use constexpr for variables, as GCC 4.8 +// requires constexpr to be consistent between declarations of variables +// unnecessarily (see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58541). +#ifdef __clang__ +#define PROTOBUF_CONSTEXPR_VAR constexpr +#else // !__clang__ +#define PROTOBUF_CONSTEXPR_VAR +#endif // !_clang + +#else +#define PROTOBUF_CONSTEXPR +#define PROTOBUF_CONSTEXPR_VAR +#endif + +namespace google { +namespace protobuf { +namespace internal { + +static PROTOBUF_CONSTEXPR const unsigned char kOneofMask = 0x40; +static PROTOBUF_CONSTEXPR const unsigned char kRepeatedMask = 0x20; +// Check this against types. + +static PROTOBUF_CONSTEXPR const unsigned char kNotPackedMask = 0x10; +static PROTOBUF_CONSTEXPR const unsigned char kInvalidMask = 0x20; + +enum ProcessingTypes { + TYPE_STRING_CORD = 19, + TYPE_STRING_STRING_PIECE = 20, + TYPE_BYTES_CORD = 21, + TYPE_BYTES_STRING_PIECE = 22, +}; + +#if LANG_CXX11 +static_assert(TYPE_BYTES_STRING_PIECE < kRepeatedMask, "Invalid enum"); +#endif + +// TODO(ckennelly): Add a static assertion to ensure that these masks do not +// conflict with wiretypes. + +// ParseTableField is kept small to help simplify instructions for computing +// offsets, as we will always need this information to parse a field. +// Additional data, needed for some types, is stored in +// AuxillaryParseTableField. +struct ParseTableField { + uint32 offset; + uint32 has_bit_index; + unsigned char normal_wiretype; + unsigned char packed_wiretype; + + // processing_type is given by: + // (FieldDescriptor->type() << 1) | FieldDescriptor->is_packed() + unsigned char processing_type; + + unsigned char tag_size; +}; + +struct ParseTable; + +union AuxillaryParseTableField { + typedef bool (*EnumValidator)(int); + + // Enums + struct enum_aux { + EnumValidator validator; + const char* name; + }; + enum_aux enums; + // Group, messages + struct message_aux { + // ExplicitlyInitialized -> T requires a reinterpret_cast, which prevents + // the tables from being constructed as a constexpr. We use void to avoid + // the cast. + const void* default_message_void; + const MessageLite* default_message() const { + return static_cast(default_message_void); + } + const ParseTable* parse_table; + }; + message_aux messages; + // Strings + struct string_aux { + const void* default_ptr; + const char* field_name; + bool strict_utf8; + const char* name; + }; + string_aux strings; + +#if LANG_CXX11 + AuxillaryParseTableField() = default; +#else + AuxillaryParseTableField() { } +#endif + PROTOBUF_CONSTEXPR AuxillaryParseTableField( + AuxillaryParseTableField::enum_aux e) : enums(e) {} + PROTOBUF_CONSTEXPR AuxillaryParseTableField( + AuxillaryParseTableField::message_aux m) : messages(m) {} + PROTOBUF_CONSTEXPR AuxillaryParseTableField( + AuxillaryParseTableField::string_aux s) : strings(s) {} +}; + +struct ParseTable { + const ParseTableField* fields; + const AuxillaryParseTableField* aux; + int max_field_number; + // TODO(ckennelly): Do something with this padding. + + // TODO(ckennelly): Vet these for sign extension. + int64 has_bits_offset; + int64 arena_offset; + int unknown_field_set; +}; + +// TODO(jhen): Remove the __NVCC__ check when we get a version of nvcc that +// supports these checks. +#if LANG_CXX11 && !defined(__NVCC__) +static_assert(sizeof(ParseTableField) <= 16, "ParseTableField is too large"); +// The tables must be composed of POD components to ensure link-time +// initialization. +static_assert(std::is_pod::value, ""); +static_assert(std::is_pod::value, ""); +static_assert(std::is_pod::value, ""); +static_assert(std::is_pod::value, ""); +static_assert(std::is_pod::value, ""); +static_assert(std::is_pod::value, ""); +#endif + +bool MergePartialFromCodedStream(MessageLite* msg, const ParseTable& table, + io::CodedInputStream* input); + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_H__ diff --git a/src/google/protobuf/generated_message_util.cc b/src/google/protobuf/generated_message_util.cc index b4d2c9c1..35d8156e 100644 --- a/src/google/protobuf/generated_message_util.cc +++ b/src/google/protobuf/generated_message_util.cc @@ -58,7 +58,7 @@ void InitEmptyString() { OnShutdown(&DeleteEmptyString); } -int StringSpaceUsedExcludingSelf(const string& str) { +size_t StringSpaceUsedExcludingSelfLong(const string& str) { const void* start = &str; const void* end = &str + 1; if (start <= str.data() && str.data() < end) { diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 14101832..903c4ee8 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -41,12 +41,13 @@ #include #include +#include #include #include #include #ifndef PROTOBUF_FINAL -#if LANG_CXX11 +#if LANG_CXX11 && !defined(__NVCC__) #define PROTOBUF_FINAL final #else #define PROTOBUF_FINAL @@ -75,6 +76,43 @@ namespace internal { #define GOOGLE_PROTOBUF_DEPRECATED_ATTR +// Returns the offset of the given field within the given aggregate type. +// This is equivalent to the ANSI C offsetof() macro. However, according +// to the C++ standard, offsetof() only works on POD types, and GCC +// enforces this requirement with a warning. In practice, this rule is +// unnecessarily strict; there is probably no compiler or platform on +// which the offsets of the direct fields of a class are non-constant. +// Fields inherited from superclasses *can* have non-constant offsets, +// but that's not what this macro will be used for. +#if defined(__clang__) +// For Clang we use __builtin_offsetof() and suppress the warning, +// to avoid Control Flow Integrity and UBSan vptr sanitizers from +// crashing while trying to validate the invalid reinterpet_casts. +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \ + __builtin_offsetof(TYPE, FIELD) \ + _Pragma("clang diagnostic pop") +#else +// Note that we calculate relative to the pointer value 16 here since if we +// just use zero, GCC complains about dereferencing a NULL pointer. We +// choose 16 rather than some other number just in case the compiler would +// be confused by an unaligned pointer. +#define GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(TYPE, FIELD) \ + static_cast( \ + reinterpret_cast( \ + &reinterpret_cast(16)->FIELD) - \ + reinterpret_cast(16)) +#endif + +#define GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ + static_cast< ::google::protobuf::uint32>( \ + reinterpret_cast(&(ONEOF->FIELD)) \ + - reinterpret_cast(ONEOF)) +// TODO(acozzette): remove this transitional macro after updating generated code +#define PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) \ + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ONEOF, FIELD) + // Constants for special floating point values. LIBPROTOBUF_EXPORT double Infinity(); LIBPROTOBUF_EXPORT double NaN(); @@ -125,7 +163,7 @@ class ExplicitlyConstructed { // Default empty string object. Don't use this directly. Instead, call // GetEmptyString() to get the reference. -LIBPROTOBUF_EXPORT extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; +extern ExplicitlyConstructed< ::std::string> fixed_address_empty_string; LIBPROTOBUF_EXPORT extern ProtobufOnceType empty_string_once_init_; LIBPROTOBUF_EXPORT void InitEmptyString(); @@ -139,7 +177,7 @@ LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { return GetEmptyStringAlreadyInited(); } -LIBPROTOBUF_EXPORT int StringSpaceUsedExcludingSelf(const string& str); +size_t StringSpaceUsedExcludingSelfLong(const string& str); // True if IsInitialized() is true for all elements of t. Type is expected @@ -159,11 +197,21 @@ LIBPROTOBUF_EXPORT void InitProtobufDefaults(); // We compute sizes as size_t but cache them as int. This function converts a // computed size to a cached size. Since we don't proceed with serialization if // the total size was > INT_MAX, it is not important what this function returns -// for inputs > INT_MAX. +// for inputs > INT_MAX. However this case should not error or GOOGLE_CHECK-fail, +// because the full size_t resolution is still returned from ByteSizeLong() and +// checked against INT_MAX; we can catch the overflow there. inline int ToCachedSize(size_t size) { return static_cast(size); } +// For cases where a legacy function returns an integer size. We GOOGLE_DCHECK() that +// the conversion will fit within an integer; if this is false then we are +// losing information. +inline int ToIntSize(size_t size) { + GOOGLE_DCHECK_LE(size, static_cast(INT_MAX)); + return static_cast(size); +} + // We mainly calculate sizes in terms of size_t, but some functions that compute // sizes return "int". These int sizes are expected to always be positive. // This function is more efficient than casting an int to size_t directly on diff --git a/src/google/protobuf/io/coded_stream.cc b/src/google/protobuf/io/coded_stream.cc index 3c2e0fbd..df4250e5 100644 --- a/src/google/protobuf/io/coded_stream.cc +++ b/src/google/protobuf/io/coded_stream.cc @@ -76,10 +76,6 @@ CodedInputStream::~CodedInputStream() { if (input_ != NULL) { BackUpInputToCurrentPosition(); } - - if (total_bytes_warning_threshold_ == -2) { - GOOGLE_LOG(WARNING) << "The total number of bytes read was " << total_bytes_read_; - } } // Static. @@ -123,21 +119,15 @@ CodedInputStream::Limit CodedInputStream::PushLimit(int byte_limit) { Limit old_limit = current_limit_; // security: byte_limit is possibly evil, so check for negative values - // and overflow. - if (byte_limit >= 0 && - byte_limit <= INT_MAX - current_position) { + // and overflow. Also check that the new requested limit is before the + // previous limit; otherwise we continue to enforce the previous limit. + if GOOGLE_PREDICT_TRUE(byte_limit >= 0 && + byte_limit <= INT_MAX - current_position && + byte_limit < current_limit_ - current_position) { current_limit_ = current_position + byte_limit; - } else { - // Negative or overflow. - current_limit_ = INT_MAX; + RecomputeBufferLimits(); } - // We need to enforce all limits, not just the new one, so if the previous - // limit was before the new requested limit, we continue to enforce the - // previous limit. - current_limit_ = std::min(current_limit_, old_limit); - - RecomputeBufferLimits(); return old_limit; } @@ -185,16 +175,12 @@ int CodedInputStream::BytesUntilLimit() const { void CodedInputStream::SetTotalBytesLimit( int total_bytes_limit, int warning_threshold) { + (void) warning_threshold; + // Make sure the limit isn't already past, since this could confuse other // code. int current_position = CurrentPosition(); total_bytes_limit_ = std::max(current_position, total_bytes_limit); - if (warning_threshold >= 0) { - total_bytes_warning_threshold_ = warning_threshold; - } else { - // warning_threshold is negative - total_bytes_warning_threshold_ = -1; - } RecomputeBufferLimits(); } @@ -605,20 +591,6 @@ bool CodedInputStream::Refresh() { return false; } - if (total_bytes_warning_threshold_ >= 0 && - total_bytes_read_ >= total_bytes_warning_threshold_) { - GOOGLE_LOG(INFO) << "Reading dangerously large protocol message. If the " - "message turns out to be larger than " - << total_bytes_limit_ << " bytes, parsing will be halted " - "for security reasons. To increase the limit (or to " - "disable these warnings), see " - "CodedInputStream::SetTotalBytesLimit() in " - "google/protobuf/io/coded_stream.h."; - - // Don't warn again for this stream, and print total size at the end. - total_bytes_warning_threshold_ = -2; - } - const void* void_buffer; int buffer_size; if (NextNonEmpty(input_, &void_buffer, &buffer_size)) { @@ -655,7 +627,7 @@ bool CodedInputStream::Refresh() { // CodedOutputStream ================================================= -bool CodedOutputStream::default_serialization_deterministic_ = false; +google::protobuf::internal::AtomicWord CodedOutputStream::default_serialization_deterministic_ = 0; CodedOutputStream::CodedOutputStream(ZeroCopyOutputStream* output) : output_(output), diff --git a/src/google/protobuf/io/coded_stream.h b/src/google/protobuf/io/coded_stream.h index b71b4a98..20d86143 100644 --- a/src/google/protobuf/io/coded_stream.h +++ b/src/google/protobuf/io/coded_stream.h @@ -131,7 +131,9 @@ #define PROTOBUF_LITTLE_ENDIAN 1 #endif #endif +#include #include +#include namespace google { @@ -371,11 +373,10 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // maximum message length should be limited to the shortest length that // will not harm usability. The theoretical shortest message that could // cause integer overflows is 512MB. The default limit is 64MB. Apps - // should set shorter limits if possible. If warning_threshold is not -1, - // a warning will be printed to stderr after warning_threshold bytes are - // read. For backwards compatibility all negative values get squashed to -1, - // as other negative values might have special internal meanings. - // An error will always be printed to stderr if the limit is reached. + // should set shorter limits if possible. For backwards compatibility all + // negative values get squashed to -1, as other negative values might have + // special internal meanings. An error will always be printed to stderr if + // the limit is reached. // // This is unrelated to PushLimit()/PopLimit(). // @@ -568,12 +569,6 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // current_limit_. Set using SetTotalBytesLimit(). int total_bytes_limit_; - // If positive/0: Limit for bytes read after which a warning due to size - // should be logged. - // If -1: Printing of warning disabled. Can be set by client. - // If -2: Internal: Limit has been reached, print full size when destructing. - int total_bytes_warning_threshold_; - // Current recursion budget, controlled by IncrementRecursionDepth() and // similar. Starts at recursion_limit_ and goes down: if this reaches // -1 we are over budget. @@ -581,6 +576,8 @@ class LIBPROTOBUF_EXPORT CodedInputStream { // Recursion depth limit, set by SetRecursionLimit(). int recursion_limit_; + bool disable_strict_correctness_enforcement_; + // See SetExtensionRegistry(). const DescriptorPool* extension_pool_; MessageFactory* extension_factory_; @@ -642,8 +639,6 @@ class LIBPROTOBUF_EXPORT CodedInputStream { static const int kDefaultTotalBytesLimit = INT_MAX; - static const int kDefaultTotalBytesWarningThreshold = 32 << 20; // 32MB - static int default_recursion_limit_; // 100 by default. }; @@ -870,7 +865,7 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { } static bool IsDefaultSerializationDeterministic() { - return default_serialization_deterministic_; + return google::protobuf::internal::Acquire_Load(&default_serialization_deterministic_); } private: @@ -885,7 +880,8 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { // See SetSerializationDeterministic() regarding these three fields. bool serialization_deterministic_is_overridden_; bool serialization_deterministic_override_; - static bool default_serialization_deterministic_; + // Conceptually, default_serialization_deterministic_ is an atomic bool. + static google::protobuf::internal::AtomicWord default_serialization_deterministic_; // Advance the buffer by a given number of bytes. void Advance(int amount); @@ -904,10 +900,15 @@ class LIBPROTOBUF_EXPORT CodedOutputStream { void WriteVarint64SlowPath(uint64 value); // See above. Other projects may use "friend" to allow them to call this. - // Requires: no protocol buffer serialization in progress. + // After SetDefaultSerializationDeterministic() completes, all protocol + // buffer serializations will be deterministic by default. Thread safe. + // However, the meaning of "after" is subtle here: to be safe, each thread + // that wants deterministic serialization by default needs to call + // SetDefaultSerializationDeterministic() or ensure on its own that another + // thread has done so. friend void ::google::protobuf::internal::MapTestForceDeterministic(); static void SetDefaultSerializationDeterministic() { - default_serialization_deterministic_ = true; + google::protobuf::internal::Release_Store(&default_serialization_deterministic_, 1); } }; @@ -1395,9 +1396,9 @@ inline CodedInputStream::CodedInputStream(ZeroCopyInputStream* input) current_limit_(kint32max), buffer_size_after_limit_(0), total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), recursion_budget_(default_recursion_limit_), recursion_limit_(default_recursion_limit_), + disable_strict_correctness_enforcement_(true), extension_pool_(NULL), extension_factory_(NULL) { // Eagerly Refresh() so buffer space is immediately available. @@ -1416,9 +1417,9 @@ inline CodedInputStream::CodedInputStream(const uint8* buffer, int size) current_limit_(size), buffer_size_after_limit_(0), total_bytes_limit_(kDefaultTotalBytesLimit), - total_bytes_warning_threshold_(kDefaultTotalBytesWarningThreshold), recursion_budget_(default_recursion_limit_), recursion_limit_(default_recursion_limit_), + disable_strict_correctness_enforcement_(true), extension_pool_(NULL), extension_factory_(NULL) { // Note that setting current_limit_ == size is important to prevent some diff --git a/src/google/protobuf/io/coded_stream_unittest.cc b/src/google/protobuf/io/coded_stream_unittest.cc index 31574d5b..96f91ae9 100644 --- a/src/google/protobuf/io/coded_stream_unittest.cc +++ b/src/google/protobuf/io/coded_stream_unittest.cc @@ -63,6 +63,7 @@ namespace protobuf { namespace io { namespace { + // =================================================================== // Data-Driven Test Infrastructure @@ -1296,35 +1297,6 @@ void CodedStreamTest::SetupTotalBytesLimitWarningTest( *out_warnings = scoped_log.GetMessages(WARNING); } -TEST_F(CodedStreamTest, TotalBytesLimitWarning) { - std::vector errors; - std::vector warnings; - SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings); - - EXPECT_EQ(0, errors.size()); - - EXPECT_EQ(1, warnings.size()); - EXPECT_PRED_FORMAT2(testing::IsSubstring, - "The total number of bytes read was 2048", - warnings[0]); -} - -TEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) { - std::vector errors; - std::vector warnings; - - // Test with -1 - SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings); - EXPECT_EQ(0, errors.size()); - EXPECT_EQ(0, warnings.size()); - - // Test again with -2, expecting the same result - SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings); - EXPECT_EQ(0, errors.size()); - EXPECT_EQ(0, warnings.size()); -} - - TEST_F(CodedStreamTest, RecursionLimit) { ArrayInputStream input(buffer_, sizeof(buffer_)); CodedInputStream coded_input(&input); @@ -1425,9 +1397,6 @@ TEST_F(CodedStreamTest, InputOver2G) { EXPECT_EQ(0, errors.size()); } -// =================================================================== - - } // namespace } // namespace io } // namespace protobuf diff --git a/src/google/protobuf/io/gzip_stream.h b/src/google/protobuf/io/gzip_stream.h index df1a446e..15b02fe3 100644 --- a/src/google/protobuf/io/gzip_stream.h +++ b/src/google/protobuf/io/gzip_stream.h @@ -118,7 +118,7 @@ class LIBPROTOBUF_EXPORT GzipOutputStream : public ZeroCopyOutputStream { ZLIB = 2, }; - struct LIBPROTOBUF_EXPORT Options { + struct Options { // Defaults to GZIP. Format format; diff --git a/src/google/protobuf/lite_unittest.cc b/src/google/protobuf/lite_unittest.cc index 3ca3fbaf..90d59fbb 100644 --- a/src/google/protobuf/lite_unittest.cc +++ b/src/google/protobuf/lite_unittest.cc @@ -36,14 +36,16 @@ #include #include #include -#include #include +#include #include #include #include #include #include #include +#include + #include using namespace std; @@ -51,9 +53,9 @@ using namespace std; namespace { // Helper methods to test parsing merge behavior. void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) { - GOOGLE_CHECK(message.optional_int32() == 3); - GOOGLE_CHECK(message.optional_int64() == 2); - GOOGLE_CHECK(message.optional_string() == "hello"); + EXPECT_EQ(message.optional_int32(), 3); + EXPECT_EQ(message.optional_int64(), 2); + EXPECT_EQ(message.optional_string(), "hello"); } void AssignParsingMergeMessages( @@ -89,14 +91,8 @@ void SetSomeTypesInEmptyMessageUnknownFields( } // namespace -#define EXPECT_TRUE GOOGLE_CHECK -#define ASSERT_TRUE GOOGLE_CHECK -#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) -#define EXPECT_EQ GOOGLE_CHECK_EQ -#define ASSERT_EQ GOOGLE_CHECK_EQ - -int main(int argc, char* argv[]) { - string data, data2, packed_data; +TEST(Lite, AllLite1) { + string data; { protobuf_unittest::TestAllTypesLite message, message2, message3; @@ -113,7 +109,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectClear(message); } +} +TEST(Lite, AllLite2) { + string data; { protobuf_unittest::TestAllExtensionsLite message, message2, message3; google::protobuf::TestUtilLite::ExpectExtensionsClear(message); @@ -129,6 +128,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectExtensionsClear(message); } +} + +TEST(Lite, AllLite3) { + string data, packed_data; { protobuf_unittest::TestPackedTypesLite message, message2, message3; @@ -152,7 +155,7 @@ int main(int argc, char* argv[]) { google::protobuf::TestUtilLite::SetPackedExtensions(&message); message2.CopyFrom(message); string packed_extensions_data = message.SerializeAsString(); - GOOGLE_CHECK(packed_extensions_data == packed_data); + EXPECT_EQ(packed_extensions_data, packed_data); message3.ParseFromString(packed_extensions_data); google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message); google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2); @@ -162,6 +165,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); } +} + +TEST(Lite, AllLite5) { + string data; { // Test that if an optional or required message/group field appears multiple @@ -209,11 +216,16 @@ int main(int argc, char* argv[]) { google::protobuf::unittest::TestParsingMergeLite::optional_ext)); // Repeated fields should not be merged. - GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3); - GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3); - GOOGLE_CHECK(parsing_merge.ExtensionSize( - google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3); + EXPECT_EQ(parsing_merge.repeated_all_types_size(), 3); + EXPECT_EQ(parsing_merge.repeatedgroup_size(), 3); + EXPECT_EQ(parsing_merge.ExtensionSize( + google::protobuf::unittest::TestParsingMergeLite::repeated_ext), + 3); } +} + +TEST(Lite, AllLite6) { + string data; // Test unknown fields support for lite messages. { @@ -231,6 +243,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectClear(message); } +} + +TEST(Lite, AllLite7) { + string data; { protobuf_unittest::TestAllExtensionsLite message, message2; @@ -247,6 +263,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectExtensionsClear(message); } +} + +TEST(Lite, AllLite8) { + string data; { protobuf_unittest::TestPackedTypesLite message, message2; @@ -263,6 +283,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectPackedClear(message); } +} + +TEST(Lite, AllLite9) { + string data; { protobuf_unittest::TestPackedExtensionsLite message, message2; @@ -279,6 +303,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message); } +} + +TEST(Lite, AllLite10) { + string data; { // Test Unknown fields swap @@ -286,11 +314,15 @@ int main(int argc, char* argv[]) { SetAllTypesInEmptyMessageUnknownFields(&empty_message); SetSomeTypesInEmptyMessageUnknownFields(&empty_message2); data = empty_message.SerializeAsString(); - data2 = empty_message2.SerializeAsString(); + string data2 = empty_message2.SerializeAsString(); empty_message.Swap(&empty_message2); - GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString()); - GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString()); + EXPECT_EQ(data, empty_message2.SerializeAsString()); + EXPECT_EQ(data2, empty_message.SerializeAsString()); } +} + +TEST(Lite, AllLite11) { + string data; { // Test unknown fields swap with self @@ -298,8 +330,12 @@ int main(int argc, char* argv[]) { SetAllTypesInEmptyMessageUnknownFields(&empty_message); data = empty_message.SerializeAsString(); empty_message.Swap(&empty_message); - GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString()); + EXPECT_EQ(data, empty_message.SerializeAsString()); } +} + +TEST(Lite, AllLite12) { + string data; { // Test MergeFrom with unknown fields @@ -324,8 +360,12 @@ int main(int argc, char* argv[]) { // We do not compare the serialized output of a normal message and a lite // message because the order of fields do not match. We convert lite message // back into normal message, then compare. - GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString()); + EXPECT_EQ(message.SerializeAsString(), message2.SerializeAsString()); } +} + +TEST(Lite, AllLite13) { + string data; { // Test unknown enum value @@ -345,18 +385,26 @@ int main(int argc, char* argv[]) { } message.ParseFromString(buffer); data = message.SerializeAsString(); - GOOGLE_CHECK_EQ(data, buffer); + EXPECT_EQ(data, buffer); } +} + +TEST(Lite, AllLite14) { + string data; { // Test Clear with unknown fields protobuf_unittest::TestEmptyMessageLite empty_message; SetAllTypesInEmptyMessageUnknownFields(&empty_message); empty_message.Clear(); - GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size()); + EXPECT_EQ(0, empty_message.unknown_fields().size()); } +} - // Tests for map lite ============================================= +// Tests for map lite ============================================= + +TEST(Lite, AllLite15) { + string data; { // Accessors @@ -368,6 +416,10 @@ int main(int argc, char* argv[]) { google::protobuf::MapLiteTestUtil::ModifyMapFields(&message); google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message); } +} + +TEST(Lite, AllLite16) { + string data; { // SetMapFieldsInitialized @@ -376,6 +428,10 @@ int main(int argc, char* argv[]) { google::protobuf::MapLiteTestUtil::SetMapFieldsInitialized(&message); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSetInitialized(message); } +} + +TEST(Lite, AllLite17) { + string data; { // Clear @@ -385,6 +441,10 @@ int main(int argc, char* argv[]) { message.Clear(); google::protobuf::MapLiteTestUtil::ExpectClear(message); } +} + +TEST(Lite, AllLite18) { + string data; { // ClearMessageMap @@ -394,6 +454,10 @@ int main(int argc, char* argv[]) { google::protobuf::TestUtilLite::ExpectClear( (*message.mutable_map_int32_message())[0]); } +} + +TEST(Lite, AllLite19) { + string data; { // CopyFrom @@ -407,6 +471,10 @@ int main(int argc, char* argv[]) { message2.CopyFrom(message2); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} + +TEST(Lite, AllLite20) { + string data; { // CopyFromMessageMap @@ -421,6 +489,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); } +} + +TEST(Lite, AllLite21) { + string data; { // SwapWithEmpty @@ -434,6 +506,10 @@ int main(int argc, char* argv[]) { google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); google::protobuf::MapLiteTestUtil::ExpectClear(message1); } +} + +TEST(Lite, AllLite22) { + string data; { // SwapWithSelf @@ -445,6 +521,10 @@ int main(int argc, char* argv[]) { message.Swap(&message); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message); } +} + +TEST(Lite, AllLite23) { + string data; { // SwapWithOther @@ -458,6 +538,10 @@ int main(int argc, char* argv[]) { google::protobuf::MapLiteTestUtil::ExpectMapFieldsModified(message1); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} + +TEST(Lite, AllLite24) { + string data; { // CopyConstructor @@ -467,6 +551,10 @@ int main(int argc, char* argv[]) { protobuf_unittest::TestMapLite message2(message1); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} + +TEST(Lite, AllLite25) { + string data; { // CopyAssignmentOperator @@ -481,6 +569,10 @@ int main(int argc, char* argv[]) { message2.operator=(message2); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} + +TEST(Lite, AllLite26) { + string data; { // NonEmptyMergeFrom @@ -499,6 +591,10 @@ int main(int argc, char* argv[]) { message1.MergeFrom(message2); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message1); } +} + +TEST(Lite, AllLite27) { + string data; { // MergeFromMessageMap @@ -513,6 +609,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message1.map_int32_message().at(0).repeated_int32_size()); EXPECT_EQ(101, message1.map_int32_message().at(0).repeated_int32(0)); } +} + +TEST(Lite, AllLite28) { + string data; { // Test the generated SerializeWithCachedSizesToArray() @@ -527,6 +627,10 @@ int main(int argc, char* argv[]) { EXPECT_TRUE(message2.ParseFromString(data)); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} + +TEST(Lite, AllLite29) { + string data; { // Test the generated SerializeWithCachedSizes() @@ -547,8 +651,12 @@ int main(int argc, char* argv[]) { EXPECT_TRUE(message2.ParseFromString(data)); google::protobuf::MapLiteTestUtil::ExpectMapFieldsSet(message2); } +} +TEST(Lite, AllLite32) { + string data; + { // Proto2UnknownEnum protobuf_unittest::TestEnumMapPlusExtraLite from; @@ -578,6 +686,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(protobuf_unittest::E_PROTO2_MAP_ENUM_EXTRA_LITE, from.unknown_map_field().at(0)); } +} + +TEST(Lite, AllLite33) { + string data; { // StandardWireFormat @@ -588,6 +700,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(1, message.map_int32_int32().at(1)); } +} + +TEST(Lite, AllLite34) { + string data; { // UnorderedWireFormat @@ -600,6 +716,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(1, message.map_int32_int32().at(2)); } +} + +TEST(Lite, AllLite35) { + string data; { // DuplicatedKeyWireFormat @@ -612,6 +732,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(1, message.map_int32_int32().at(2)); } +} + +TEST(Lite, AllLite36) { + string data; { // DuplicatedValueWireFormat @@ -624,6 +748,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(2, message.map_int32_int32().at(1)); } +} + +TEST(Lite, AllLite37) { + string data; { // MissedKeyWireFormat @@ -636,6 +764,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(1, message.map_int32_int32().at(0)); } +} + +TEST(Lite, AllLite38) { + string data; { // MissedValueWireFormat @@ -648,6 +780,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(0, message.map_int32_int32().at(1)); } +} + +TEST(Lite, AllLite39) { + string data; { // UnknownFieldWireFormat @@ -660,6 +796,10 @@ int main(int argc, char* argv[]) { EXPECT_EQ(1, message.map_int32_int32().size()); EXPECT_EQ(3, message.map_int32_int32().at(2)); } +} + +TEST(Lite, AllLite40) { + string data; { // CorruptedWireFormat @@ -670,6 +810,10 @@ int main(int argc, char* argv[]) { EXPECT_FALSE(message.ParseFromString(data)); } +} + +TEST(Lite, AllLite41) { + string data; { // IsInitialized @@ -685,6 +829,10 @@ int main(int argc, char* argv[]) { (*map_message.mutable_map_field())[0].set_c(0); EXPECT_TRUE(map_message.IsInitialized()); } +} + +TEST(Lite, AllLite42) { + string data; { // Check that adding more values to enum does not corrupt message @@ -714,5 +862,4 @@ int main(int argc, char* argv[]) { } std::cout << "PASS" << std::endl; - return 0; } diff --git a/src/google/protobuf/map.h b/src/google/protobuf/map.h index 88878b58..18ee3652 100644 --- a/src/google/protobuf/map.h +++ b/src/google/protobuf/map.h @@ -37,7 +37,6 @@ #ifndef GOOGLE_PROTOBUF_MAP_H__ #define GOOGLE_PROTOBUF_MAP_H__ -#include #include #include // To support Visual Studio 2008 #include @@ -47,8 +46,7 @@ #include #include #include -#include -#include +#include #if __cpp_exceptions && LANG_CXX11 #include #endif @@ -64,16 +62,14 @@ class MapIterator; template struct is_proto_enum; namespace internal { -template + WireFormatLite::FieldType value_wire_type, int default_enum_value> class MapFieldLite; -template + WireFormatLite::FieldType value_wire_type, int default_enum_value> class MapField; template @@ -84,389 +80,6 @@ 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_; - } - bool 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_) { - // We could define a total order that handles this case, but - // there currently no need. So, for now, fail. - GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; - } - switch (type()) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - return false; - 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_; - } - return false; - } - - bool operator==(const MapKey& other) const { - if (type_ != other.type_) { - // To be consistent with operator<, we don't allow this either. - GOOGLE_LOG(FATAL) << "Unsupported: type mismatch"; - } - switch (type()) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - 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_; - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return false; - } - - void CopyFrom(const MapKey& other) { - SetType(other.type()); - switch (type_) { - case FieldDescriptor::CPPTYPE_DOUBLE: - case FieldDescriptor::CPPTYPE_FLOAT: - case FieldDescriptor::CPPTYPE_ENUM: - case FieldDescriptor::CPPTYPE_MESSAGE: - GOOGLE_LOG(FATAL) << "Unsupported"; - break; - 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; - } - } - - private: - template - 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(data_) = value; - } - void SetUInt64Value(uint64 value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, - "MapValueRef::SetUInt64Value"); - *reinterpret_cast(data_) = value; - } - void SetInt32Value(int32 value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, - "MapValueRef::SetInt32Value"); - *reinterpret_cast(data_) = value; - } - void SetUInt32Value(uint32 value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, - "MapValueRef::SetUInt32Value"); - *reinterpret_cast(data_) = value; - } - void SetBoolValue(bool value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, - "MapValueRef::SetBoolValue"); - *reinterpret_cast(data_) = value; - } - // TODO(jieluo) - Checks that enum is member. - void SetEnumValue(int value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, - "MapValueRef::SetEnumValue"); - *reinterpret_cast(data_) = value; - } - void SetStringValue(const string& value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, - "MapValueRef::SetStringValue"); - *reinterpret_cast(data_) = value; - } - void SetFloatValue(float value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, - "MapValueRef::SetFloatValue"); - *reinterpret_cast(data_) = value; - } - void SetDoubleValue(double value) { - TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, - "MapValueRef::SetDoubleValue"); - *reinterpret_cast(data_) = value; - } - - int64 GetInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, - "MapValueRef::GetInt64Value"); - return *reinterpret_cast(data_); - } - uint64 GetUInt64Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, - "MapValueRef::GetUInt64Value"); - return *reinterpret_cast(data_); - } - int32 GetInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, - "MapValueRef::GetInt32Value"); - return *reinterpret_cast(data_); - } - uint32 GetUInt32Value() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, - "MapValueRef::GetUInt32Value"); - return *reinterpret_cast(data_); - } - bool GetBoolValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, - "MapValueRef::GetBoolValue"); - return *reinterpret_cast(data_); - } - int GetEnumValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, - "MapValueRef::GetEnumValue"); - return *reinterpret_cast(data_); - } - const string& GetStringValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, - "MapValueRef::GetStringValue"); - return *reinterpret_cast(data_); - } - float GetFloatValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, - "MapValueRef::GetFloatValue"); - return *reinterpret_cast(data_); - } - double GetDoubleValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, - "MapValueRef::GetDoubleValue"); - return *reinterpret_cast(data_); - } - - const Message& GetMessageValue() const { - TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, - "MapValueRef::GetMessageValue"); - return *reinterpret_cast(data_); - } - - Message* MutableMessageValue() { - TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, - "MapValueRef::MutableMessageValue"); - return reinterpret_cast(data_); - } - - private: - template - friend class internal::MapField; - template - 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(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(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 // its process of construction and destruction. @@ -523,30 +136,18 @@ class Map { typedef size_t size_type; typedef hash hasher; - explicit Map(bool old_style = false) - : arena_(NULL), - default_enum_value_(0), - old_style_(old_style) { - Init(); - } - explicit Map(Arena* arena, bool old_style = false) - : arena_(arena), - default_enum_value_(0), - old_style_(old_style) { - Init(); - } + Map() : arena_(NULL), default_enum_value_(0) { Init(); } + explicit Map(Arena* arena) : arena_(arena), default_enum_value_(0) { Init(); } + Map(const Map& other) - : arena_(NULL), - default_enum_value_(other.default_enum_value_), - old_style_(other.old_style_) { + : arena_(NULL), default_enum_value_(other.default_enum_value_) { Init(); insert(other.begin(), other.end()); } + template - Map(const InputIt& first, const InputIt& last, bool old_style = false) - : arena_(NULL), - default_enum_value_(0), - old_style_(old_style) { + Map(const InputIt& first, const InputIt& last) + : arena_(NULL), default_enum_value_(0) { Init(); insert(first, last); } @@ -554,22 +155,13 @@ class Map { ~Map() { clear(); if (arena_ == NULL) { - if (old_style_) - delete deprecated_elements_; - else - delete elements_; + delete elements_; } } private: void Init() { - if (old_style_) - deprecated_elements_ = Arena::Create( - arena_, 0, hasher(), std::equal_to(), - MapAllocator*> >(arena_)); - else - elements_ = - Arena::Create(arena_, 0, hasher(), Allocator(arena_)); + elements_ = Arena::Create(arena_, 0, hasher(), Allocator(arena_)); } // re-implement std::allocator to use arena allocator for memory allocation. @@ -764,14 +356,13 @@ class Map { }; typedef typename Allocator::template rebind::other KeyPtrAllocator; typedef std::set Tree; + typedef typename Tree::iterator TreeIterator; // iterator and const_iterator are instantiations of iterator_base. template - class iterator_base { - public: + struct iterator_base { typedef KeyValueType& reference; typedef KeyValueType* pointer; - typedef typename Tree::iterator TreeIterator; // Invariants: // node_ is always correct. This is handy because the most common @@ -780,7 +371,7 @@ class Map { // are updated to be correct also, but those fields can become stale // if the underlying map is modified. When those fields are needed they // are rechecked, and updated if necessary. - iterator_base() : node_(NULL) {} + iterator_base() : node_(NULL), m_(NULL), bucket_index_(0) {} explicit iterator_base(const InnerMap* m) : m_(m) { SearchFrom(m->index_of_first_non_null_); @@ -791,22 +382,15 @@ class Map { // can convert to const_iterator" is OK but the reverse direction is not. template explicit iterator_base(const iterator_base& it) - : node_(it.node_), - m_(it.m_), - bucket_index_(it.bucket_index_), - tree_it_(it.tree_it_) {} + : node_(it.node_), m_(it.m_), bucket_index_(it.bucket_index_) {} iterator_base(Node* n, const InnerMap* m, size_type index) - : node_(n), - m_(m), - bucket_index_(index) {} + : node_(n), m_(m), bucket_index_(index) {} iterator_base(TreeIterator tree_it, const InnerMap* m, size_type index) - : node_(NodePtrFromKeyPtr(*tree_it)), - m_(m), - bucket_index_(index), - tree_it_(tree_it) { - // Invariant: iterators that use tree_it_ have an even bucket_index_. + : node_(NodePtrFromKeyPtr(*tree_it)), m_(m), bucket_index_(index) { + // Invariant: iterators that use buckets with trees have an even + // bucket_index_. GOOGLE_DCHECK_EQ(bucket_index_ % 2, 0); } @@ -824,8 +408,7 @@ class Map { } else if (m_->TableEntryIsTree(bucket_index_)) { Tree* tree = static_cast(m_->table_[bucket_index_]); GOOGLE_DCHECK(!tree->empty()); - tree_it_ = tree->begin(); - node_ = NodePtrFromKeyPtr(*tree_it_); + node_ = NodePtrFromKeyPtr(*tree->begin()); break; } } @@ -843,16 +426,17 @@ class Map { iterator_base& operator++() { if (node_->next == NULL) { - const bool is_list = revalidate_if_necessary(); + TreeIterator tree_it; + const bool is_list = revalidate_if_necessary(&tree_it); if (is_list) { SearchFrom(bucket_index_ + 1); } else { GOOGLE_DCHECK_EQ(bucket_index_ & 1, 0); Tree* tree = static_cast(m_->table_[bucket_index_]); - if (++tree_it_ == tree->end()) { + if (++tree_it == tree->end()) { SearchFrom(bucket_index_ + 2); } else { - node_ = NodePtrFromKeyPtr(*tree_it_); + node_ = NodePtrFromKeyPtr(*tree_it); } } } else { @@ -869,8 +453,9 @@ class Map { // Assumes node_ and m_ are correct and non-NULL, but other fields may be // stale. Fix them as needed. Then return true iff node_ points to a - // Node in a list. - bool revalidate_if_necessary() { + // Node in a list. If false is returned then *it is modified to be + // a valid iterator for node_. + bool revalidate_if_necessary(TreeIterator* it) { GOOGLE_DCHECK(node_ != NULL && m_ != NULL); // Force bucket_index_ to be in range. bucket_index_ &= (m_->num_buckets_ - 1); @@ -891,16 +476,14 @@ class Map { // not. Revalidate just to be sure. This case is rare enough that we // don't worry about potential optimizations, such as having a custom // find-like method that compares Node* instead of const Key&. - iterator_base i(m_->find(*KeyPtrFromNodePtr(node_))); + iterator_base i(m_->find(*KeyPtrFromNodePtr(node_), it)); bucket_index_ = i.bucket_index_; - tree_it_ = i.tree_it_; return m_->TableEntryIsList(bucket_index_); } Node* node_; const InnerMap* m_; size_type bucket_index_; - TreeIterator tree_it_; }; public: @@ -952,7 +535,7 @@ class Map { bool empty() const { return size() == 0; } iterator find(const Key& k) { return iterator(FindHelper(k).first); } - const_iterator find(const Key& k) const { return FindHelper(k).first; } + const_iterator find(const Key& k) const { return find(k, NULL); } // In traditional C++ style, this performs "insert if not present." std::pair insert(const KeyValuePair& kv) { @@ -999,7 +582,8 @@ class Map { void erase(iterator it) { GOOGLE_DCHECK_EQ(it.m_, this); - const bool is_list = it.revalidate_if_necessary(); + typename Tree::iterator tree_it; + const bool is_list = it.revalidate_if_necessary(&tree_it); size_type b = it.bucket_index_; Node* const item = it.node_; if (is_list) { @@ -1010,7 +594,7 @@ class Map { } else { GOOGLE_DCHECK(TableEntryIsTree(b)); Tree* tree = static_cast(table_[b]); - tree->erase(it.tree_it_); + tree->erase(*tree_it); if (tree->empty()) { // Force b to be the minimum of b and b ^ 1. This is important // only because we want index_of_first_non_null_ to be correct. @@ -1030,7 +614,14 @@ class Map { } private: + const_iterator find(const Key& k, TreeIterator* it) const { + return FindHelper(k, it).first; + } std::pair FindHelper(const Key& k) const { + return FindHelper(k, NULL); + } + std::pair FindHelper(const Key& k, + TreeIterator* it) const { size_type b = BucketNumber(k); if (TableEntryIsNonEmptyList(b)) { Node* node = static_cast(table_[b]); @@ -1048,6 +639,7 @@ class Map { Key* key = const_cast(&k); typename Tree::iterator tree_it = tree->find(key); if (tree_it != tree->end()) { + if (it != NULL) *it = tree_it; return std::make_pair(const_iterator(tree_it, this, b), b); } } @@ -1358,72 +950,30 @@ class Map { GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(InnerMap); }; // end of class InnerMap - typedef hash_map, std::equal_to, - MapAllocator*> > > - DeprecatedInnerMap; - public: // Iterators - class iterator_base { - public: - // We support "old style" and "new style" iterators for now. This is - // temporary. Also, for "iterator()" we have an unknown category. - // TODO(gpike): get rid of this. - enum IteratorStyle { kUnknown, kOld, kNew }; - explicit iterator_base(IteratorStyle style) : iterator_style_(style) {} - - bool OldStyle() const { - GOOGLE_DCHECK_NE(iterator_style_, kUnknown); - return iterator_style_ == kOld; - } - bool UnknownStyle() const { - return iterator_style_ == kUnknown; - } - bool SameStyle(const iterator_base& other) const { - return iterator_style_ == other.iterator_style_; - } - - private: - IteratorStyle iterator_style_; - }; - class const_iterator - : private iterator_base, - public std::iterator { typedef typename InnerMap::const_iterator InnerIt; - typedef typename DeprecatedInnerMap::const_iterator DeprecatedInnerIt; public: - const_iterator() : iterator_base(iterator_base::kUnknown) {} - explicit const_iterator(const DeprecatedInnerIt& dit) - : iterator_base(iterator_base::kOld), dit_(dit) {} - explicit const_iterator(const InnerIt& it) - : iterator_base(iterator_base::kNew), it_(it) {} - - const_iterator(const const_iterator& other) - : iterator_base(other), it_(other.it_), dit_(other.dit_) {} + const_iterator() {} + explicit const_iterator(const InnerIt& it) : it_(it) {} const_reference operator*() const { - return this->OldStyle() ? *dit_->second : *it_->value(); + return *it_->value(); } const_pointer operator->() const { return &(operator*()); } const_iterator& operator++() { - if (this->OldStyle()) - ++dit_; - else - ++it_; + ++it_; return *this; } - const_iterator operator++(int) { - return this->OldStyle() ? const_iterator(dit_++) : const_iterator(it_++); - } + const_iterator operator++(int) { return const_iterator(it_++); } friend bool operator==(const const_iterator& a, const const_iterator& b) { - if (!a.SameStyle(b)) return false; - if (a.UnknownStyle()) return true; - return a.OldStyle() ? (a.dit_ == b.dit_) : (a.it_ == b.it_); + return a.it_ == b.it_; } friend bool operator!=(const const_iterator& a, const const_iterator& b) { return !(a == b); @@ -1431,48 +981,31 @@ class Map { private: InnerIt it_; - DeprecatedInnerIt dit_; }; - class iterator : private iterator_base, - public std::iterator { + class iterator : public std::iterator { typedef typename InnerMap::iterator InnerIt; - typedef typename DeprecatedInnerMap::iterator DeprecatedInnerIt; public: - iterator() : iterator_base(iterator_base::kUnknown) {} - explicit iterator(const DeprecatedInnerIt& dit) - : iterator_base(iterator_base::kOld), dit_(dit) {} - explicit iterator(const InnerIt& it) - : iterator_base(iterator_base::kNew), it_(it) {} + iterator() {} + explicit iterator(const InnerIt& it) : it_(it) {} - reference operator*() const { - return this->OldStyle() ? *dit_->second : *it_->value(); - } + reference operator*() const { return *it_->value(); } pointer operator->() const { return &(operator*()); } iterator& operator++() { - if (this->OldStyle()) - ++dit_; - else - ++it_; + ++it_; return *this; } - iterator operator++(int) { - return this->OldStyle() ? iterator(dit_++) : iterator(it_++); - } + iterator operator++(int) { return iterator(it_++); } // Allow implicit conversion to const_iterator. operator const_iterator() const { - return this->OldStyle() ? - const_iterator(typename DeprecatedInnerMap::const_iterator(dit_)) : - const_iterator(typename InnerMap::const_iterator(it_)); + return const_iterator(typename InnerMap::const_iterator(it_)); } friend bool operator==(const iterator& a, const iterator& b) { - if (!a.SameStyle(b)) return false; - if (a.UnknownStyle()) return true; - return a.OldStyle() ? a.dit_ == b.dit_ : a.it_ == b.it_; + return a.it_ == b.it_; } friend bool operator!=(const iterator& a, const iterator& b) { return !(a == b); @@ -1482,38 +1015,26 @@ class Map { friend class Map; InnerIt it_; - DeprecatedInnerIt dit_; }; - iterator begin() { - return old_style_ ? iterator(deprecated_elements_->begin()) - : iterator(elements_->begin()); - } - iterator end() { - return old_style_ ? iterator(deprecated_elements_->end()) - : iterator(elements_->end()); - } + iterator begin() { return iterator(elements_->begin()); } + iterator end() { return iterator(elements_->end()); } const_iterator begin() const { - return old_style_ ? const_iterator(deprecated_elements_->begin()) - : const_iterator(iterator(elements_->begin())); + return const_iterator(iterator(elements_->begin())); } const_iterator end() const { - return old_style_ ? const_iterator(deprecated_elements_->end()) - : const_iterator(iterator(elements_->end())); + return const_iterator(iterator(elements_->end())); } const_iterator cbegin() const { return begin(); } const_iterator cend() const { return end(); } // Capacity - size_type size() const { - return old_style_ ? deprecated_elements_->size() : elements_->size(); - } + size_type size() const { return elements_->size(); } bool empty() const { return size() == 0; } // Element access T& operator[](const key_type& key) { - value_type** value = - old_style_ ? &(*deprecated_elements_)[key] : &(*elements_)[key]; + value_type** value = &(*elements_)[key]; if (*value == NULL) { *value = CreateValueTypeInternal(key); internal::MapValueInitializer::value, @@ -1540,13 +1061,9 @@ class Map { return it == end() ? 0 : 1; } const_iterator find(const key_type& key) const { - return old_style_ ? const_iterator(deprecated_elements_->find(key)) - : const_iterator(iterator(elements_->find(key))); - } - iterator find(const key_type& key) { - return old_style_ ? iterator(deprecated_elements_->find(key)) - : iterator(elements_->find(key)); + return const_iterator(iterator(elements_->find(key))); } + iterator find(const key_type& key) { return iterator(elements_->find(key)); } std::pair equal_range( const key_type& key) const { const_iterator it = find(key); @@ -1569,23 +1086,12 @@ class Map { // insert std::pair insert(const value_type& value) { - if (old_style_) { - iterator it = find(value.first); - if (it != end()) { - return std::pair(it, false); - } else { - return std::pair( - iterator(deprecated_elements_->insert(std::pair( - value.first, CreateValueTypeInternal(value))).first), true); - } - } else { - std::pair p = - elements_->insert(value.first); - if (p.second) { - p.first->value() = CreateValueTypeInternal(value); - } - return std::pair(iterator(p.first), p.second); + std::pair p = + elements_->insert(value.first); + if (p.second) { + p.first->value() = CreateValueTypeInternal(value); } + return std::pair(iterator(p.first), p.second); } template void insert(InputIt first, InputIt last) { @@ -1610,10 +1116,7 @@ class Map { iterator erase(iterator pos) { if (arena_ == NULL) delete pos.operator->(); iterator i = pos++; - if (old_style_) - deprecated_elements_->erase(i.dit_); - else - elements_->erase(i.it_); + elements_->erase(i.it_); return pos; } void erase(iterator first, iterator last) { @@ -1633,13 +1136,9 @@ class Map { } void swap(Map& other) { - if (arena_ == other.arena_ && old_style_ == other.old_style_) { + if (arena_ == other.arena_) { std::swap(default_enum_value_, other.default_enum_value_); - if (old_style_) { - std::swap(deprecated_elements_, other.deprecated_elements_); - } else { - std::swap(elements_, other.elements_); - } + std::swap(elements_, other.elements_); } else { // TODO(zuguang): optimize this. The temporary copy can be allocated // in the same arena as the other message, and the "other = copy" can @@ -1653,8 +1152,7 @@ class Map { // Access to hasher. Currently this returns a copy, but it may // be modified to return a const reference in the future. hasher hash_function() const { - return old_style_ ? deprecated_elements_->hash_function() - : elements_->hash_function(); + return elements_->hash_function(); } private: @@ -1692,19 +1190,12 @@ class Map { Arena* arena_; int default_enum_value_; - // The following is a tagged union because we support two map styles - // for now. - // TODO(gpike): get rid of the old style. - const bool old_style_; - union { - InnerMap* elements_; - DeprecatedInnerMap* deprecated_elements_; - }; + InnerMap* elements_; friend class ::google::protobuf::Arena; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - template @@ -1712,49 +1203,6 @@ class Map { }; } // namespace protobuf -} // namespace google - -GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START -template<> -struct hash { - size_t - operator()(const google::protobuf::MapKey& map_key) const { - switch (map_key.type()) { - 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) << "Unsupported"; - break; - case google::protobuf::FieldDescriptor::CPPTYPE_STRING: - return hash()(map_key.GetStringValue()); -#if defined(GOOGLE_PROTOBUF_HAVE_64BIT_HASH) - case google::protobuf::FieldDescriptor::CPPTYPE_INT64: - return hash< ::google::protobuf::int64>()(map_key.GetInt64Value()); - case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: - return hash< ::google::protobuf::uint64>()(map_key.GetUInt64Value()); -#else - case google::protobuf::FieldDescriptor::CPPTYPE_INT64: - case google::protobuf::FieldDescriptor::CPPTYPE_UINT64: - GOOGLE_LOG(FATAL) << "Unsupported on this platform."; - break; -#endif - case google::protobuf::FieldDescriptor::CPPTYPE_INT32: - return hash< ::google::protobuf::int32>()(map_key.GetInt32Value()); - case google::protobuf::FieldDescriptor::CPPTYPE_UINT32: - return hash< ::google::protobuf::uint32>()(map_key.GetUInt32Value()); - case google::protobuf::FieldDescriptor::CPPTYPE_BOOL: - return hash()(map_key.GetBoolValue()); - } - GOOGLE_LOG(FATAL) << "Can't get here."; - return 0; - } - bool - operator()(const google::protobuf::MapKey& map_key1, - const google::protobuf::MapKey& map_key2) const { - return map_key1 < map_key2; - } -}; -GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END +} // namespace google #endif // GOOGLE_PROTOBUF_MAP_H__ diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index d7db9b0f..0a7d9a97 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -43,10 +43,9 @@ namespace google { namespace protobuf { class Arena; namespace internal { -template + WireFormatLite::FieldType kValueFieldType, int default_enum_value> class MapField; } } @@ -54,30 +53,6 @@ class MapField; namespace protobuf { namespace internal { -// Register all MapEntry default instances so we can delete them in -// ShutdownProtobufLibrary(). -void LIBPROTOBUF_EXPORT RegisterMapEntryDefaultInstance( - MessageLite* default_instance); - -// This is the common base class for MapEntry. It is used by MapFieldBase in -// reflection api, in which the static type of key and value is unknown. -class LIBPROTOBUF_EXPORT MapEntryBase : public Message { - public: - ::google::protobuf::Metadata GetMetadata() const { - ::google::protobuf::Metadata metadata; - metadata.descriptor = descriptor_; - metadata.reflection = reflection_; - return metadata; - } - - protected: - MapEntryBase() : descriptor_(NULL), reflection_(NULL) { } - virtual ~MapEntryBase() {} - - const Descriptor* descriptor_; - const Reflection* reflection_; -}; - // 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 in-memory type is the same as generated message with the same @@ -105,212 +80,72 @@ class LIBPROTOBUF_EXPORT MapEntryBase : public Message { // 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 -class MapEntry : public MapEntryBase { - // Provide utilities to parse/serialize key/value. Provide utilities to - // manipulate internal stored type. - typedef MapTypeHandler KeyTypeHandler; - typedef MapTypeHandler 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< - Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> EntryType; - - // Abbreviation for MapEntryLite - typedef typename google::protobuf::internal::MapEntryLite< - Key, Value, kKeyFieldType, kValueFieldType, default_enum_value> - EntryLiteType; - + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +class LIBPROTOBUF_EXPORT MapEntry + : public MapEntryImpl { public: - ~MapEntry() { - if (this == default_instance_) { - delete reflection_; - } - } - - // accessors ====================================================== - - virtual inline const KeyMapEntryAccessorType& key() const { - return entry_lite_.key(); - } - inline KeyMapEntryAccessorType* mutable_key() { - return entry_lite_.mutable_key(); - } - virtual inline const ValueMapEntryAccessorType& value() const { - return entry_lite_.value(); - } - inline ValueMapEntryAccessorType* mutable_value() { - return entry_lite_.mutable_value(); - } - - // implements Message ============================================= - - bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { - return entry_lite_.MergePartialFromCodedStream(input); - } - - size_t ByteSizeLong() const { - return entry_lite_.ByteSizeLong(); - } - - void SerializeWithCachedSizes(::google::protobuf::io::CodedOutputStream* output) const { - entry_lite_.SerializeWithCachedSizes(output); - } - - ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, - ::google::protobuf::uint8* output) const { - return entry_lite_.InternalSerializeWithCachedSizesToArray(deterministic, - output); - } - - int GetCachedSize() const { - return entry_lite_.GetCachedSize(); - } - - bool IsInitialized() const { - return entry_lite_.IsInitialized(); - } - - Message* New() const { - MapEntry* entry = new MapEntry; - entry->descriptor_ = descriptor_; - entry->reflection_ = reflection_; - entry->set_default_instance(default_instance_); - return entry; - } - - Message* New(Arena* arena) const { - MapEntry* entry = Arena::CreateMessage(arena); - entry->descriptor_ = descriptor_; - entry->reflection_ = reflection_; - entry->set_default_instance(default_instance_); - return entry; - } - - int SpaceUsed() const { - int size = sizeof(MapEntry); - size += entry_lite_.SpaceUsed(); - return size; - } - - void CopyFrom(const ::google::protobuf::Message& from) { - Clear(); - MergeFrom(from); - } - - void MergeFrom(const ::google::protobuf::Message& from) { - GOOGLE_CHECK_NE(&from, this); - const MapEntry* source = dynamic_cast_if_available(&from); - if (source == NULL) { - ReflectionOps::Merge(from, this); - } else { - MergeFrom(*source); - } - } - - void CopyFrom(const MapEntry& from) { - Clear(); - MergeFrom(from); - } - - void MergeFrom(const MapEntry& from) { - entry_lite_.MergeFrom(from.entry_lite_); - } - - void Clear() { - entry_lite_.Clear(); - } - - void InitAsDefaultInstance() { - entry_lite_.InitAsDefaultInstance(); - } - - Arena* GetArena() const { - return entry_lite_.GetArena(); - } - // Create default MapEntry instance for given descriptor. Descriptor has to be // given when creating default MapEntry instance because different map field // may have the same type and MapEntry class. The given descriptor is needed // to distinguish instances of the same MapEntry class. - static MapEntry* CreateDefaultInstance(const Descriptor* descriptor) { - MapEntry* entry = new MapEntry; + static const Reflection* CreateReflection(const Descriptor* descriptor, + const Derived* entry) { ReflectionSchema schema = { entry, offsets_, has_bits_, - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_._has_bits_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _internal_metadata_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, _has_bits_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, + _internal_metadata_), -1, -1, sizeof(MapEntry)}; const Reflection* reflection = new GeneratedMessageReflection( descriptor, schema, DescriptorPool::generated_pool(), MessageFactory::generated_factory()); - entry->descriptor_ = descriptor; - entry->reflection_ = reflection; - entry->set_default_instance(entry); - entry->InitAsDefaultInstance(); - RegisterMapEntryDefaultInstance(entry); - return entry; + return reflection; } - private: - MapEntry() - : _internal_metadata_(NULL), default_instance_(NULL), entry_lite_() {} - + MapEntry() : _internal_metadata_(NULL) {} explicit MapEntry(Arena* arena) - : _internal_metadata_(arena), - default_instance_(NULL), - entry_lite_(arena) {} - - inline Arena* GetArenaNoVirtual() const { - return entry_lite_.GetArenaNoVirtual(); - } - - void set_default_instance(MapEntry* default_instance) { - default_instance_ = default_instance; - entry_lite_.set_default_instance(&default_instance->entry_lite_); - } + : MapEntryImpl(arena), + _internal_metadata_(arena) {} + typedef void InternalArenaConstructable_; + typedef void DestructorSkippable_; + private: static uint32 offsets_[2]; static uint32 has_bits_[2]; InternalMetadataWithArena _internal_metadata_; - MapEntry* default_instance_; - EntryLiteType entry_lite_; friend class ::google::protobuf::Arena; - typedef void InternalArenaConstructable_; - typedef void DestructorSkippable_; - template + template friend class internal::MapField; friend class internal::GeneratedMessageReflection; GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry); }; -template -uint32 MapEntry::offsets_[2] = { - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.key_), - GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, entry_lite_.value_), +uint32 MapEntry::offsets_[2] = { + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, key_), + GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MapEntry, value_), }; -template -uint32 MapEntry::has_bits_[2] = {0, 1}; +uint32 MapEntry::has_bits_[2] = {0, 1}; } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index 1243911b..cd67f6e0 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -32,22 +32,21 @@ #define GOOGLE_PROTOBUF_MAP_ENTRY_LITE_H__ #include + +#include #include #include namespace google { namespace protobuf { -class Arena; namespace internal { -template + WireFormatLite::FieldType kValueFieldType, int default_enum_value> class MapEntry; -template + WireFormatLite::FieldType kValueFieldType, int default_enum_value> class MapFieldLite; } // namespace internal } // namespace protobuf @@ -87,13 +86,14 @@ struct MoveHelper { // strings and similar } }; -// MapEntryLite is used to implement parsing and serialization of map for lite -// runtime. -template -class MapEntryLite : public MessageLite { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +class LIBPROTOBUF_EXPORT MapEntryImpl : public Base { + protected: // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. typedef MapTypeHandler KeyTypeHandler; @@ -122,7 +122,30 @@ class MapEntryLite : public MessageLite { static const size_t kTagSize = 1; public: - ~MapEntryLite() { + // Work-around for a compiler bug (see repeated_field.h). + typedef void MapEntryHasMergeTypeTrait; + typedef Derived EntryType; + typedef Key EntryKeyType; + typedef Value EntryValueType; + static const WireFormatLite::FieldType kEntryKeyFieldType = kKeyFieldType; + static const WireFormatLite::FieldType kEntryValueFieldType = kValueFieldType; + static const int kEntryDefaultEnumValue = default_enum_value; + + MapEntryImpl() : default_instance_(NULL), arena_(NULL) { + KeyTypeHandler::Initialize(&key_, NULL); + ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value, + NULL); + _has_bits_[0] = 0; + } + + explicit MapEntryImpl(Arena* arena) : default_instance_(NULL), arena_(arena) { + KeyTypeHandler::Initialize(&key_, arena); + ValueTypeHandler::InitializeMaybeByDefaultEnum(&value_, default_enum_value, + arena); + _has_bits_[0] = 0; + } + + ~MapEntryImpl() { if (this != default_instance_) { if (GetArenaNoVirtual() != NULL) return; KeyTypeHandler::DeleteNoArena(key_); @@ -151,12 +174,12 @@ class MapEntryLite : public MessageLite { // implements MessageLite ========================================= - // MapEntryLite is for implementation only and this function isn't called + // MapEntryImpl is for implementation only and this function isn't called // anywhere. Just provide a fake implementation here for MessageLite. string GetTypeName() const { return ""; } void CheckTypeAndMergeFrom(const MessageLite& other) { - MergeFrom(*::google::protobuf::down_cast(&other)); + MergeFromInternal(*::google::protobuf::down_cast(&other)); } bool MergePartialFromCodedStream(::google::protobuf::io::CodedInputStream* input) { @@ -238,26 +261,29 @@ class MapEntryLite : public MessageLite { bool IsInitialized() const { return ValueTypeHandler::IsInitialized(value_); } - MessageLite* New() const { - MapEntryLite* entry = new MapEntryLite; + Base* New() const { + Derived* entry = new Derived; entry->default_instance_ = default_instance_; return entry; } - MessageLite* New(Arena* arena) const { - MapEntryLite* entry = Arena::CreateMessage(arena); + Base* New(Arena* arena) const { + Derived* entry = Arena::CreateMessage(arena); entry->default_instance_ = default_instance_; return entry; } - int SpaceUsed() const { - int size = sizeof(MapEntryLite); - size += KeyTypeHandler::SpaceUsedInMapEntry(key_); - size += ValueTypeHandler::SpaceUsedInMapEntry(value_); + size_t SpaceUsedLong() const { + size_t size = sizeof(Derived); + size += KeyTypeHandler::SpaceUsedInMapEntryLong(key_); + size += ValueTypeHandler::SpaceUsedInMapEntryLong(value_); return size; } - void MergeFrom(const MapEntryLite& from) { + protected: + // We can't declare this function directly here as it would hide the other + // overload (const Message&). + void MergeFromInternal(const MapEntryImpl& from) { if (from._has_bits_[0]) { if (from.has_key()) { KeyTypeHandler::EnsureMutable(&key_, GetArenaNoVirtual()); @@ -272,6 +298,7 @@ class MapEntryLite : public MessageLite { } } + public: void Clear() { KeyTypeHandler::Clear(&key_, GetArenaNoVirtual()); ValueTypeHandler::ClearMaybeByDefaultEnum( @@ -280,6 +307,10 @@ class MapEntryLite : public MessageLite { clear_has_value(); } + void set_default_instance(MapEntryImpl* default_instance) { + default_instance_ = default_instance; + } + void InitAsDefaultInstance() { KeyTypeHandler::AssignDefaultValue(&key_); ValueTypeHandler::AssignDefaultValue(&value_); @@ -289,24 +320,18 @@ class MapEntryLite : public MessageLite { return GetArenaNoVirtual(); } - // Create a MapEntryLite for given key and value from google::protobuf::Map in + // Create a MapEntryImpl for given key and value from google::protobuf::Map in // serialization. This function is only called when value is enum. Enum is // treated differently because its type in MapEntry is int and its type in // google::protobuf::Map is enum. We cannot create a reference to int from an enum. - static MapEntryLite* EnumWrap(const Key& key, const Value value, - Arena* arena) { - return Arena::CreateMessage >( - arena, key, value); + static Derived* EnumWrap(const Key& key, const Value value, Arena* arena) { + return Arena::CreateMessage(arena, key, value); } // Like above, but for all the other types. This avoids value copy to create - // MapEntryLite from google::protobuf::Map in serialization. - static MapEntryLite* Wrap(const Key& key, const Value& value, Arena* arena) { - return Arena::CreateMessage >( - arena, key, value); + // MapEntryImpl from google::protobuf::Map in serialization. + static Derived* Wrap(const Key& key, const Value& value, Arena* arena) { + return Arena::CreateMessage(arena, key, value); } // Parsing using MergePartialFromCodedStream, above, is not as @@ -411,7 +436,7 @@ class MapEntryLite : public MessageLite { Value* value_ptr_; // On the fast path entry_ is not used. And, when entry_ is used, it's set // to mf_->NewEntry(), so in the arena case we must call entry_.release. - google::protobuf::scoped_ptr entry_; + google::protobuf::scoped_ptr entry_; }; protected: @@ -433,21 +458,17 @@ class MapEntryLite : public MessageLite { // involves copy of key and value to construct a MapEntry. In order to avoid // this copy in constructing a MapEntry, we need the following class which // only takes references of given key and value. - template - class MapEntryWrapper - : public MapEntryLite { - typedef MapEntryLite Base; - typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType; - typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType; + class MapEntryWrapper : public Derived { + typedef Derived BaseClass; + typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType; + typedef + typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType; public: - MapEntryWrapper(Arena* arena, const K& key, const V& value) - : MapEntryLite(arena), - key_(key), - value_(value) { - Base::set_has_key(); - Base::set_has_value(); + MapEntryWrapper(Arena* arena, const Key& key, const Value& value) + : Derived(arena), key_(key), value_(value) { + BaseClass::set_has_key(); + BaseClass::set_has_value(); } inline const KeyMapEntryAccessorType& key() const { return key_; } inline const ValueMapEntryAccessorType& value() const { return value_; } @@ -467,21 +488,17 @@ class MapEntryLite : public MessageLite { // initialize a reference to int with a reference to enum, compiler will // generate a temporary int from enum and initialize the reference to int with // the temporary. - template - class MapEnumEntryWrapper - : public MapEntryLite { - typedef MapEntryLite Base; - typedef typename Base::KeyMapEntryAccessorType KeyMapEntryAccessorType; - typedef typename Base::ValueMapEntryAccessorType ValueMapEntryAccessorType; + class MapEnumEntryWrapper : public Derived { + typedef Derived BaseClass; + typedef typename BaseClass::KeyMapEntryAccessorType KeyMapEntryAccessorType; + typedef + typename BaseClass::ValueMapEntryAccessorType ValueMapEntryAccessorType; public: - MapEnumEntryWrapper(Arena* arena, const K& key, const V& value) - : MapEntryLite(arena), - key_(key), - value_(value) { - Base::set_has_key(); - Base::set_has_value(); + MapEnumEntryWrapper(Arena* arena, const Key& key, const Value& value) + : Derived(arena), key_(key), value_(value) { + BaseClass::set_has_key(); + BaseClass::set_has_value(); } inline const KeyMapEntryAccessorType& key() const { return key_; } inline const ValueMapEntryAccessorType& value() const { return value_; } @@ -494,30 +511,11 @@ class MapEntryLite : public MessageLite { typedef void DestructorSkippable_; }; - MapEntryLite() : default_instance_(NULL), arena_(NULL) { - KeyTypeHandler::Initialize(&key_, NULL); - ValueTypeHandler::InitializeMaybeByDefaultEnum( - &value_, default_enum_value, NULL); - _has_bits_[0] = 0; - } - - explicit MapEntryLite(Arena* arena) - : default_instance_(NULL), arena_(arena) { - KeyTypeHandler::Initialize(&key_, arena); - ValueTypeHandler::InitializeMaybeByDefaultEnum( - &value_, default_enum_value, arena); - _has_bits_[0] = 0; - } - inline Arena* GetArenaNoVirtual() const { return arena_; } - void set_default_instance(MapEntryLite* default_instance) { - default_instance_ = default_instance; - } - - MapEntryLite* default_instance_; + MapEntryImpl* default_instance_; KeyOnMemory key_; ValueOnMemory value_; @@ -527,14 +525,33 @@ class MapEntryLite : public MessageLite { friend class ::google::protobuf::Arena; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - template friend class internal::MapEntry; - template friend class internal::MapFieldLite; - GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryLite); + GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntryImpl); +}; + +template +class LIBPROTOBUF_EXPORT MapEntryLite + : public MapEntryImpl, + MessageLite, Key, Value, kKeyFieldType, + kValueFieldType, default_enum_value> { + public: + typedef MapEntryImpl + SuperType; + MapEntryLite() {} + explicit MapEntryLite(Arena* arena) : SuperType(arena) {} + void MergeFrom(const MapEntryLite& other) { + MergeFromInternal(other); + } }; // Helpers for deterministic serialization ============================= diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 49f91818..4cde0aaa 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -37,31 +37,6 @@ namespace google { namespace protobuf { namespace internal { -ProtobufOnceType map_entry_default_instances_once_; -Mutex* map_entry_default_instances_mutex_; -vector* map_entry_default_instances_; - -void DeleteMapEntryDefaultInstances() { - for (int i = 0; i < map_entry_default_instances_->size(); ++i) { - delete map_entry_default_instances_->at(i); - } - delete map_entry_default_instances_mutex_; - delete map_entry_default_instances_; -} - -void InitMapEntryDefaultInstances() { - map_entry_default_instances_mutex_ = new Mutex(); - map_entry_default_instances_ = new vector(); - OnShutdown(&DeleteMapEntryDefaultInstances); -} - -void RegisterMapEntryDefaultInstance(MessageLite* default_instance) { - ::google::protobuf::GoogleOnceInit(&map_entry_default_instances_once_, - &InitMapEntryDefaultInstances); - MutexLock lock(map_entry_default_instances_mutex_); - map_entry_default_instances_->push_back(default_instance); -} - MapFieldBase::~MapFieldBase() { if (repeated_field_ != NULL && arena_ == NULL) delete repeated_field_; } @@ -77,27 +52,21 @@ RepeatedPtrFieldBase* MapFieldBase::MutableRepeatedField() { return repeated_field_; } -int MapFieldBase::SpaceUsedExcludingSelf() const { +size_t MapFieldBase::SpaceUsedExcludingSelfLong() const { mutex_.Lock(); - int size = SpaceUsedExcludingSelfNoLock(); + size_t size = SpaceUsedExcludingSelfNoLock(); mutex_.Unlock(); return size; } -int MapFieldBase::SpaceUsedExcludingSelfNoLock() const { +size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const { if (repeated_field_ != NULL) { - return repeated_field_->SpaceUsedExcludingSelf(); + return repeated_field_->SpaceUsedExcludingSelfLong(); } else { return 0; } } -void MapFieldBase::InitMetadataOnce() const { - GOOGLE_CHECK(entry_descriptor_ != NULL); - GOOGLE_CHECK(assign_descriptor_callback_ != NULL); - (*assign_descriptor_callback_)(); -} - void MapFieldBase::SetMapDirty() { state_ = STATE_MODIFIED_MAP; } void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; } @@ -421,13 +390,13 @@ void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const { } } -int DynamicMapField::SpaceUsedExcludingSelfNoLock() const { - int size = 0; +size_t DynamicMapField::SpaceUsedExcludingSelfNoLock() const { + size_t size = 0; if (MapFieldBase::repeated_field_ != NULL) { - size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelf(); + size += MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); } size += sizeof(map_); - int map_size = map_.size(); + size_t map_size = map_.size(); if (map_size) { Map::const_iterator it = map_.begin(); size += sizeof(it->first) * map_size; @@ -456,7 +425,7 @@ int DynamicMapField::SpaceUsedExcludingSelfNoLock() const { case google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE: { while (it != map_.end()) { const Message& message = it->second.GetMessageValue(); - size += message.GetReflection()->SpaceUsed(message); + size += message.GetReflection()->SpaceUsedLong(message); ++it; } break; diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index d6af8532..6d904076 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -62,14 +63,10 @@ class LIBPROTOBUF_EXPORT MapFieldBase { MapFieldBase() : arena_(NULL), repeated_field_(NULL), - entry_descriptor_(NULL), - assign_descriptor_callback_(NULL), state_(STATE_MODIFIED_MAP) {} explicit MapFieldBase(Arena* arena) : arena_(arena), repeated_field_(NULL), - entry_descriptor_(NULL), - assign_descriptor_callback_(NULL), state_(STATE_MODIFIED_MAP) { // Mutex's destructor needs to be called explicitly to release resources // acquired in its constructor. @@ -99,11 +96,15 @@ class LIBPROTOBUF_EXPORT MapFieldBase { // Returns the number of bytes used by the repeated field, excluding // sizeof(*this) - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } protected: // Gets the size of space used by map field. - virtual int SpaceUsedExcludingSelfNoLock() const; + virtual size_t SpaceUsedExcludingSelfNoLock() const; // Synchronizes the content in Map to RepeatedPtrField if there is any change // to Map after last synchronization. @@ -124,9 +125,6 @@ class LIBPROTOBUF_EXPORT MapFieldBase { // Provides derived class the access to repeated field. void* MutableRepeatedPtrField() const; - // Creates descriptor for only one time. - void InitMetadataOnce() const; - enum State { STATE_MODIFIED_MAP = 0, // map has newly added data that has not been // synchronized to repeated field @@ -137,13 +135,6 @@ class LIBPROTOBUF_EXPORT MapFieldBase { Arena* arena_; mutable RepeatedPtrField* repeated_field_; - // MapEntry can only be created from MapField. To create MapEntry, MapField - // needs to know its descriptor, because MapEntry is not generated class which - // cannot initialize its own descriptor by calling generated - // descriptor-assign-function. Thus, we need to register a callback to - // initialize MapEntry's descriptor. - const Descriptor** entry_descriptor_; - void (*assign_descriptor_callback_)(); mutable Mutex mutex_; // The thread to synchronize map and repeated field // needs to get lock first; @@ -211,27 +202,24 @@ class TypeDefinedMapFieldBase : public MapFieldBase { // This class provides access to map field using generated api. It is used for // internal generated message implentation only. Users should never use this // directly. -template -class MapField : public TypeDefinedMapFieldBase, - public MapFieldLite { + WireFormatLite::FieldType kValueFieldType, int default_enum_value = 0> +class MapField : public TypeDefinedMapFieldBase { // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. typedef MapTypeHandler KeyTypeHandler; typedef MapTypeHandler ValueTypeHandler; // Define message type for internal repeated field. - typedef MapEntry - EntryType; + typedef Derived EntryType; typedef MapEntryLite EntryLiteType; // Define abbreviation for parent MapFieldLite - typedef MapFieldLite MapFieldLiteType; + typedef MapFieldLite + MapFieldLiteType; // 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 @@ -241,58 +229,62 @@ class MapField : public TypeDefinedMapFieldBase, typedef typename MapIf::type CastValueType; public: - MapField(); - explicit MapField(Arena* arena); - // MapField doesn't own the default_entry, which means default_entry must - // outlive the lifetime of MapField. - MapField(const Message* default_entry); - // For tests only. - MapField(Arena* arena, const Message* default_entry); - ~MapField(); + MapField() {} + explicit MapField(Arena* arena) + : TypeDefinedMapFieldBase(arena), impl_(arena) {} // Implement MapFieldBase bool ContainsMapKey(const MapKey& map_key) const; bool InsertOrLookupMapValue(const MapKey& map_key, MapValueRef* val); bool DeleteMapValue(const MapKey& map_key); - // Accessors - const Map& GetMap() const; - Map* MutableMap(); + const Map& GetMap() const { + MapFieldBase::SyncMapWithRepeatedField(); + return impl_.GetMap(); + } + + Map* MutableMap() { + MapFieldBase::SyncMapWithRepeatedField(); + Map* result = impl_.MutableMap(); + MapFieldBase::SetMapDirty(); + return result; + } // Convenient methods for generated message implementation. int size() const; void Clear(); - void MergeFrom(const MapFieldLiteType& other); - void Swap(MapFieldLiteType* other); - - // Allocates metadata only if this MapField is part of a generated message. - void SetEntryDescriptor(const Descriptor** descriptor); - void SetAssignDescriptorCallback(void (*callback)()); + void MergeFrom(const MapField& other); + void Swap(MapField* other); + + // Used in the implementation of parsing. Caller should take the ownership iff + // arena_ is NULL. + EntryType* NewEntry() const { return impl_.NewEntry(); } + // Used in the implementation of serializing enum value type. Caller should + // take the ownership iff arena_ is NULL. + EntryType* NewEnumEntryWrapper(const Key& key, const T t) const { + return impl_.NewEnumEntryWrapper(key, t); + } + // Used in the implementation of serializing other value types. Caller should + // take the ownership iff arena_ is NULL. + EntryType* NewEntryWrapper(const Key& key, const T& t) const { + return impl_.NewEntryWrapper(key, t); + } private: + MapFieldLiteType impl_; + typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - // MapField needs MapEntry's default instance to create new MapEntry. - void InitDefaultEntryOnce() const; - - // Manually set default entry instance. For test only. - void SetDefaultEntryOnce(const EntryType* default_entry) const; - - // Convenient methods to get internal google::protobuf::Map - const Map& GetInternalMap() const; - Map* MutableInternalMap(); - // Implements MapFieldBase void SyncRepeatedFieldWithMapNoLock() const; void SyncMapWithRepeatedFieldNoLock() const; - int SpaceUsedExcludingSelfNoLock() const; + size_t SpaceUsedExcludingSelfNoLock() const; void SetMapIteratorValue(MapIterator* map_iter) const; - mutable const EntryType* default_entry_; - friend class ::google::protobuf::Arena; + friend class MapFieldStateTest; // For testing, it needs raw access to impl_ }; class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase { @@ -318,12 +310,395 @@ class LIBPROTOBUF_EXPORT DynamicMapField: public TypeDefinedMapFieldBase + 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(data_) = value; + } + void SetUInt64Value(uint64 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueRef::SetUInt64Value"); + *reinterpret_cast(data_) = value; + } + void SetInt32Value(int32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueRef::SetInt32Value"); + *reinterpret_cast(data_) = value; + } + void SetUInt32Value(uint32 value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueRef::SetUInt32Value"); + *reinterpret_cast(data_) = value; + } + void SetBoolValue(bool value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, + "MapValueRef::SetBoolValue"); + *reinterpret_cast(data_) = value; + } + // TODO(jieluo) - Checks that enum is member. + void SetEnumValue(int value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, + "MapValueRef::SetEnumValue"); + *reinterpret_cast(data_) = value; + } + void SetStringValue(const string& value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueRef::SetStringValue"); + *reinterpret_cast(data_) = value; + } + void SetFloatValue(float value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueRef::SetFloatValue"); + *reinterpret_cast(data_) = value; + } + void SetDoubleValue(double value) { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueRef::SetDoubleValue"); + *reinterpret_cast(data_) = value; + } + + int64 GetInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT64, + "MapValueRef::GetInt64Value"); + return *reinterpret_cast(data_); + } + uint64 GetUInt64Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT64, + "MapValueRef::GetUInt64Value"); + return *reinterpret_cast(data_); + } + int32 GetInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_INT32, + "MapValueRef::GetInt32Value"); + return *reinterpret_cast(data_); + } + uint32 GetUInt32Value() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_UINT32, + "MapValueRef::GetUInt32Value"); + return *reinterpret_cast(data_); + } + bool GetBoolValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_BOOL, + "MapValueRef::GetBoolValue"); + return *reinterpret_cast(data_); + } + int GetEnumValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_ENUM, + "MapValueRef::GetEnumValue"); + return *reinterpret_cast(data_); + } + const string& GetStringValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_STRING, + "MapValueRef::GetStringValue"); + return *reinterpret_cast(data_); + } + float GetFloatValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_FLOAT, + "MapValueRef::GetFloatValue"); + return *reinterpret_cast(data_); + } + double GetDoubleValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_DOUBLE, + "MapValueRef::GetDoubleValue"); + return *reinterpret_cast(data_); + } + + const Message& GetMessageValue() const { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueRef::GetMessageValue"); + return *reinterpret_cast(data_); + } + + Message* MutableMessageValue() { + TYPE_CHECK(FieldDescriptor::CPPTYPE_MESSAGE, + "MapValueRef::MutableMessageValue"); + return reinterpret_cast(data_); + } + + private: + template + friend class internal::MapField; + template + 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(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(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 + class LIBPROTOBUF_EXPORT MapIterator { public: MapIterator(Message* message, const FieldDescriptor* field) { @@ -373,7 +748,7 @@ class LIBPROTOBUF_EXPORT MapIterator { template friend class internal::TypeDefinedMapFieldBase; friend class internal::DynamicMapField; - template @@ -392,6 +767,42 @@ class LIBPROTOBUF_EXPORT MapIterator { }; } // namespace protobuf - } // namespace google + +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START +template<> +struct hash { + size_t + operator()(const google::protobuf::MapKey& map_key) const { + switch (map_key.type()) { + 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) << "Unsupported"; + break; + case google::protobuf::FieldDescriptor::CPPTYPE_STRING: + return hash()(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()(map_key.GetBoolValue()); + } + GOOGLE_LOG(FATAL) << "Can't get here."; + return 0; + } + bool + operator()(const google::protobuf::MapKey& map_key1, + const google::protobuf::MapKey& map_key2) const { + return map_key1 < map_key2; + } +}; +GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END + #endif // GOOGLE_PROTOBUF_MAP_FIELD_H__ diff --git a/src/google/protobuf/map_field_inl.h b/src/google/protobuf/map_field_inl.h index 2d84b0a3..8c5da3c6 100644 --- a/src/google/protobuf/map_field_inl.h +++ b/src/google/protobuf/map_field_inl.h @@ -162,81 +162,32 @@ void TypeDefinedMapFieldBase::CopyIterator( // ---------------------------------------------------------------------- -template -MapField::MapField() - : default_entry_(NULL) {} - -template -MapField::MapField( - Arena* arena) - : TypeDefinedMapFieldBase(arena), - MapFieldLite( - arena), - default_entry_(NULL) {} - -template -MapField::MapField( - const Message* default_entry) - : default_entry_(down_cast(default_entry)) {} - -template -MapField::MapField( - Arena* arena, const Message* default_entry) - : TypeDefinedMapFieldBase(arena), - MapFieldLite( - arena), - default_entry_(down_cast(default_entry)) {} - -template -MapField::~MapField() {} - -template -int -MapField::size() const { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +int MapField::size() const { MapFieldBase::SyncMapWithRepeatedField(); - return MapFieldLiteType::GetInternalMap().size(); + return impl_.GetMap().size(); } -template -void -MapField::Clear() { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::Clear() { MapFieldBase::SyncMapWithRepeatedField(); - MapFieldLiteType::MutableInternalMap()->clear(); + impl_.MutableMap()->clear(); MapFieldBase::SetMapDirty(); } -template -void MapField::SetMapIteratorValue( - MapIterator* map_iter) const { - const Map& map = GetMap(); + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::SetMapIteratorValue(MapIterator* map_iter) + const { + const Map& map = impl_.GetMap(); typename Map::const_iterator iter = TypeDefinedMapFieldBase::InternalGetIterator(map_iter); if (iter == map.end()) return; @@ -244,27 +195,23 @@ void MapFieldvalue_.SetValue(&iter->second); } -template -bool MapField::ContainsMapKey( - const MapKey& map_key) const { - const Map& map = GetMap(); + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +bool MapField::ContainsMapKey(const MapKey& map_key) const { + const Map& map = impl_.GetMap(); const Key& key = UnwrapMapKey(map_key); typename Map::const_iterator iter = map.find(key); return iter != map.end(); } -template -bool MapField::InsertOrLookupMapValue( - const MapKey& map_key, - MapValueRef* val) { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +bool MapField::InsertOrLookupMapValue(const MapKey& map_key, + MapValueRef* val) { // Always use mutable map because users may change the map value by // MapValueRef. Map* map = MutableMap(); @@ -280,118 +227,41 @@ bool MapField -bool MapField::DeleteMapValue( - const MapKey& map_key) { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +bool MapField::DeleteMapValue(const MapKey& map_key) { const Key& key = UnwrapMapKey(map_key); return MutableMap()->erase(key); } -template -const Map& -MapField::GetMap() const { - MapFieldBase::SyncMapWithRepeatedField(); - return MapFieldLiteType::GetInternalMap(); -} - -template -Map* -MapField::MutableMap() { - MapFieldBase::SyncMapWithRepeatedField(); - Map* result = MapFieldLiteType::MutableInternalMap(); - MapFieldBase::SetMapDirty(); - return result; -} - -template -void -MapField::MergeFrom( - const MapFieldLiteType& other) { - const MapField& down_other = down_cast(other); + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::MergeFrom(const MapField& other) { MapFieldBase::SyncMapWithRepeatedField(); - down_other.SyncMapWithRepeatedField(); - MapFieldLiteType::MergeFrom(other); + other.SyncMapWithRepeatedField(); + impl_.MergeFrom(other.impl_); MapFieldBase::SetMapDirty(); } -template -void -MapField::Swap( - MapFieldLiteType* other) { - MapField* down_other = down_cast(other); - std::swap(this->MapFieldBase::repeated_field_, down_other->repeated_field_); - MapFieldLiteType::Swap(other); - std::swap(this->MapFieldBase::state_, down_other->state_); -} - -template -void -MapField::SetEntryDescriptor( - const Descriptor** descriptor) { - this->MapFieldBase::entry_descriptor_ = descriptor; -} - -template -void -MapField::SetAssignDescriptorCallback(void (*callback)()) { - this->MapFieldBase::assign_descriptor_callback_ = callback; -} - -template -const Map& -MapField::GetInternalMap() const { - return MapFieldLiteType::GetInternalMap(); + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::Swap(MapField* other) { + std::swap(MapFieldBase::repeated_field_, other->repeated_field_); + impl_.Swap(&other->impl_); + std::swap(MapFieldBase::state_, other->state_); } -template -Map* -MapField::MutableInternalMap() { - return MapFieldLiteType::MutableInternalMap(); -} - -template -void -MapField::SyncRepeatedFieldWithMapNoLock() const { + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::SyncRepeatedFieldWithMapNoLock() const { if (this->MapFieldBase::repeated_field_ == NULL) { if (this->MapFieldBase::arena_ == NULL) { this->MapFieldBase::repeated_field_ = new RepeatedPtrField(); @@ -401,33 +271,35 @@ MapFieldMapFieldBase::arena_); } } - const Map& map = GetInternalMap(); + const Map& map = impl_.GetMap(); RepeatedPtrField* repeated_field = reinterpret_cast*>( this->MapFieldBase::repeated_field_); repeated_field->Clear(); + // The only way we can get at this point is through reflection and the + // only way we can get the reflection object is by having called GetReflection + // on the encompassing field. So that type must have existed and hence we + // know that this MapEntry default_type has also already been constructed. + // So it's safe to just call internal_default_instance(). + const Message* default_entry = Derived::internal_default_instance(); for (typename Map::const_iterator it = map.begin(); it != map.end(); ++it) { - InitDefaultEntryOnce(); - GOOGLE_CHECK(default_entry_ != NULL); EntryType* new_entry = - down_cast(default_entry_->New(this->MapFieldBase::arena_)); + down_cast(default_entry->New(this->MapFieldBase::arena_)); repeated_field->AddAllocated(new_entry); (*new_entry->mutable_key()) = it->first; (*new_entry->mutable_value()) = it->second; } } -template -void -MapField::SyncMapWithRepeatedFieldNoLock() const { - Map* map = const_cast(this)->MutableInternalMap(); + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +void MapField::SyncMapWithRepeatedFieldNoLock() const { + Map* map = const_cast(this)->impl_.MutableMap(); RepeatedPtrField* repeated_field = reinterpret_cast*>( this->MapFieldBase::repeated_field_); @@ -444,44 +316,24 @@ MapField -int -MapField::SpaceUsedExcludingSelfNoLock() const { - int size = 0; + WireFormatLite::FieldType kValueFieldType, int default_enum_value> +size_t MapField::SpaceUsedExcludingSelfNoLock() const { + size_t size = 0; if (this->MapFieldBase::repeated_field_ != NULL) { - size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelf(); + size += this->MapFieldBase::repeated_field_->SpaceUsedExcludingSelfLong(); } - Map* map = const_cast(this)->MutableInternalMap(); + Map* map = const_cast(this)->impl_.MutableMap(); size += sizeof(*map); - for (typename Map::iterator it = map->begin(); - it != map->end(); ++it) { - size += KeyTypeHandler::SpaceUsedInMap(it->first); - size += ValueTypeHandler::SpaceUsedInMap(it->second); + for (typename Map::iterator it = map->begin(); it != map->end(); + ++it) { + size += KeyTypeHandler::SpaceUsedInMapLong(it->first); + size += ValueTypeHandler::SpaceUsedInMapLong(it->second); } return size; } - -template -void -MapField::InitDefaultEntryOnce() - const { - if (default_entry_ == NULL) { - MapFieldBase::InitMetadataOnce(); - GOOGLE_CHECK(*this->MapFieldBase::entry_descriptor_ != NULL); - default_entry_ = down_cast( - MessageFactory::generated_factory()->GetPrototype( - *this->MapFieldBase::entry_descriptor_)); - } -} - } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/map_field_lite.h b/src/google/protobuf/map_field_lite.h index cb0a4a45..2d102392 100644 --- a/src/google/protobuf/map_field_lite.h +++ b/src/google/protobuf/map_field_lite.h @@ -41,223 +41,69 @@ namespace internal { // This class provides access to map field using generated api. It is used for // internal generated message implentation only. Users should never use this // directly. -template + WireFormatLite::FieldType value_wire_type, int default_enum_value = 0> class MapFieldLite { // Define message type for internal repeated field. - typedef MapEntryLite EntryType; + typedef Derived EntryType; public: - MapFieldLite(); - explicit MapFieldLite(Arena* arena); - virtual ~MapFieldLite(); + MapFieldLite() : arena_(NULL) { SetDefaultEnumValue(); } + + explicit MapFieldLite(Arena* arena) : arena_(arena), map_(arena) { + SetDefaultEnumValue(); + } // Accessors - virtual const Map& GetMap() const; - virtual Map* MutableMap(); + const Map& GetMap() const { return map_; } + Map* MutableMap() { return &map_; } // Convenient methods for generated message implementation. - virtual int size() const; - virtual void Clear(); - virtual void MergeFrom(const MapFieldLite& other); - virtual void Swap(MapFieldLite* other); + int size() const { return map_.size(); } + void Clear() { return map_.clear(); } + void MergeFrom(const MapFieldLite& other) { + for (typename Map::const_iterator it = other.map_.begin(); + it != other.map_.end(); ++it) { + map_[it->first] = it->second; + } + } + void Swap(MapFieldLite* other) { map_.swap(other->map_); } // Set default enum value only for proto2 map field whose value is enum type. - void SetDefaultEnumValue(); + void SetDefaultEnumValue() { + MutableMap()->SetDefaultEnumValue(default_enum_value); + } // Used in the implementation of parsing. Caller should take the ownership iff // arena_ is NULL. - EntryType* NewEntry() const; + EntryType* NewEntry() const { + if (arena_ == NULL) { + return new EntryType(); + } else { + return Arena::CreateMessage(arena_); + } + } // Used in the implementation of serializing enum value type. Caller should // take the ownership iff arena_ is NULL. - EntryType* NewEnumEntryWrapper(const Key& key, const T t) const; + EntryType* NewEnumEntryWrapper(const Key& key, const T t) const { + return EntryType::EnumWrap(key, t, arena_); + } // Used in the implementation of serializing other value types. Caller should // take the ownership iff arena_ is NULL. - EntryType* NewEntryWrapper(const Key& key, const T& t) const; - - protected: - // Convenient methods to get internal google::protobuf::Map - virtual const Map& GetInternalMap() const; - virtual Map* MutableInternalMap(); + EntryType* NewEntryWrapper(const Key& key, const T& t) const { + return EntryType::Wrap(key, t, arena_); + } private: typedef void DestructorSkippable_; Arena* arena_; - Map* map_; + Map map_; friend class ::google::protobuf::Arena; }; -template -MapFieldLite::MapFieldLite() - : arena_(NULL) { - map_ = new Map; - SetDefaultEnumValue(); -} - -template -MapFieldLite::MapFieldLite(Arena* arena) - : arena_(arena) { - map_ = Arena::CreateMessage >(arena); - SetDefaultEnumValue(); -} - -template -MapFieldLite::~MapFieldLite() { - delete map_; -} - -template -const Map& -MapFieldLite::GetMap() const { - return *map_; -} - -template -Map* -MapFieldLite::MutableMap() { - return map_; -} - -template -int -MapFieldLite::size() const { - return map_->size(); -} - -template -void -MapFieldLite::Clear() { - map_->clear(); -} - -template -void -MapFieldLite::MergeFrom( - const MapFieldLite& other) { - for (typename Map::const_iterator it = other.map_->begin(); - it != other.map_->end(); ++it) { - (*map_)[it->first] = it->second; - } -} - -template -void -MapFieldLite::Swap( - MapFieldLite* other) { - std::swap(map_, other->map_); -} - -template -void -MapFieldLite::SetDefaultEnumValue() { - MutableInternalMap()->SetDefaultEnumValue(default_enum_value); -} - -template -const Map& -MapFieldLite::GetInternalMap() const { - return *map_; -} - -template -Map* -MapFieldLite::MutableInternalMap() { - return map_; -} - -#define EntryType \ - MapEntryLite - -template -EntryType* -MapFieldLite::NewEntry() const { - if (arena_ == NULL) { - return new EntryType(); - } else { - return Arena::CreateMessage(arena_); - } -} - -template -EntryType* -MapFieldLite::NewEnumEntryWrapper(const Key& key, - const T t) const { - return EntryType::EnumWrap(key, t, arena_); -} - -template -EntryType* -MapFieldLite::NewEntryWrapper(const Key& key, - const T& t) const { - return EntryType::Wrap(key, t, arena_); -} - -#undef EntryType // True if IsInitialized() is true for value field in all elements of t. T is // expected to be message. It's useful to have this helper here to keep the diff --git a/src/google/protobuf/map_field_test.cc b/src/google/protobuf/map_field_test.cc index dd5061c4..8617a366 100644 --- a/src/google/protobuf/map_field_test.cc +++ b/src/google/protobuf/map_field_test.cc @@ -101,8 +101,10 @@ class MapFieldBaseStub : public MapFieldBase { class MapFieldBasePrimitiveTest : public ::testing::Test { protected: - typedef MapField MapFieldType; + typedef unittest::TestMap::TestMap_MapInt32Int32Entry EntryType; + typedef MapField + MapFieldType; MapFieldBasePrimitiveTest() { // Get descriptors @@ -113,9 +115,7 @@ class MapFieldBasePrimitiveTest : public ::testing::Test { value_descriptor_ = map_descriptor_->FindFieldByName("value"); // Build map field - default_entry_ = - MessageFactory::generated_factory()->GetPrototype(map_descriptor_); - map_field_.reset(new MapFieldType(default_entry_)); + map_field_.reset(new MapFieldType); map_field_base_ = map_field_.get(); map_ = map_field_->MutableMap(); initial_value_map_[0] = 100; @@ -130,7 +130,6 @@ class MapFieldBasePrimitiveTest : public ::testing::Test { const Descriptor* map_descriptor_; const FieldDescriptor* key_descriptor_; const FieldDescriptor* value_descriptor_; - const Message* default_entry_; std::map initial_value_map_; // copy of initial values inserted }; @@ -177,8 +176,7 @@ TEST_F(MapFieldBasePrimitiveTest, Arena) { // repeated fields are allocated from arenas. // NoHeapChecker no_heap; - MapFieldType* map_field = - Arena::CreateMessage(&arena, default_entry_); + MapFieldType* map_field = Arena::CreateMessage(&arena); // Set content in map (*map_field->MutableMap())[100] = 101; @@ -208,19 +206,13 @@ class MapFieldStateTest : public testing::TestWithParam { public: protected: - typedef MapField MapFieldType; - typedef MapFieldLite MapFieldLiteType; + typedef unittest::TestMap::TestMap_MapInt32Int32Entry EntryType; + typedef MapField + MapFieldType; MapFieldStateTest() : state_(GetParam()) { // Build map field - const Descriptor* map_descriptor = - unittest::TestMap::descriptor() - ->FindFieldByName("map_int32_int32") - ->message_type(); - default_entry_ = - MessageFactory::generated_factory()->GetPrototype(map_descriptor); - map_field_.reset(new MapFieldType(default_entry_)); + map_field_.reset(new MapFieldType()); map_field_base_ = map_field_.get(); Expect(map_field_.get(), MAP_DIRTY, 0, 0, true); @@ -257,8 +249,8 @@ class MapFieldStateTest MakeMapDirty(map_field); MapFieldBase* map_field_base = map_field; map_field_base->MutableRepeatedField(); - Map* map = implicit_cast(map_field) - ->MapFieldLiteType::MutableMap(); + // We use MutableMap on impl_ because we don't want to disturb the syncing + Map* map = map_field->impl_.MutableMap(); map->clear(); Expect(map_field, REPEATED_DIRTY, 0, 1, false); @@ -270,8 +262,8 @@ class MapFieldStateTest MapFieldBaseStub* stub = reinterpret_cast(map_field_base); - Map* map = implicit_cast(map_field) - ->MapFieldLiteType::MutableMap(); + // We use MutableMap on impl_ because we don't want to disturb the syncing + Map* map = map_field->impl_.MutableMap(); RepeatedPtrField* repeated_field = stub->InternalRepeatedField(); switch (state) { @@ -302,7 +294,6 @@ class MapFieldStateTest google::protobuf::scoped_ptr map_field_; MapFieldBase* map_field_base_; State state_; - const Message* default_entry_; }; INSTANTIATE_TEST_CASE_P(MapFieldStateTestInstance, MapFieldStateTest, @@ -327,7 +318,7 @@ TEST_P(MapFieldStateTest, MutableMap) { } TEST_P(MapFieldStateTest, MergeFromClean) { - MapFieldType other(default_entry_); + MapFieldType other; AddOneStillClean(&other); map_field_->MergeFrom(other); @@ -342,7 +333,7 @@ TEST_P(MapFieldStateTest, MergeFromClean) { } TEST_P(MapFieldStateTest, MergeFromMapDirty) { - MapFieldType other(default_entry_); + MapFieldType other; MakeMapDirty(&other); map_field_->MergeFrom(other); @@ -357,7 +348,7 @@ TEST_P(MapFieldStateTest, MergeFromMapDirty) { } TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) { - MapFieldType other(default_entry_); + MapFieldType other; MakeRepeatedDirty(&other); map_field_->MergeFrom(other); @@ -372,7 +363,7 @@ TEST_P(MapFieldStateTest, MergeFromRepeatedDirty) { } TEST_P(MapFieldStateTest, SwapClean) { - MapFieldType other(default_entry_); + MapFieldType other; AddOneStillClean(&other); map_field_->Swap(&other); @@ -395,7 +386,7 @@ TEST_P(MapFieldStateTest, SwapClean) { } TEST_P(MapFieldStateTest, SwapMapDirty) { - MapFieldType other(default_entry_); + MapFieldType other; MakeMapDirty(&other); map_field_->Swap(&other); @@ -418,7 +409,7 @@ TEST_P(MapFieldStateTest, SwapMapDirty) { } TEST_P(MapFieldStateTest, SwapRepeatedDirty) { - MapFieldType other(default_entry_); + MapFieldType other; MakeRepeatedDirty(&other); map_field_->Swap(&other); diff --git a/src/google/protobuf/map_proto2_unittest.proto b/src/google/protobuf/map_proto2_unittest.proto index e9360a5a..20d58f90 100644 --- a/src/google/protobuf/map_proto2_unittest.proto +++ b/src/google/protobuf/map_proto2_unittest.proto @@ -84,3 +84,8 @@ message TestMaps { map m_bool = 11; map m_string = 12; } + +// Test maps in submessages. +message TestSubmessageMaps { + optional TestMaps m = 1; +} diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 43fe0f44..3fe44512 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -54,10 +54,13 @@ #include #include #include -#include #include +#include #include #include +#include +#include +#include #include #include #include @@ -70,12 +73,8 @@ #include #include #include -#include -#include -#include -#include #include -#include +#include #include #include #include @@ -97,17 +96,15 @@ void MapTestForceDeterministic() { // Map API Test ===================================================== -// Parameterized tests on whether to use old style maps. -class MapImplTest : public testing::TestWithParam { +class MapImplTest : public ::testing::Test { protected: MapImplTest() - : map_ptr_(new Map(GetParam())), + : map_ptr_(new Map()), map_(*map_ptr_), const_map_(*map_ptr_) { EXPECT_TRUE(map_.empty()); EXPECT_EQ(0, map_.size()); } - ~MapImplTest() {} void ExpectSingleElement(int32 key, int32 value) { EXPECT_FALSE(map_.empty()); @@ -178,7 +175,7 @@ class MapImplTest : public testing::TestWithParam { const Map& const_map_; }; -TEST_P(MapImplTest, OperatorBracket) { +TEST_F(MapImplTest, OperatorBracket) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -192,7 +189,7 @@ TEST_P(MapImplTest, OperatorBracket) { ExpectSingleElement(key, value2); } -TEST_P(MapImplTest, OperatorBracketNonExist) { +TEST_F(MapImplTest, OperatorBracketNonExist) { int32 key = 0; int32 default_value = 0; @@ -200,7 +197,7 @@ TEST_P(MapImplTest, OperatorBracketNonExist) { ExpectSingleElement(key, default_value); } -TEST_P(MapImplTest, MutableAt) { +TEST_F(MapImplTest, MutableAt) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -214,15 +211,15 @@ TEST_P(MapImplTest, MutableAt) { #ifdef PROTOBUF_HAS_DEATH_TEST -TEST_P(MapImplTest, MutableAtNonExistDeathTest) { +TEST_F(MapImplTest, MutableAtNonExistDeathTest) { EXPECT_DEATH(map_.at(0), ""); } -TEST_P(MapImplTest, ImmutableAtNonExistDeathTest) { +TEST_F(MapImplTest, ImmutableAtNonExistDeathTest) { EXPECT_DEATH(const_map_.at(0), ""); } -TEST_P(MapImplTest, UsageErrors) { +TEST_F(MapImplTest, UsageErrors) { MapKey key; key.SetInt64Value(1); EXPECT_DEATH(key.GetUInt64Value(), @@ -239,23 +236,23 @@ TEST_P(MapImplTest, UsageErrors) { #endif // PROTOBUF_HAS_DEATH_TEST -TEST_P(MapImplTest, CountNonExist) { +TEST_F(MapImplTest, CountNonExist) { EXPECT_EQ(0, map_.count(0)); } -TEST_P(MapImplTest, MutableFindNonExist) { +TEST_F(MapImplTest, MutableFindNonExist) { EXPECT_TRUE(map_.end() == map_.find(0)); } -TEST_P(MapImplTest, ImmutableFindNonExist) { +TEST_F(MapImplTest, ImmutableFindNonExist) { EXPECT_TRUE(const_map_.end() == const_map_.find(0)); } -TEST_P(MapImplTest, ConstEnd) { +TEST_F(MapImplTest, ConstEnd) { EXPECT_TRUE(const_map_.end() == const_map_.cend()); } -TEST_P(MapImplTest, GetReferenceFromIterator) { +TEST_F(MapImplTest, GetReferenceFromIterator) { for (int i = 0; i < 10; i++) { map_[i] = i; } @@ -278,7 +275,7 @@ TEST_P(MapImplTest, GetReferenceFromIterator) { } } -TEST_P(MapImplTest, IteratorBasic) { +TEST_F(MapImplTest, IteratorBasic) { map_[0] = 0; // Default constructible (per forward iterator requirements). @@ -320,10 +317,9 @@ static int k2 = 1321555333; // A naive begin() implementation will cause begin() to get slower and slower // if one erases elements at the "front" of the hash map, and we'd like to // avoid that, as std::unordered_map does. -TEST_P(MapImplTest, BeginIsFast) { - // Disable this test for both new and old implementations. - if (/*GetParam()*/true) return; - Map map(false); // This test uses new-style maps only. +TEST_F(MapImplTest, BeginIsFast) { + if (true) return; // TODO(gpike): make this less flaky and re-enable it. + Map map; const int kTestSize = 250000; // Create a random-looking map of size n. Use non-negative integer keys. uint32 frog = 123983; @@ -371,7 +367,7 @@ TEST_P(MapImplTest, BeginIsFast) { // Try to create kTestSize keys that will land in just a few buckets, and // time the insertions, to get a rough estimate of whether an O(n^2) worst case // was triggered. This test is a hacky, but probably better than nothing. -TEST_P(MapImplTest, HashFlood) { +TEST_F(MapImplTest, HashFlood) { const int kTestSize = 1024; // must be a power of 2 std::set s; for (int i = 0; s.size() < kTestSize; i++) { @@ -404,6 +400,22 @@ TEST_P(MapImplTest, HashFlood) { EXPECT_LE(x1, x0 * 20); } +TEST_F(MapImplTest, CopyIteratorStressTest) { + std::vector::iterator> v; + const int kIters = 1e5; + for (uint32 i = 0; i < kIters; i++) { + int32 key = (3 + i * (5 + i * (-8 + i * (62 + i)))) & 0x77777777; + map_[key] = i; + v.push_back(map_.find(key)); + } + for (std::vector::iterator>::const_iterator it = v.begin(); + it != v.end(); it++) { + Map::iterator i = *it; + ASSERT_EQ(i->first, (*it)->first); + ASSERT_EQ(i->second, (*it)->second); + } +} + template static void TestValidityForAllKeysExcept(int key_to_avoid, const T& check_map, @@ -468,11 +480,11 @@ static void TestOldVersusNewIterator(int skip, Map* m) { } // Create and test an n-element Map, with emphasis on iterator correctness. -static void StressTestIterators(int n, bool test_old_style_proto2_maps) { +static void StressTestIterators(int n) { GOOGLE_LOG(INFO) << "StressTestIterators " << n; GOOGLE_CHECK_GT(n, 0); // Create a random-looking map of size n. Use non-negative integer keys. - Map m(test_old_style_proto2_maps); + Map m; uint32 frog = 123987 + n; int last_key = 0; int counter = 0; @@ -530,10 +542,7 @@ static void StressTestIterators(int n, bool test_old_style_proto2_maps) { } } -TEST_P(MapImplTest, IteratorInvalidation) { - // As multiple underlying hash_map implementations do not follow the - // validation requirement, the test is disabled for old-style maps. - if (GetParam()) return; +TEST_F(MapImplTest, IteratorInvalidation) { // Create a set of pseudo-random sizes to test. #ifndef NDEBUG const int kMaxSizeToTest = 100 * 1000; @@ -555,15 +564,12 @@ TEST_P(MapImplTest, IteratorInvalidation) { s.insert(3); // Now, the real work. for (std::set::iterator i = s.begin(); i != s.end(); ++i) { - StressTestIterators(*i, GetParam()); + StressTestIterators(*i); } } // Test that erase() revalidates iterators. -TEST_P(MapImplTest, EraseRevalidates) { - // As multiple underlying hash_map implementations do not follow the - // validation requirement, the test is disabled for old-style maps. - if (GetParam()) return; +TEST_F(MapImplTest, EraseRevalidates) { map_[3] = map_[13] = map_[20] = 0; const int initial_size = map_.size(); EXPECT_EQ(3, initial_size); @@ -595,7 +601,7 @@ bool IsConstHelper(const T& /*t*/) { return true; } -TEST_P(MapImplTest, IteratorConstness) { +TEST_F(MapImplTest, IteratorConstness) { map_[0] = 0; EXPECT_TRUE(IsConstHelper(*map_.cbegin())); EXPECT_TRUE(IsConstHelper(*const_map_.begin())); @@ -608,14 +614,14 @@ bool IsForwardIteratorHelper(T /*t*/) { return false; } -TEST_P(MapImplTest, IteratorCategory) { +TEST_F(MapImplTest, IteratorCategory) { EXPECT_TRUE(IsForwardIteratorHelper( std::iterator_traits::iterator>::iterator_category())); EXPECT_TRUE(IsForwardIteratorHelper(std::iterator_traits< Map::const_iterator>::iterator_category())); } -TEST_P(MapImplTest, InsertSingle) { +TEST_F(MapImplTest, InsertSingle) { int32 key = 0; int32 value1 = 100; int32 value2 = 101; @@ -640,7 +646,7 @@ TEST_P(MapImplTest, InsertSingle) { EXPECT_FALSE(result2.second); } -TEST_P(MapImplTest, InsertByIterator) { +TEST_F(MapImplTest, InsertByIterator) { int32 key1 = 0; int32 key2 = 1; int32 value1a = 100; @@ -663,7 +669,7 @@ TEST_P(MapImplTest, InsertByIterator) { ExpectElements(map1); } -TEST_P(MapImplTest, EraseSingleByKey) { +TEST_F(MapImplTest, EraseSingleByKey) { int32 key = 0; int32 value = 100; @@ -681,7 +687,7 @@ TEST_P(MapImplTest, EraseSingleByKey) { EXPECT_EQ(0, map_.erase(key)); } -TEST_P(MapImplTest, EraseMutipleByKey) { +TEST_F(MapImplTest, EraseMutipleByKey) { // erase in one specific order to trigger corner cases for (int i = 0; i < 5; i++) { map_[i] = i; @@ -708,7 +714,7 @@ TEST_P(MapImplTest, EraseMutipleByKey) { EXPECT_TRUE(map_.end() == map_.find(2)); } -TEST_P(MapImplTest, EraseSingleByIterator) { +TEST_F(MapImplTest, EraseSingleByIterator) { int32 key = 0; int32 value = 100; @@ -723,7 +729,7 @@ TEST_P(MapImplTest, EraseSingleByIterator) { EXPECT_TRUE(map_.begin() == map_.end()); } -TEST_P(MapImplTest, ValidIteratorAfterErase) { +TEST_F(MapImplTest, ValidIteratorAfterErase) { for (int i = 0; i < 10; i++) { map_[i] = i; } @@ -743,7 +749,7 @@ TEST_P(MapImplTest, ValidIteratorAfterErase) { EXPECT_EQ(5, map_.size()); } -TEST_P(MapImplTest, EraseByIterator) { +TEST_F(MapImplTest, EraseByIterator) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -764,7 +770,7 @@ TEST_P(MapImplTest, EraseByIterator) { EXPECT_TRUE(map_.begin() == map_.end()); } -TEST_P(MapImplTest, Clear) { +TEST_F(MapImplTest, Clear) { int32 key = 0; int32 value = 100; @@ -798,16 +804,16 @@ static void CopyConstructorHelper(Arena* arena, Map* m) { EXPECT_EQ(value2, other.at(key2)); } -TEST_P(MapImplTest, CopyConstructorWithArena) { +TEST_F(MapImplTest, CopyConstructorWithArena) { Arena a; CopyConstructorHelper(&a, &map_); } -TEST_P(MapImplTest, CopyConstructorWithoutArena) { +TEST_F(MapImplTest, CopyConstructorWithoutArena) { CopyConstructorHelper(NULL, &map_); } -TEST_P(MapImplTest, IterConstructor) { +TEST_F(MapImplTest, IterConstructor) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -817,15 +823,14 @@ TEST_P(MapImplTest, IterConstructor) { map[key1] = value1; map[key2] = value2; - Map new_map(map.begin(), map.end(), - GetParam()); + Map 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_P(MapImplTest, Assigner) { +TEST_F(MapImplTest, Assigner) { int32 key1 = 0; int32 key2 = 1; int32 value1 = 100; @@ -837,7 +842,7 @@ TEST_P(MapImplTest, Assigner) { map_.insert(map.begin(), map.end()); - Map other(GetParam()); + Map other; int32 key_other = 123; int32 value_other = 321; other[key_other] = value_other; @@ -855,16 +860,9 @@ TEST_P(MapImplTest, Assigner) { EXPECT_EQ(2, other.size()); EXPECT_EQ(value1, other.at(key1)); EXPECT_EQ(value2, other.at(key2)); - - // Try assignment to a map with a different choice of "style." - Map m(!GetParam()); - m = other; - EXPECT_EQ(2, m.size()); - EXPECT_EQ(value1, m.at(key1)); - EXPECT_EQ(value2, m.at(key2)); } -TEST_P(MapImplTest, Rehash) { +TEST_F(MapImplTest, Rehash) { const int test_size = 50; std::map reference_map; for (int i = 0; i < test_size; i++) { @@ -881,7 +879,7 @@ TEST_P(MapImplTest, Rehash) { EXPECT_TRUE(map_.empty()); } -TEST_P(MapImplTest, EqualRange) { +TEST_F(MapImplTest, EqualRange) { int key = 100, key_missing = 101; map_[key] = 100; @@ -905,14 +903,14 @@ TEST_P(MapImplTest, EqualRange) { EXPECT_TRUE(const_map_.end() == const_range.second); } -TEST_P(MapImplTest, ConvertToStdMap) { +TEST_F(MapImplTest, ConvertToStdMap) { map_[100] = 101; std::map std_map(map_.begin(), map_.end()); EXPECT_EQ(1, std_map.size()); EXPECT_EQ(101, std_map[100]); } -TEST_P(MapImplTest, ConvertToStdVectorOfPairs) { +TEST_F(MapImplTest, ConvertToStdVectorOfPairs) { map_[100] = 101; std::vector > std_vec(map_.begin(), map_.end()); EXPECT_EQ(1, std_vec.size()); @@ -920,8 +918,8 @@ TEST_P(MapImplTest, ConvertToStdVectorOfPairs) { EXPECT_EQ(101, std_vec[0].second); } -TEST_P(MapImplTest, SwapSameStyle) { - Map another(GetParam()); // same old_style_ value +TEST_F(MapImplTest, SwapBasic) { + Map another; map_[9398] = 41999; another[9398] = 41999; another[8070] = 42056; @@ -933,23 +931,10 @@ TEST_P(MapImplTest, SwapSameStyle) { testing::Pair(9398, 41999))); } -TEST_P(MapImplTest, SwapDifferentStyle) { - Map another(!GetParam()); // different old_style_ value - map_[9398] = 41999; - another[9398] = 41999; - another[8070] = 42056; - another.swap(map_); - EXPECT_THAT(another, testing::UnorderedElementsAre( - testing::Pair(9398, 41999))); - EXPECT_THAT(map_, testing::UnorderedElementsAre( - testing::Pair(8070, 42056), - testing::Pair(9398, 41999))); -} - -TEST_P(MapImplTest, SwapArena) { +TEST_F(MapImplTest, SwapArena) { Arena arena1, arena2; - Map m1(&arena1, false); - Map m2(&arena2, false); + Map m1(&arena1); + Map m2(&arena2); map_[9398] = 41999; m1[9398] = 41999; m1[8070] = 42056; @@ -969,8 +954,6 @@ TEST_P(MapImplTest, SwapArena) { testing::Pair(9398, 41999))); } -INSTANTIATE_TEST_CASE_P(BoolSequence, MapImplTest, testing::Bool()); - // Map Field Reflection Test ======================================== static int Func(int i, int j) { @@ -2980,6 +2963,27 @@ TEST(MapSerializationTest, Deterministic) { TestDeterministicSerialization(t, "golden_message_maps"); } +TEST(MapSerializationTest, DeterministicSubmessage) { + protobuf_unittest::TestSubmessageMaps p; + protobuf_unittest::TestMaps t; + const string filename = "golden_message_maps"; + string golden; + GOOGLE_CHECK_OK(File::GetContents( + TestSourceDir() + "/google/protobuf/testdata/" + filename, + &golden, true)); + t.ParseFromString(golden); + *(p.mutable_m()) = t; + std::vector v; + // Use multiple attempts to increase the chance of a failure if something is + // buggy. For example, each separate copy of a map might use a different + // randomly-chosen hash function. + const int kAttempts = 10; + for (int i = 0; i < kAttempts; i++) { + protobuf_unittest::TestSubmessageMaps q(p); + ASSERT_EQ(DeterministicSerialization(q), DeterministicSerialization(p)); + } +} + // Text Format Test ================================================= TEST(TextFormatMapTest, SerializeAndParse) { diff --git a/src/google/protobuf/map_test_util_impl.h b/src/google/protobuf/map_test_util_impl.h index b3ba4e06..ad4d1a3d 100644 --- a/src/google/protobuf/map_test_util_impl.h +++ b/src/google/protobuf/map_test_util_impl.h @@ -33,14 +33,9 @@ #include #include +#include -#define EXPECT_TRUE GOOGLE_CHECK -#define ASSERT_TRUE GOOGLE_CHECK -#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) -#define EXPECT_EQ GOOGLE_CHECK_EQ -#define ASSERT_EQ GOOGLE_CHECK_EQ - namespace google { namespace protobuf_unittest {} // forward declaration @@ -265,23 +260,23 @@ void MapTestUtilImpl::ExpectClear(const MapMessage& message) { template void MapTestUtilImpl::ExpectMapFieldsSet(const MapMessage& message) { - EXPECT_EQ(2, message.map_int32_int32().size()); - EXPECT_EQ(2, message.map_int64_int64().size()); - EXPECT_EQ(2, message.map_uint32_uint32().size()); - EXPECT_EQ(2, message.map_uint64_uint64().size()); - EXPECT_EQ(2, message.map_sint32_sint32().size()); - EXPECT_EQ(2, message.map_sint64_sint64().size()); - EXPECT_EQ(2, message.map_fixed32_fixed32().size()); - EXPECT_EQ(2, message.map_fixed64_fixed64().size()); - EXPECT_EQ(2, message.map_sfixed32_sfixed32().size()); - EXPECT_EQ(2, message.map_sfixed64_sfixed64().size()); - 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()); + ASSERT_EQ(2, message.map_int32_int32().size()); + ASSERT_EQ(2, message.map_int64_int64().size()); + ASSERT_EQ(2, message.map_uint32_uint32().size()); + ASSERT_EQ(2, message.map_uint64_uint64().size()); + ASSERT_EQ(2, message.map_sint32_sint32().size()); + ASSERT_EQ(2, message.map_sint64_sint64().size()); + ASSERT_EQ(2, message.map_fixed32_fixed32().size()); + ASSERT_EQ(2, message.map_fixed64_fixed64().size()); + ASSERT_EQ(2, message.map_sfixed32_sfixed32().size()); + ASSERT_EQ(2, message.map_sfixed64_sfixed64().size()); + ASSERT_EQ(2, message.map_int32_float().size()); + ASSERT_EQ(2, message.map_int32_double().size()); + ASSERT_EQ(2, message.map_bool_bool().size()); + ASSERT_EQ(2, message.map_string_string().size()); + ASSERT_EQ(2, message.map_int32_bytes().size()); + ASSERT_EQ(2, message.map_int32_enum().size()); + ASSERT_EQ(2, message.map_int32_foreign_message().size()); EXPECT_EQ(0, message.map_int32_int32().at(0)); EXPECT_EQ(0, message.map_int64_int64().at(0)); diff --git a/src/google/protobuf/map_type_handler.h b/src/google/protobuf/map_type_handler.h index ac987cbc..301b37fe 100644 --- a/src/google/protobuf/map_type_handler.h +++ b/src/google/protobuf/map_type_handler.h @@ -186,9 +186,9 @@ class MapTypeHandler { 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); + static inline size_t SpaceUsedInMapEntryLong(const Type* value); // Return bytes used by value in Map. - static inline int SpaceUsedInMap(const Type& value); + static inline size_t SpaceUsedInMapLong(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 @@ -224,9 +224,7 @@ class MapTypeHandler { static inline void Write(int field, const MapEntryAccessorType& value, \ io::CodedOutputStream* output); \ static inline uint8* InternalWriteToArray( \ - int field, \ - const MapEntryAccessorType& value, \ - bool deterministic, \ + int field, const MapEntryAccessorType& value, bool deterministic, \ uint8* target); \ static inline uint8* WriteToArray(int field, \ const MapEntryAccessorType& value, \ @@ -242,9 +240,9 @@ class MapTypeHandler { 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 size_t SpaceUsedInMapEntryLong(const TypeOnMemory& value); \ + static inline size_t SpaceUsedInMapLong(const TypeOnMemory& value); \ + static inline size_t SpaceUsedInMapLong(const string& value); \ static inline void AssignDefaultValue(TypeOnMemory* value); \ static inline const MapEntryAccessorType& DefaultIfNotInitialized( \ const TypeOnMemory& value, const TypeOnMemory& default_value); \ @@ -467,16 +465,15 @@ MapTypeHandler -inline int -MapTypeHandler::SpaceUsedInMapEntry(const Type* value) { - return value->SpaceUsed(); +inline size_t MapTypeHandler::SpaceUsedInMapEntryLong(const Type* value) { + return value->SpaceUsedLong(); } template -int MapTypeHandler::SpaceUsedInMap( +size_t MapTypeHandler::SpaceUsedInMapLong( const Type& value) { - return value.SpaceUsed(); + return value.SpaceUsedLong(); } template @@ -507,7 +504,7 @@ void MapTypeHandler::DeleteNoArena( template inline void MapTypeHandler::AssignDefaultValue(Type** value) { - *value = const_cast(&Type::default_instance()); + *value = const_cast(Type::internal_default_instance()); } template @@ -559,19 +556,21 @@ inline bool MapTypeHandler \ - inline int \ - MapTypeHandler::SpaceUsedInMapEntry( \ - const TypeOnMemory& value) { \ + inline size_t \ + MapTypeHandler::SpaceUsedInMapEntryLong(const TypeOnMemory& value) { \ return sizeof(value); \ } \ template \ - inline int MapTypeHandler::SpaceUsedInMap(const TypeOnMemory& value) { \ + inline size_t \ + MapTypeHandler::SpaceUsedInMapLong( \ + const TypeOnMemory& value) { \ return sizeof(value); \ } \ template \ - inline int MapTypeHandler::SpaceUsedInMap(const string& value) { \ + inline size_t \ + MapTypeHandler::SpaceUsedInMapLong( \ + const string& value) { \ return sizeof(value); \ } \ template \ @@ -647,14 +646,15 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) return value; \ } \ template \ - inline int \ - MapTypeHandler::SpaceUsedInMapEntry( \ - const TypeOnMemory& value) { \ + inline size_t \ + MapTypeHandler::SpaceUsedInMapEntryLong(const TypeOnMemory& value) { \ return 0; \ } \ template \ - inline int MapTypeHandler::SpaceUsedInMap(const TypeOnMemory& value) { \ + inline size_t \ + MapTypeHandler::SpaceUsedInMapLong( \ + const TypeOnMemory& value) { \ return sizeof(Type); \ } \ template \ @@ -663,11 +663,9 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) *value = 0; \ } \ template \ - inline void \ - MapTypeHandler::ClearMaybeByDefaultEnum(TypeOnMemory* value, \ - Arena* arena, \ - int default_enum_value) { \ + inline void MapTypeHandler:: \ + ClearMaybeByDefaultEnum(TypeOnMemory* value, Arena* arena, \ + int default_enum_value) { \ *value = static_cast(default_enum_value); \ } \ template \ @@ -688,11 +686,9 @@ STRING_OR_BYTES_HANDLER_FUNCTIONS(BYTES) *value = 0; \ } \ template \ - inline void \ - MapTypeHandler::InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ - int default_enum_value, \ - Arena* arena) { \ + inline void MapTypeHandler:: \ + InitializeMaybeByDefaultEnum(TypeOnMemory* value, \ + int default_enum_value, Arena* arena) { \ *value = static_cast(default_enum_value); \ } \ template \ diff --git a/src/google/protobuf/message.cc b/src/google/protobuf/message.cc index 6800e4cd..2134f95f 100644 --- a/src/google/protobuf/message.cc +++ b/src/google/protobuf/message.cc @@ -158,8 +158,8 @@ void Message::SetCachedSize(int /* size */) const { "Must implement one or the other."; } -int Message::SpaceUsed() const { - return GetReflection()->SpaceUsed(*this); +size_t Message::SpaceUsedLong() const { + return GetReflection()->SpaceUsedLong(*this); } bool Message::SerializeToFileDescriptor(int file_descriptor) const { diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 4d14584d..7d9bb8a9 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -245,7 +245,9 @@ class LIBPROTOBUF_EXPORT Message : public MessageLite { // using reflection (rather than the generated code implementation for // ByteSize()). Like ByteSize(), its CPU time is linear in the number of // fields defined for the proto. - virtual int SpaceUsed() const; + virtual size_t SpaceUsedLong() const; + + int SpaceUsed() const { return internal::ToIntSize(SpaceUsedLong()); } // Debugging & Testing---------------------------------------------- @@ -417,7 +419,11 @@ class LIBPROTOBUF_EXPORT Reflection { virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0; // Estimate the amount of memory used by the message object. - virtual int SpaceUsed(const Message& message) const = 0; + virtual size_t SpaceUsedLong(const Message& message) const = 0; + + int SpaceUsed(const Message& message) const { + return internal::ToIntSize(SpaceUsedLong(message)); + } // Check if the given non-repeated field is set. virtual bool HasField(const Message& message, diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index b8cb3f4c..fda84b51 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -222,6 +222,11 @@ bool MessageLite::ParsePartialFromArray(const void* data, int size) { // =================================================================== +uint8* MessageLite::SerializeWithCachedSizesToArray(uint8* target) const { + return InternalSerializeWithCachedSizesToArray( + io::CodedOutputStream::IsDefaultSerializationDeterministic(), target); +} + uint8* MessageLite::InternalSerializeWithCachedSizesToArray( bool deterministic, uint8* target) const { // We only optimize this when using optimize_for = SPEED. In other cases diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 5e5ed306..046a736d 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -42,6 +42,7 @@ #include #include #include +#include namespace google { @@ -248,11 +249,7 @@ class LIBPROTOBUF_EXPORT MessageLite { virtual size_t ByteSizeLong() const = 0; // Legacy ByteSize() API. - int ByteSize() const { - size_t result = ByteSizeLong(); - GOOGLE_DCHECK_LE(result, static_cast(INT_MAX)); - return static_cast(result); - } + int ByteSize() const { return internal::ToIntSize(ByteSizeLong()); } // Serializes the message without recomputing the size. The message must not // have changed since the last call to ByteSize(), and the value returned by @@ -260,11 +257,17 @@ class LIBPROTOBUF_EXPORT MessageLite { virtual void SerializeWithCachedSizes( io::CodedOutputStream* output) const = 0; - // A version of SerializeWithCachedSizesToArray, below, that does - // not guarantee deterministic serialization. - virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const { - return InternalSerializeWithCachedSizesToArray(false, target); - } + // Functions below here are not part of the public interface. It isn't + // enforced, but they should be treated as private, and will be private + // at some future time. Unfortunately the implementation of the "friend" + // keyword in GCC is broken at the moment, but we expect it will be fixed. + + // Like SerializeWithCachedSizes, but writes directly to *target, returning + // a pointer to the byte immediately after the last byte written. "target" + // must point at a byte array of at least ByteSize() bytes. Whether to use + // deterministic serialization, e.g., maps in sorted order, is determined by + // CodedOutputStream::IsDefaultSerializationDeterministic(). + virtual uint8* SerializeWithCachedSizesToArray(uint8* target) const; // Returns the result of the last call to ByteSize(). An embedded message's // size is needed both to serialize it (because embedded messages are @@ -279,16 +282,6 @@ class LIBPROTOBUF_EXPORT MessageLite { // method.) virtual int GetCachedSize() const = 0; - // Functions below here are not part of the public interface. It isn't - // enforced, but they should be treated as private, and will be private - // at some future time. Unfortunately the implementation of the "friend" - // keyword in GCC is broken at the moment, but we expect it will be fixed. - - // Like SerializeWithCachedSizes, but writes directly to *target, returning - // a pointer to the byte immediately after the last byte written. "target" - // must point at a byte array of at least ByteSize() bytes. If deterministic - // is true then we use deterministic serialization, e.g., map keys are sorted. - // FOR INTERNAL USE ONLY! virtual uint8* InternalSerializeWithCachedSizesToArray(bool deterministic, uint8* target) const; diff --git a/src/google/protobuf/message_unittest.cc b/src/google/protobuf/message_unittest.cc index c1b05bc1..0469f4ca 100644 --- a/src/google/protobuf/message_unittest.cc +++ b/src/google/protobuf/message_unittest.cc @@ -551,6 +551,17 @@ TEST(MessageTest, MergeFrom) { ASSERT_EQ(0, dest.repeated_uint64_size()); } +TEST(MessageTest, IsInitialized) { + protobuf_unittest::TestIsInitialized msg; + EXPECT_TRUE(msg.IsInitialized()); + protobuf_unittest::TestIsInitialized::SubMessage* sub_message = msg.mutable_sub_message(); + EXPECT_TRUE(msg.IsInitialized()); + protobuf_unittest::TestIsInitialized::SubMessage::SubGroup* sub_group = sub_message->mutable_subgroup(); + EXPECT_FALSE(msg.IsInitialized()); + sub_group->set_i(1); + EXPECT_TRUE(msg.IsInitialized()); +} + TEST(MessageFactoryTest, GeneratedFactoryLookup) { EXPECT_EQ( MessageFactory::generated_factory()->GetPrototype( diff --git a/src/google/protobuf/metadata.h b/src/google/protobuf/metadata.h index dca1fa45..0a6507c0 100644 --- a/src/google/protobuf/metadata.h +++ b/src/google/protobuf/metadata.h @@ -38,134 +38,13 @@ #ifndef GOOGLE_PROTOBUF_METADATA_H__ #define GOOGLE_PROTOBUF_METADATA_H__ -#include -#include -#include -#include +#include #include namespace google { namespace protobuf { namespace internal { -// This is the representation for messages that support arena allocation. It -// uses a tagged pointer to either store the Arena pointer, if there are no -// unknown fields, or a pointer to a block of memory with both the Arena pointer -// and the UnknownFieldSet, if there are unknown fields. This optimization -// allows for "zero-overhead" storage of the Arena pointer, relative to the -// above baseline implementation. -// -// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to -// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container -// pointer. -template -class InternalMetadataWithArenaBase { - public: - InternalMetadataWithArenaBase() : ptr_(NULL) {} - explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {} - - ~InternalMetadataWithArenaBase() { - if (have_unknown_fields() && arena() == NULL) { - delete PtrValue(); - } - ptr_ = NULL; - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const { - if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->unknown_fields; - } else { - return Derived::default_instance(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() { - if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { - return &PtrValue()->unknown_fields; - } else { - return mutable_unknown_fields_slow(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { - if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { - return PtrValue()->arena; - } else { - return PtrValue(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { - return PtrTag() == kTagContainer; - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* 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 - // different states (direct arena pointer vs. container with UFS) so we - // cannot simply swap ptr_ and then restore the arena pointers. We reuse - // UFS's swap implementation instead. - if (have_unknown_fields() || other->have_unknown_fields()) { - static_cast(this)->DoSwap(other->mutable_unknown_fields()); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) { - if (other.have_unknown_fields()) { - static_cast(this)->DoMergeFrom(other.unknown_fields()); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() { - if (have_unknown_fields()) { - static_cast(this)->DoClear(); - } - } - - GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { - return ptr_; - } - - private: - void* ptr_; - - // Tagged pointer implementation. - enum { - // ptr_ is an Arena*. - kTagArena = 0, - // ptr_ is a Container*. - kTagContainer = 1, - }; - static const intptr_t kPtrTagMask = 1; - static const intptr_t kPtrValueMask = ~kPtrTagMask; - - // Accessors for pointer tag and pointer value. - GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { - return reinterpret_cast(ptr_) & kPtrTagMask; - } - - template U* PtrValue() const { - return reinterpret_cast( - reinterpret_cast(ptr_) & kPtrValueMask); - } - - // If ptr_'s tag is kTagContainer, it points to an instance of this struct. - struct Container { - T unknown_fields; - Arena* arena; - }; - - GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() { - Arena* my_arena = arena(); - Container* container = Arena::Create(my_arena); - ptr_ = reinterpret_cast( - reinterpret_cast(container) | kTagContainer); - container->arena = my_arena; - return &(container->unknown_fields); - } -}; - class InternalMetadataWithArena : public InternalMetadataWithArenaBase { @@ -192,36 +71,6 @@ class InternalMetadataWithArena } }; -// We store unknown fields as a string right now, because there is currently no -// good interface for reading unknown fields into an ArenaString. We may want -// to revisit this to allow unknown fields to be parsed onto the Arena. -class InternalMetadataWithArenaLite - : public InternalMetadataWithArenaBase { - public: - InternalMetadataWithArenaLite() {} - - explicit InternalMetadataWithArenaLite(Arena* arena) - : InternalMetadataWithArenaBase(arena) {} - - void DoSwap(string* other) { - mutable_unknown_fields()->swap(*other); - } - - void DoMergeFrom(const string& other) { - mutable_unknown_fields()->append(other); - } - - void DoClear() { - mutable_unknown_fields()->clear(); - } - - static const string& default_instance() { - return GetEmptyStringAlreadyInited(); - } -}; - } // namespace internal } // namespace protobuf diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h new file mode 100644 index 00000000..840c02e8 --- /dev/null +++ b/src/google/protobuf/metadata_lite.h @@ -0,0 +1,193 @@ +// 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_METADATA_LITE_H__ +#define GOOGLE_PROTOBUF_METADATA_LITE_H__ + +#include +#include +#include + +namespace google { +namespace protobuf { +namespace internal { + +// This is the representation for messages that support arena allocation. It +// uses a tagged pointer to either store the Arena pointer, if there are no +// unknown fields, or a pointer to a block of memory with both the Arena pointer +// and the UnknownFieldSet, if there are unknown fields. This optimization +// allows for "zero-overhead" storage of the Arena pointer, relative to the +// above baseline implementation. +// +// The tagged pointer uses the LSB to disambiguate cases, and uses bit 0 == 0 to +// indicate an arena pointer and bit 0 == 1 to indicate a UFS+Arena-container +// pointer. +template +class InternalMetadataWithArenaBase { + public: + InternalMetadataWithArenaBase() : ptr_(NULL) {} + explicit InternalMetadataWithArenaBase(Arena* arena) : ptr_(arena) {} + + ~InternalMetadataWithArenaBase() { + if (have_unknown_fields() && arena() == NULL) { + delete PtrValue(); + } + ptr_ = NULL; + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE const T& unknown_fields() const { + if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { + return PtrValue()->unknown_fields; + } else { + return Derived::default_instance(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE T* mutable_unknown_fields() { + if (GOOGLE_PREDICT_TRUE(have_unknown_fields())) { + return &PtrValue()->unknown_fields; + } else { + return mutable_unknown_fields_slow(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE Arena* arena() const { + if (GOOGLE_PREDICT_FALSE(have_unknown_fields())) { + return PtrValue()->arena; + } else { + return PtrValue(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE bool have_unknown_fields() const { + return PtrTag() == kTagContainer; + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Swap(Derived* 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 + // different states (direct arena pointer vs. container with UFS) so we + // cannot simply swap ptr_ and then restore the arena pointers. We reuse + // UFS's swap implementation instead. + if (have_unknown_fields() || other->have_unknown_fields()) { + static_cast(this)->DoSwap(other->mutable_unknown_fields()); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void MergeFrom(const Derived& other) { + if (other.have_unknown_fields()) { + static_cast(this)->DoMergeFrom(other.unknown_fields()); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void Clear() { + if (have_unknown_fields()) { + static_cast(this)->DoClear(); + } + } + + GOOGLE_ATTRIBUTE_ALWAYS_INLINE void* raw_arena_ptr() const { + return ptr_; + } + + private: + void* ptr_; + + // Tagged pointer implementation. + enum { + // ptr_ is an Arena*. + kTagArena = 0, + // ptr_ is a Container*. + kTagContainer = 1, + }; + static const intptr_t kPtrTagMask = 1; + static const intptr_t kPtrValueMask = ~kPtrTagMask; + + // Accessors for pointer tag and pointer value. + GOOGLE_ATTRIBUTE_ALWAYS_INLINE int PtrTag() const { + return reinterpret_cast(ptr_) & kPtrTagMask; + } + + template U* PtrValue() const { + return reinterpret_cast( + reinterpret_cast(ptr_) & kPtrValueMask); + } + + // If ptr_'s tag is kTagContainer, it points to an instance of this struct. + struct Container { + T unknown_fields; + Arena* arena; + }; + + GOOGLE_ATTRIBUTE_NOINLINE T* mutable_unknown_fields_slow() { + Arena* my_arena = arena(); + Container* container = Arena::Create(my_arena); + ptr_ = reinterpret_cast( + reinterpret_cast(container) | kTagContainer); + container->arena = my_arena; + return &(container->unknown_fields); + } +}; + +// We store unknown fields as a string right now, because there is currently no +// good interface for reading unknown fields into an ArenaString. We may want +// to revisit this to allow unknown fields to be parsed onto the Arena. +class InternalMetadataWithArenaLite + : public InternalMetadataWithArenaBase { + public: + InternalMetadataWithArenaLite() {} + + explicit InternalMetadataWithArenaLite(Arena* arena) + : InternalMetadataWithArenaBase(arena) {} + + void DoSwap(string* other) { + mutable_unknown_fields()->swap(*other); + } + + void DoMergeFrom(const string& other) { + mutable_unknown_fields()->append(other); + } + + void DoClear() { + mutable_unknown_fields()->clear(); + } + + static const string& default_instance() { + return GetEmptyStringAlreadyInited(); + } +}; + +} // namespace internal +} // namespace protobuf + +} // namespace google +#endif // GOOGLE_PROTOBUF_METADATA_LITE_H__ diff --git a/src/google/protobuf/reflection.h b/src/google/protobuf/reflection.h index d5a6653c..fcb9a435 100755 --- a/src/google/protobuf/reflection.h +++ b/src/google/protobuf/reflection.h @@ -570,8 +570,8 @@ struct RefTypeTraits< typedef RepeatedFieldRefIterator iterator; typedef RepeatedFieldAccessor AccessorType; typedef string AccessorValueType; - typedef string IteratorValueType; - typedef string* IteratorPointerType; + typedef const string IteratorValueType; + typedef const string* IteratorPointerType; static const FieldDescriptor::CppType cpp_type = FieldDescriptor::CPPTYPE_STRING; static const Descriptor* GetMessageFieldDescriptor() { diff --git a/src/google/protobuf/reflection_ops_unittest.cc b/src/google/protobuf/reflection_ops_unittest.cc index 86453170..9cedb342 100644 --- a/src/google/protobuf/reflection_ops_unittest.cc +++ b/src/google/protobuf/reflection_ops_unittest.cc @@ -41,6 +41,7 @@ #include #include #include + #include namespace google { diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index db5893b5..074319e8 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -51,8 +51,9 @@ #include #endif -#include #include +#include +#include #include #include #include @@ -76,6 +77,8 @@ class Message; namespace internal { +class MergePartialFromCodedStreamHelper; + static const int kMinRepeatedFieldAllocationSize = 4; // A utility function for logging that doesn't need any template types. @@ -155,6 +158,7 @@ class RepeatedField PROTOBUF_FINAL { // The new element is uninitialized if |Element| is a POD type. // Should be called only if Capacity() > Size(). Element* AddAlreadyReserved(); + Element* AddNAlreadyReserved(int elements); int Capacity() const; // Like STL resize. Uses value to fill appended elements. @@ -216,7 +220,11 @@ class RepeatedField PROTOBUF_FINAL { // Returns the number of bytes used by the repeated field, excluding // sizeof(*this) - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } // Removes the element referenced by position. // @@ -238,6 +246,11 @@ class RepeatedField PROTOBUF_FINAL { return GetArenaNoVirtual(); } + // For internal use only. + // + // This is public due to it being called by generated code. + inline void InternalSwap(RepeatedField* other); + private: static const int kInitialSize = 0; // A note on the representation here (see also comment below for @@ -276,8 +289,6 @@ class RepeatedField PROTOBUF_FINAL { // Copy the elements of |from| into |to|. void CopyArray(Element* to, const Element* from, int size); - inline void InternalSwap(RepeatedField* other); - // Internal helper expected by Arena methods. inline Arena* GetArenaNoVirtual() const { return (rep_ == NULL) ? NULL : rep_->arena; @@ -303,6 +314,9 @@ class RepeatedField PROTOBUF_FINAL { } } } + + friend class internal::WireFormatLite; + const Element* unsafe_data() const; }; template @@ -321,7 +335,8 @@ namespace internal { // shouldn't be necessary, but our compiler doesn't optimize std::copy very // effectively. template ::value> + bool HasTrivialCopy = + has_trivial_copy::value> struct ElementCopier { void operator()(Element* to, const Element* from, int array_size); }; @@ -335,8 +350,8 @@ namespace internal { // exist on the contained type. In particular, we rely on MergeFrom() existing // as a general proxy for the fact that a copy will work, and we also provide a // specific override for string*. -template -struct TypeImplementsMergeBehavior { +template +struct TypeImplementsMergeBehaviorProbeForMergeFrom { typedef char HasMerge; typedef long HasNoMerge; @@ -360,8 +375,13 @@ struct TypeImplementsMergeBehavior { (sizeof(Check(0)) == sizeof(HasMerge))> type; }; -template<> -struct TypeImplementsMergeBehavior< ::std::string > { +template +struct TypeImplementsMergeBehavior : + TypeImplementsMergeBehaviorProbeForMergeFrom {}; + + +template <> +struct TypeImplementsMergeBehavior< ::std::string> { typedef google::protobuf::internal::true_type type; }; @@ -379,7 +399,7 @@ struct TypeImplementsMergeBehavior< ::std::string > { // static void Merge(const Type& from, Type* to); // // // Only needs to be implemented if SpaceUsedExcludingSelf() is called. -// static int SpaceUsed(const Type&); +// static int SpaceUsedLong(const Type&); // }; class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { protected: @@ -389,10 +409,10 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { friend class GeneratedMessageReflection; // ExtensionSet stores repeated message extensions as - // RepeatedPtrField, but non-lite ExtensionSets need to - // implement SpaceUsed(), and thus need to call SpaceUsedExcludingSelf() - // reinterpreting MessageLite as Message. ExtensionSet also needs to make - // use of AddFromCleared(), which is not part of the public interface. + // RepeatedPtrField, but non-lite ExtensionSets need to implement + // SpaceUsedLong(), and thus need to call SpaceUsedExcludingSelfLong() + // reinterpreting MessageLite as Message. ExtensionSet also needs to make use + // of AddFromCleared(), which is not part of the public interface. friend class ExtensionSet; // The MapFieldBase implementation needs to call protected methods directly, @@ -400,6 +420,10 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { // subclass. friend class MapFieldBase; + // The table-driven MergePartialFromCodedStream implementation needs to + // operate on RepeatedPtrField. + friend class MergePartialFromCodedStreamHelper; + // To parse directly into a proto2 generated class, the upb class GMR_Handlers // needs to be able to modify a RepeatedPtrFieldBase directly. friend class upb::google_opensource::GMR_Handlers; @@ -426,7 +450,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { #if LANG_CXX11 template void Add(typename TypeHandler::Type&& value, - std::enable_if* dummy = NULL); + internal::enable_if* dummy = NULL); #endif template @@ -459,7 +483,7 @@ class LIBPROTOBUF_EXPORT RepeatedPtrFieldBase { void SwapElements(int index1, int index2); template - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; // Advanced memory management -------------------------------------- @@ -583,14 +607,12 @@ class GenericTypeHandler { #if LANG_CXX11 static const bool Moveable = false; #endif + static inline GenericType* New(Arena* arena) { return ::google::protobuf::Arena::CreateMaybeMessage( arena, static_cast(0)); } - // We force NewFromPrototype() to be non-inline to reduce code size: - // else, several other methods get inlined copies of message types' - // constructors. - GOOGLE_ATTRIBUTE_NOINLINE static GenericType* NewFromPrototype( + static inline GenericType* NewFromPrototype( const GenericType* prototype, ::google::protobuf::Arena* arena = NULL); static inline void Delete(GenericType* value, Arena* arena) { if (arena == NULL) { @@ -607,8 +629,8 @@ class GenericTypeHandler { static inline void Clear(GenericType* value) { value->Clear(); } GOOGLE_ATTRIBUTE_NOINLINE static void Merge(const GenericType& from, GenericType* to); - static inline int SpaceUsed(const GenericType& value) { - return value.SpaceUsed(); + static inline size_t SpaceUsedLong(const GenericType& value) { + return value.SpaceUsedLong(); } static inline const Type& default_instance() { return Type::default_instance(); @@ -626,11 +648,9 @@ void GenericTypeHandler::Merge(const GenericType& from, 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. +// NewFromPrototype() and Merge() are not defined inline here, as we will need +// to do a virtual function dispatch anyways to go from Message* to call +// New/Merge. template<> MessageLite* GenericTypeHandler::NewFromPrototype( const MessageLite* prototype, google::protobuf::Arena* arena); @@ -708,7 +728,7 @@ class StringTypeHandler { return Arena::Create(arena); } #if LANG_CXX11 - static inline string* New(Arena* arena, std::string&& value) { + static inline string* New(Arena* arena, string&& value) { return Arena::Create(arena, std::move(value)); } #endif @@ -732,12 +752,11 @@ class StringTypeHandler { static inline const Type& default_instance() { return ::google::protobuf::internal::GetEmptyString(); } - static int SpaceUsed(const string& value) { - return static_cast(sizeof(value)) + StringSpaceUsedExcludingSelf(value); + static size_t SpaceUsedLong(const string& value) { + return sizeof(value) + StringSpaceUsedExcludingSelfLong(value); } }; - } // namespace internal // RepeatedPtrField is like RepeatedField, but used for repeated strings or @@ -842,10 +861,11 @@ class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { // Custom STL-like iterator that iterates over and returns the underlying // pointers to Element rather than Element itself. - typedef internal::RepeatedPtrOverPtrsIterator - pointer_iterator; - typedef internal::RepeatedPtrOverPtrsIterator - const_pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator + pointer_iterator; + typedef internal::RepeatedPtrOverPtrsIterator + const_pointer_iterator; pointer_iterator pointer_begin(); const_pointer_iterator pointer_begin() const; pointer_iterator pointer_end(); @@ -853,7 +873,11 @@ class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { // Returns (an estimate of) the number of bytes used by the repeated field, // excluding sizeof(*this). - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } // Advanced memory management -------------------------------------- // When hardcore memory management becomes necessary -- as it sometimes @@ -970,6 +994,11 @@ class RepeatedPtrField PROTOBUF_FINAL : public internal::RepeatedPtrFieldBase { return GetArenaNoVirtual(); } + // For internal use only. + // + // This is public due to it being called by generated code. + using RepeatedPtrFieldBase::InternalSwap; + private: // Note: RepeatedPtrField SHOULD NOT be subclassed by users. class TypeHandler; @@ -1088,6 +1117,14 @@ inline Element* RepeatedField::AddAlreadyReserved() { return &rep_->elements[current_size_++]; } +template +inline Element* RepeatedField::AddNAlreadyReserved(int elements) { + GOOGLE_DCHECK_LE(current_size_ + elements, total_size_); + Element* ret = &rep_->elements[current_size_]; + current_size_ += elements; + return ret; +} + template inline void RepeatedField::Resize(int new_size, const Element& value) { GOOGLE_DCHECK_GE(new_size, 0); @@ -1208,9 +1245,17 @@ inline const Element* RepeatedField::data() const { return rep_ ? rep_->elements : NULL; } +template +inline const Element* RepeatedField::unsafe_data() const { + GOOGLE_DCHECK(rep_); + return rep_->elements; +} template inline void RepeatedField::InternalSwap(RepeatedField* other) { + GOOGLE_DCHECK(this != other); + GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + std::swap(rep_, other->rep_); std::swap(current_size_, other->current_size_); std::swap(total_size_, other->total_size_); @@ -1219,7 +1264,7 @@ inline void RepeatedField::InternalSwap(RepeatedField* other) { template void RepeatedField::Swap(RepeatedField* other) { if (this == other) return; - if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { + if (GetArenaNoVirtual() == other->GetArenaNoVirtual()) { InternalSwap(other); } else { RepeatedField temp(other->GetArenaNoVirtual()); @@ -1232,7 +1277,6 @@ void RepeatedField::Swap(RepeatedField* other) { template void RepeatedField::UnsafeArenaSwap(RepeatedField* other) { if (this == other) return; - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); InternalSwap(other); } @@ -1274,9 +1318,8 @@ RepeatedField::cend() const { } template -inline int RepeatedField::SpaceUsedExcludingSelf() const { - return rep_ ? - (total_size_ * sizeof(Element) + kRepHeaderSize) : 0; +inline size_t RepeatedField::SpaceUsedExcludingSelfLong() const { + return rep_ ? (total_size_ * sizeof(Element) + kRepHeaderSize) : 0; } // Avoid inlining of Reserve(): new, copy, and delete[] lead to a significant @@ -1288,9 +1331,9 @@ void RepeatedField::Reserve(int new_size) { Arena* arena = GetArenaNoVirtual(); new_size = std::max(google::protobuf::internal::kMinRepeatedFieldAllocationSize, std::max(total_size_ * 2, new_size)); - GOOGLE_CHECK_LE(static_cast(new_size), - (std::numeric_limits::max() - kRepHeaderSize) / - sizeof(Element)) + GOOGLE_DCHECK_LE( + static_cast(new_size), + (std::numeric_limits::max() - kRepHeaderSize) / sizeof(Element)) << "Requested size is too large to fit into size_t."; size_t bytes = kRepHeaderSize + sizeof(Element) * new_size; if (arena == NULL) { @@ -1476,9 +1519,10 @@ inline typename TypeHandler::Type* RepeatedPtrFieldBase::Add( template inline void RepeatedPtrFieldBase::Add( typename TypeHandler::Type&& value, - std::enable_if*) { + internal::enable_if*) { if (rep_ != NULL && current_size_ < rep_->allocated_size) { - cast(rep_->elements[current_size_++]) = std::move(value); + *cast(rep_->elements[current_size_++]) = std::move(value); + return; } if (!rep_ || rep_->allocated_size == total_size_) { Reserve(total_size_ + 1); @@ -1606,11 +1650,11 @@ inline void RepeatedPtrFieldBase::SwapElements(int index1, int index2) { } template -inline int RepeatedPtrFieldBase::SpaceUsedExcludingSelf() const { - int allocated_bytes = total_size_ * sizeof(void*); +inline size_t RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong() const { + size_t allocated_bytes = total_size_ * sizeof(void*); if (rep_ != NULL) { for (int i = 0; i < rep_->allocated_size; ++i) { - allocated_bytes += TypeHandler::SpaceUsed( + allocated_bytes += TypeHandler::SpaceUsedLong( *cast(rep_->elements[i])); } allocated_bytes += kRepHeaderSize; @@ -1819,7 +1863,6 @@ class RepeatedPtrField::TypeHandler : public internal::StringTypeHandler { }; - template inline RepeatedPtrField::RepeatedPtrField() : RepeatedPtrFieldBase() {} @@ -2036,7 +2079,6 @@ inline void RepeatedPtrField::Swap(RepeatedPtrField* other) { template inline void RepeatedPtrField::UnsafeArenaSwap( RepeatedPtrField* other) { - GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); if (this == other) return; RepeatedPtrFieldBase::InternalSwap(other); @@ -2053,8 +2095,8 @@ inline Arena* RepeatedPtrField::GetArenaNoVirtual() const { } template -inline int RepeatedPtrField::SpaceUsedExcludingSelf() const { - return RepeatedPtrFieldBase::SpaceUsedExcludingSelf(); +inline size_t RepeatedPtrField::SpaceUsedExcludingSelfLong() const { + return RepeatedPtrFieldBase::SpaceUsedExcludingSelfLong(); } template @@ -2212,18 +2254,17 @@ class RepeatedPtrIterator // the array. // The VoidPtr template parameter holds the type-agnostic pointer value // referenced by the iterator. It should either be "void *" for a mutable -// iterator, or "const void *" for a constant iterator. -template +// iterator, or "const void* const" for a constant iterator. +template class RepeatedPtrOverPtrsIterator - : public std::iterator { + : public std::iterator { public: typedef RepeatedPtrOverPtrsIterator iterator; - typedef std::iterator< - std::random_access_iterator_tag, Element*> superclass; + typedef std::iterator superclass; // Shadow the value_type in std::iterator<> because const_iterator::value_type // needs to be T, not const T. - typedef typename remove_const::type value_type; + typedef typename remove_const::type value_type; // Let the compiler know that these are type names, so we don't have to // write "typename" in front of them everywhere. @@ -2235,7 +2276,7 @@ class RepeatedPtrOverPtrsIterator explicit RepeatedPtrOverPtrsIterator(VoidPtr* it) : it_(it) {} // dereferenceable - reference operator*() const { return *reinterpret_cast(it_); } + reference operator*() const { return *reinterpret_cast(it_); } pointer operator->() const { return &(operator*()); } // {inc,dec}rementable @@ -2291,6 +2332,9 @@ class RepeatedPtrOverPtrsIterator }; void RepeatedPtrFieldBase::InternalSwap(RepeatedPtrFieldBase* other) { + GOOGLE_DCHECK(this != other); + GOOGLE_DCHECK(GetArenaNoVirtual() == other->GetArenaNoVirtual()); + std::swap(rep_, other->rep_); std::swap(current_size_, other->current_size_); std::swap(total_size_, other->total_size_); @@ -2337,7 +2381,7 @@ RepeatedPtrField::pointer_begin() { template inline typename RepeatedPtrField::const_pointer_iterator RepeatedPtrField::pointer_begin() const { - return const_pointer_iterator(const_cast(raw_mutable_data())); + return const_pointer_iterator(const_cast(raw_data())); } template inline typename RepeatedPtrField::pointer_iterator @@ -2348,7 +2392,7 @@ template inline typename RepeatedPtrField::const_pointer_iterator RepeatedPtrField::pointer_end() const { return const_pointer_iterator( - const_cast(raw_mutable_data() + size())); + const_cast(raw_data() + size())); } diff --git a/src/google/protobuf/repeated_field_reflection_unittest.cc b/src/google/protobuf/repeated_field_reflection_unittest.cc index fcebe5ce..fd466565 100644 --- a/src/google/protobuf/repeated_field_reflection_unittest.cc +++ b/src/google/protobuf/repeated_field_reflection_unittest.cc @@ -189,8 +189,8 @@ TEST(RepeatedFieldReflectionTest, ExtensionFields) { } } -template -void TestRepeatedFieldRefIterator( +template +void TestRepeatedFieldRefIteratorForPrimitive( const Ref& handle, const MessageType& message, ValueType (MessageType::*GetFunc)(int) const) { int index = 0; @@ -202,6 +202,21 @@ void TestRepeatedFieldRefIterator( EXPECT_EQ(handle.size(), index); } +template +void TestRepeatedFieldRefIteratorForString( + const RepeatedFieldRef& handle, const MessageType& message, + ValueType (MessageType::*GetFunc)(int) const) { + int index = 0; + for (typename RepeatedFieldRef::const_iterator it = handle.begin(); + it != handle.end(); ++it) { + // Test both operator* and operator-> + EXPECT_EQ((message.*GetFunc)(index), *it); + EXPECT_EQ((message.*GetFunc)(index).size(), it->size()); + ++index; + } + EXPECT_EQ(handle.size(), index); +} + TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { TestAllTypes message; const Reflection* refl = message.GetReflection(); @@ -312,12 +327,12 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForRegularFields) { } // Test iterators. - TestRepeatedFieldRefIterator(rf_int32, message, - &TestAllTypes::repeated_int32); - TestRepeatedFieldRefIterator(rf_double, message, - &TestAllTypes::repeated_double); - TestRepeatedFieldRefIterator(rf_string, message, - &TestAllTypes::repeated_string); + TestRepeatedFieldRefIteratorForPrimitive(rf_int32, message, + &TestAllTypes::repeated_int32); + TestRepeatedFieldRefIteratorForPrimitive(rf_double, message, + &TestAllTypes::repeated_double); + TestRepeatedFieldRefIteratorForString(rf_string, message, + &TestAllTypes::repeated_string); // Test iterators for message fields. typedef RepeatedFieldRef::iterator MessageIterator; @@ -474,10 +489,10 @@ TEST(RepeatedFieldReflectionTest, RepeatedFieldRefForEnums) { EXPECT_EQ(TestAllTypes::BAZ, message.repeated_nested_enum(i)); } - TestRepeatedFieldRefIterator(enum_ref, message, - &TestAllTypes::repeated_nested_enum); - TestRepeatedFieldRefIterator(int32_ref, message, - &TestAllTypes::repeated_nested_enum); + TestRepeatedFieldRefIteratorForPrimitive(enum_ref, message, + &TestAllTypes::repeated_nested_enum); + TestRepeatedFieldRefIteratorForPrimitive(int32_ref, message, + &TestAllTypes::repeated_nested_enum); // Test Add() mutable_enum_ref.Add(TestAllTypes::FOO); diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index ec1074c9..043cc746 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -45,9 +45,9 @@ #include #include #include -#include #include #include +#include #include namespace google { diff --git a/src/google/protobuf/source_context.pb.cc b/src/google/protobuf/source_context.pb.cc index 50e17da1..3244444a 100644 --- a/src/google/protobuf/source_context.pb.cc +++ b/src/google/protobuf/source_context.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceContext, file_name_), }; @@ -165,7 +180,7 @@ void SourceContext::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* SourceContext::descriptor() { protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const SourceContext& SourceContext::default_instance() { @@ -236,6 +251,9 @@ failure: void SourceContext::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.SourceContext) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string file_name = 1; if (this->file_name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -251,8 +269,10 @@ void SourceContext::SerializeWithCachedSizes( ::google::protobuf::uint8* SourceContext::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.SourceContext) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string file_name = 1; if (this->file_name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -305,6 +325,9 @@ void SourceContext::MergeFrom(const SourceContext& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.SourceContext) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.file_name().size() > 0) { file_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.file_name_); @@ -340,7 +363,7 @@ void SourceContext::InternalSwap(SourceContext* other) { ::google::protobuf::Metadata SourceContext::GetMetadata() const { protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -368,6 +391,7 @@ void SourceContext::set_file_name(::std::string&& value) { } #endif void SourceContext::set_file_name(const char* value) { + GOOGLE_DCHECK(value != NULL); file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 10888385..5eeef140 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -72,6 +76,8 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ return reinterpret_cast( &_SourceContext_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void Swap(SourceContext* other); @@ -94,11 +100,6 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -140,7 +141,7 @@ class LIBPROTOBUF_EXPORT SourceContext : public ::google::protobuf::Message /* @ ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_; ::google::protobuf::internal::ArenaStringPtr file_name_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fsource_5fcontext_2eproto::TableStruct; }; // =================================================================== @@ -172,6 +173,7 @@ inline void SourceContext::set_file_name(::std::string&& value) { } #endif inline void SourceContext::set_file_name(const char* value) { + GOOGLE_DCHECK(value != NULL); file_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value)); // @@protoc_insertion_point(field_set_char:google.protobuf.SourceContext.file_name) diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index a1aa51ec..825810b1 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -19,6 +19,8 @@ namespace google { namespace protobuf { +class Struct_FieldsEntryDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { +} _Struct_FieldsEntry_default_instance_; class StructDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { } _Struct_default_instance_; class ValueDefaultTypeInternal : public ::google::protobuf::internal::ExplicitlyConstructed { @@ -43,37 +45,58 @@ const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[1]; } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Struct, fields_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _internal_metadata_), ~0u, // no _extensions_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, _oneof_case_[0]), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), null_value_), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), number_value_), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), string_value_), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), bool_value_), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), struct_value_), - PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), list_value_), + ~0u, // no _weak_field_map_ + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), null_value_), + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), number_value_), + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), string_value_), + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), bool_value_), + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), struct_value_), + GOOGLE_PROTOBUF_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET((&_Value_default_instance_), list_value_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Value, kind_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListValue, values_), }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { { 0, -1, sizeof(Struct)}, - { 5, -1, sizeof(Value)}, - { 16, -1, sizeof(ListValue)}, + { 6, -1, sizeof(Value)}, + { 18, -1, sizeof(ListValue)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { + reinterpret_cast(&_Struct_FieldsEntry_default_instance_), reinterpret_cast(&_Struct_default_instance_), reinterpret_cast(&_Value_default_instance_), reinterpret_cast(&_ListValue_default_instance_), @@ -87,6 +110,7 @@ void protobuf_AssignDescriptors() { AssignDescriptors( "google/protobuf/struct.proto", schemas, file_default_instances, TableStruct::offsets, factory, file_level_metadata, file_level_enum_descriptors, NULL); +file_level_metadata[0].reflection = Struct::Struct_FieldsEntry::CreateReflection(file_level_metadata[0].descriptor, _Struct_FieldsEntry_default_instance_.get_mutable()); } void protobuf_AssignDescriptorsOnce() { @@ -98,16 +122,6 @@ void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; void protobuf_RegisterTypes(const ::std::string&) { protobuf_AssignDescriptorsOnce(); ::google::protobuf::internal::RegisterAllTypes(file_level_metadata, 4); - const ::google::protobuf::Descriptor* Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor; - ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage( - Struct_FieldsEntry_descriptor, - ::google::protobuf::internal::MapEntry< - ::std::string, - ::google::protobuf::Value, - ::google::protobuf::internal::WireFormatLite::TYPE_STRING, - ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, - 0>::CreateDefaultInstance( - Struct_FieldsEntry_descriptor)); } } // namespace @@ -125,9 +139,12 @@ void TableStruct::InitDefaultsImpl() { GOOGLE_PROTOBUF_VERIFY_VERSION; ::google::protobuf::internal::InitProtobufDefaults(); + _Struct_FieldsEntry_default_instance_.DefaultConstruct(); _Struct_default_instance_.DefaultConstruct(); _Value_default_instance_.DefaultConstruct(); _ListValue_default_instance_.DefaultConstruct(); + _Struct_FieldsEntry_default_instance_.get_mutable()->set_default_instance(_Struct_FieldsEntry_default_instance_.get_mutable()); + _Struct_FieldsEntry_default_instance_.get_mutable()->InitAsDefaultInstance(); _Value_default_instance_.null_value_ = 0; _Value_default_instance_.number_value_ = 0; _Value_default_instance_.string_value_.UnsafeSetDefault( @@ -200,6 +217,20 @@ bool NullValue_IsValid(int value) { // =================================================================== +Struct::Struct_FieldsEntry::Struct_FieldsEntry() {} +Struct::Struct_FieldsEntry::Struct_FieldsEntry(::google::protobuf::Arena* arena) : SuperType(arena) {} +::google::protobuf::Metadata Struct::Struct_FieldsEntry::GetMetadata() const { + protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0]; +} +void Struct::Struct_FieldsEntry::MergeFrom( + const ::google::protobuf::Message& other) { + ::google::protobuf::Message::MergeFrom(other); +} +void Struct::Struct_FieldsEntry::MergeFrom(const Struct_FieldsEntry& other) { + MergeFromInternal(other); +} + #if PROTOBUF_INLINE_NOT_IN_HEADERS #endif // PROTOBUF_INLINE_NOT_IN_HEADERS @@ -233,21 +264,11 @@ Struct::Struct(const Struct& from) _internal_metadata_(NULL), _cached_size_(0) { _internal_metadata_.MergeFrom(from._internal_metadata_); - const ::google::protobuf::Descriptor*& Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor; - fields_.SetAssignDescriptorCallback( - protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce); - fields_.SetEntryDescriptor( - &Struct_FieldsEntry_descriptor); fields_.MergeFrom(from.fields_); // @@protoc_insertion_point(copy_constructor:google.protobuf.Struct) } void Struct::SharedCtor() { - const ::google::protobuf::Descriptor*& Struct_FieldsEntry_descriptor = protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[0].descriptor; - fields_.SetAssignDescriptorCallback( - protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce); - fields_.SetEntryDescriptor( - &Struct_FieldsEntry_descriptor); _cached_size_ = 0; } @@ -277,7 +298,7 @@ void Struct::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Struct::descriptor() { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Struct& Struct::default_instance() { @@ -308,8 +329,8 @@ bool Struct::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(10u)) { - DO_(input->IncrementRecursionDepth()); Struct_FieldsEntry::Parser< ::google::protobuf::internal::MapField< + Struct_FieldsEntry, ::std::string, ::google::protobuf::Value, ::google::protobuf::internal::WireFormatLite::TYPE_STRING, ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, @@ -324,7 +345,6 @@ bool Struct::MergePartialFromCodedStream( } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -352,6 +372,9 @@ failure: void Struct::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Struct) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // map fields = 1; if (!this->fields().empty()) { typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer @@ -412,8 +435,10 @@ void Struct::SerializeWithCachedSizes( ::google::protobuf::uint8* Struct::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Struct) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // map fields = 1; if (!this->fields().empty()) { typedef ::google::protobuf::Map< ::std::string, ::google::protobuf::Value >::const_pointer @@ -527,6 +552,9 @@ void Struct::MergeFrom(const Struct& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Struct) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + fields_.MergeFrom(from.fields_); } @@ -574,7 +602,7 @@ void Struct::InternalSwap(Struct* other) { ::google::protobuf::Metadata Struct::GetMetadata() const { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -701,7 +729,7 @@ void Value::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Value::descriptor() { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Value& Value::default_instance() { @@ -877,6 +905,9 @@ failure: void Value::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // .google.protobuf.NullValue null_value = 1; if (has_null_value()) { ::google::protobuf::internal::WireFormatLite::WriteEnum( @@ -920,8 +951,10 @@ void Value::SerializeWithCachedSizes( ::google::protobuf::uint8* Value::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // .google.protobuf.NullValue null_value = 1; if (has_null_value()) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( @@ -953,14 +986,14 @@ void Value::SerializeWithCachedSizes( if (has_struct_value()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 5, *kind_.struct_value_, false, target); + 5, *kind_.struct_value_, deterministic, target); } // .google.protobuf.ListValue list_value = 6; if (has_list_value()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 6, *kind_.list_value_, false, target); + 6, *kind_.list_value_, deterministic, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Value) @@ -1039,6 +1072,9 @@ void Value::MergeFrom(const Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Value) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + switch (from.kind_case()) { case kNullValue: { set_null_value(from.null_value()); @@ -1115,7 +1151,7 @@ void Value::InternalSwap(Value* other) { ::google::protobuf::Metadata Value::GetMetadata() const { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1211,6 +1247,7 @@ void Value::set_string_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) } void Value::set_string_value(const char* value) { + GOOGLE_DCHECK(value != NULL); if (!has_string_value()) { clear_kind(); set_has_string_value(); @@ -1568,7 +1605,7 @@ void ListValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* ListValue::descriptor() { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[3].descriptor; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const ListValue& ListValue::default_instance() { @@ -1599,13 +1636,11 @@ bool ListValue::MergePartialFromCodedStream( case 1: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(10u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_values())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1633,6 +1668,9 @@ failure: void ListValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.ListValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.Value values = 1; for (unsigned int i = 0, n = this->values_size(); i < n; i++) { ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray( @@ -1644,13 +1682,15 @@ void ListValue::SerializeWithCachedSizes( ::google::protobuf::uint8* ListValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.ListValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // repeated .google.protobuf.Value values = 1; for (unsigned int i = 0, n = this->values_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 1, this->values(i), false, target); + 1, this->values(i), deterministic, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.ListValue) @@ -1698,6 +1738,9 @@ void ListValue::MergeFrom(const ListValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.ListValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + values_.MergeFrom(from.values_); } @@ -1739,13 +1782,13 @@ void ListValue::UnsafeArenaSwap(ListValue* other) { InternalSwap(other); } void ListValue::InternalSwap(ListValue* other) { - values_.UnsafeArenaSwap(&other->values_); + values_.InternalSwap(&other->values_); std::swap(_cached_size_, other->_cached_size_); } ::google::protobuf::Metadata ListValue::GetMetadata() const { protobuf_google_2fprotobuf_2fstruct_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[3]; + return protobuf_google_2fprotobuf_2fstruct_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 043f0c32..816aa794 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -22,12 +22,13 @@ #include #include #include +#include #include #include #include #include // IWYU pragma: export #include // IWYU pragma: export -#include +#include // IWYU pragma: export #include #include #include @@ -40,6 +41,9 @@ LIBPROTOBUF_EXPORT extern ListValueDefaultTypeInternal _ListValue_default_instan class Struct; class StructDefaultTypeInternal; LIBPROTOBUF_EXPORT extern StructDefaultTypeInternal _Struct_default_instance_; +class Struct_FieldsEntry; +class Struct_FieldsEntryDefaultTypeInternal; +LIBPROTOBUF_EXPORT extern Struct_FieldsEntryDefaultTypeInternal _Struct_FieldsEntry_default_instance_; class Value; class ValueDefaultTypeInternal; LIBPROTOBUF_EXPORT extern ValueDefaultTypeInternal _Value_default_instance_; @@ -52,6 +56,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fstruct_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -110,6 +117,8 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc return reinterpret_cast( &_Struct_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void UnsafeArenaSwap(Struct* other); void Swap(Struct* other); @@ -133,11 +142,6 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -181,19 +185,34 @@ class LIBPROTOBUF_EXPORT Struct : public ::google::protobuf::Message /* @@protoc friend class ::google::protobuf::Arena; typedef void InternalArenaConstructable_; typedef void DestructorSkippable_; - typedef ::google::protobuf::internal::MapEntryLite< + public: + class Struct_FieldsEntry : public ::google::protobuf::internal::MapEntry { + public: + typedef ::google::protobuf::internal::MapEntry - Struct_FieldsEntry; + 0 > SuperType; + Struct_FieldsEntry(); + Struct_FieldsEntry(::google::protobuf::Arena* arena); + void MergeFrom(const ::google::protobuf::Message& other) PROTOBUF_FINAL; + void MergeFrom(const Struct_FieldsEntry& other); + static const Message* internal_default_instance() { return reinterpret_cast(&_Struct_FieldsEntry_default_instance_); } + ::google::protobuf::Metadata GetMetadata() const; + }; ::google::protobuf::internal::MapField< + Struct_FieldsEntry, ::std::string, ::google::protobuf::Value, ::google::protobuf::internal::WireFormatLite::TYPE_STRING, ::google::protobuf::internal::WireFormatLite::TYPE_MESSAGE, 0 > fields_; + private: mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -232,6 +251,8 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast( &_Value_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void UnsafeArenaSwap(Value* other); void Swap(Value* other); @@ -255,11 +276,6 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -396,7 +412,7 @@ class LIBPROTOBUF_EXPORT Value : public ::google::protobuf::Message /* @@protoc_ mutable int _cached_size_; ::google::protobuf::uint32 _oneof_case_[1]; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -425,6 +441,8 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro return reinterpret_cast( &_ListValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 3; void UnsafeArenaSwap(ListValue* other); void Swap(ListValue* other); @@ -448,11 +466,6 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -500,7 +513,7 @@ class LIBPROTOBUF_EXPORT ListValue : public ::google::protobuf::Message /* @@pro typedef void DestructorSkippable_; ::google::protobuf::RepeatedPtrField< ::google::protobuf::Value > values_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fstruct_2eproto::TableStruct; }; // =================================================================== @@ -624,6 +637,7 @@ inline void Value::set_string_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Value.string_value) } inline void Value::set_string_value(const char* value) { + GOOGLE_DCHECK(value != NULL); if (!has_string_value()) { clear_kind(); set_has_string_value(); diff --git a/src/google/protobuf/test_util_lite.cc b/src/google/protobuf/test_util_lite.cc index 388c0cbd..79c5abec 100644 --- a/src/google/protobuf/test_util_lite.cc +++ b/src/google/protobuf/test_util_lite.cc @@ -35,14 +35,9 @@ #include #include #include +#include -#define EXPECT_TRUE GOOGLE_CHECK -#define ASSERT_TRUE GOOGLE_CHECK -#define EXPECT_FALSE(COND) GOOGLE_CHECK(!(COND)) -#define EXPECT_EQ GOOGLE_CHECK_EQ -#define ASSERT_EQ GOOGLE_CHECK_EQ - namespace google { namespace protobuf { diff --git a/src/google/protobuf/text_format.cc b/src/google/protobuf/text_format.cc index 778b878e..04c887e0 100644 --- a/src/google/protobuf/text_format.cc +++ b/src/google/protobuf/text_format.cc @@ -74,18 +74,6 @@ inline bool IsOctNumber(const string& str) { (str[1] >= '0' && str[1] < '8')); } -inline bool GetAnyFieldDescriptors(const Message& message, - const FieldDescriptor** type_url_field, - const FieldDescriptor** value_field) { - const Descriptor* descriptor = message.GetDescriptor(); - *type_url_field = descriptor->FindFieldByNumber(1); - *value_field = descriptor->FindFieldByNumber(2); - return (*type_url_field != NULL && - (*type_url_field)->type() == FieldDescriptor::TYPE_STRING && - *value_field != NULL && - (*value_field)->type() == FieldDescriptor::TYPE_BYTES); -} - } // namespace string Message::DebugString() const { @@ -1322,6 +1310,7 @@ bool TextFormat::Parser::ParseFromString(const string& input, return Parse(&input_stream, output); } + bool TextFormat::Parser::Merge(io::ZeroCopyInputStream* input, Message* output) { ParserImpl parser(output->GetDescriptor(), input, error_collector_, @@ -1339,6 +1328,7 @@ bool TextFormat::Parser::MergeFromString(const string& input, return Merge(&input_stream, output); } + bool TextFormat::Parser::MergeUsingImpl(io::ZeroCopyInputStream* /* input */, Message* output, ParserImpl* parser_impl) { @@ -1387,6 +1377,7 @@ bool TextFormat::Parser::ParseFieldValueFromString( return Parser().MergeFromString(input, output); } + // =========================================================================== // The default implementation for FieldValuePrinter. The base class just diff --git a/src/google/protobuf/text_format.h b/src/google/protobuf/text_format.h index 2873d339..560fd391 100644 --- a/src/google/protobuf/text_format.h +++ b/src/google/protobuf/text_format.h @@ -75,8 +75,8 @@ class LIBPROTOBUF_EXPORT TextFormat { io::ZeroCopyOutputStream* output); // Like Print(), but outputs directly to a string. - // Note: output will be cleared before prior to printing, and will - // be left empty even if printing fails. + // Note: output will be cleared prior to printing, and will be left empty + // even if printing fails. static bool PrintToString(const Message& message, string* output); // Like PrintUnknownFields(), but outputs directly to a string. diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index e6441339..422a86b4 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -53,11 +53,11 @@ #include #include #include -#include #include #include #include #include +#include namespace google { diff --git a/src/google/protobuf/timestamp.pb.cc b/src/google/protobuf/timestamp.pb.cc index c1865d93..b2fe28a4 100644 --- a/src/google/protobuf/timestamp.pb.cc +++ b/src/google/protobuf/timestamp.pb.cc @@ -31,11 +31,26 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, seconds_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Timestamp, nanos_), }; @@ -186,7 +201,7 @@ void Timestamp::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Timestamp::descriptor() { protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Timestamp& Timestamp::default_instance() { @@ -266,6 +281,9 @@ failure: void Timestamp::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Timestamp) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 seconds = 1; if (this->seconds() != 0) { ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->seconds(), output); @@ -281,8 +299,10 @@ void Timestamp::SerializeWithCachedSizes( ::google::protobuf::uint8* Timestamp::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Timestamp) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 seconds = 1; if (this->seconds() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->seconds(), target); @@ -341,6 +361,9 @@ void Timestamp::MergeFrom(const Timestamp& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Timestamp) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.seconds() != 0) { set_seconds(from.seconds()); } @@ -394,7 +417,7 @@ void Timestamp::InternalSwap(Timestamp* other) { ::google::protobuf::Metadata Timestamp::GetMetadata() const { protobuf_google_2fprotobuf_2ftimestamp_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2ftimestamp_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index e6fc09a1..f7f669af 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2ftimestamp_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -78,6 +82,8 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro return reinterpret_cast( &_Timestamp_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void UnsafeArenaSwap(Timestamp* other); void Swap(Timestamp* other); @@ -101,11 +107,6 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -154,7 +155,7 @@ class LIBPROTOBUF_EXPORT Timestamp : public ::google::protobuf::Message /* @@pro ::google::protobuf::int64 seconds_; ::google::protobuf::int32 nanos_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftimestamp_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftimestamp_2eproto::TableStruct; }; // =================================================================== diff --git a/src/google/protobuf/timestamp.proto b/src/google/protobuf/timestamp.proto index 67e2eba4..b7cbd175 100644 --- a/src/google/protobuf/timestamp.proto +++ b/src/google/protobuf/timestamp.proto @@ -52,6 +52,8 @@ option objc_class_prefix = "GPB"; // and from RFC 3339 date strings. // See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). // +// # Examples +// // Example 1: Compute Timestamp from POSIX `time()`. // // Timestamp timestamp; @@ -92,6 +94,29 @@ option objc_class_prefix = "GPB"; // timestamp = Timestamp() // timestamp.GetCurrentTime() // +// # JSON Mapping +// +// In JSON format, the Timestamp type is encoded as a string in the +// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +// where {year} is always expressed using four digits while {month}, {day}, +// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +// is required, though only UTC (as indicated by "Z") is presently supported. +// +// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +// 01:30 UTC on January 15, 2017. +// +// In JavaScript, one can convert a Date object to this format using the +// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] +// method. In Python, a standard `datetime.datetime` object can be converted +// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) +// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one +// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( +// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()) +// to obtain a formatter capable of generating timestamps in this format. +// // message Timestamp { diff --git a/src/google/protobuf/type.pb.cc b/src/google/protobuf/type.pb.cc index 017392c9..8f017a89 100644 --- a/src/google/protobuf/type.pb.cc +++ b/src/google/protobuf/type.pb.cc @@ -40,11 +40,30 @@ const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors[3]; } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, fields_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Type, oneofs_), @@ -55,6 +74,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, kind_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, cardinality_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Field, number_), @@ -69,6 +89,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, enumvalue_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Enum, options_), @@ -78,6 +99,7 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, number_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValue, options_), @@ -85,16 +107,17 @@ const ::google::protobuf::uint32 TableStruct::offsets[] = { GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, name_), GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Option, value_), }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { { 0, -1, sizeof(Type)}, - { 10, -1, sizeof(Field)}, - { 24, -1, sizeof(Enum)}, - { 33, -1, sizeof(EnumValue)}, - { 40, -1, sizeof(Option)}, + { 11, -1, sizeof(Field)}, + { 26, -1, sizeof(Enum)}, + { 36, -1, sizeof(EnumValue)}, + { 44, -1, sizeof(Option)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -449,7 +472,7 @@ void Type::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Type::descriptor() { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Type& Type::default_instance() { @@ -504,13 +527,11 @@ bool Type::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_fields())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -535,13 +556,11 @@ bool Type::MergePartialFromCodedStream( case 4: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(34u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -596,6 +615,9 @@ failure: void Type::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Type) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -645,8 +667,10 @@ void Type::SerializeWithCachedSizes( ::google::protobuf::uint8* Type::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Type) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -662,7 +686,7 @@ void Type::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->fields_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->fields(i), false, target); + 2, this->fields(i), deterministic, target); } // repeated string oneofs = 3; @@ -679,14 +703,14 @@ void Type::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 4, this->options(i), false, target); + 4, this->options(i), deterministic, target); } // .google.protobuf.SourceContext source_context = 5; if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 5, *this->source_context_, false, target); + 5, *this->source_context_, deterministic, target); } // .google.protobuf.Syntax syntax = 6; @@ -779,6 +803,9 @@ void Type::MergeFrom(const Type& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Type) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + fields_.MergeFrom(from.fields_); oneofs_.MergeFrom(from.oneofs_); options_.MergeFrom(from.options_); @@ -831,9 +858,9 @@ void Type::UnsafeArenaSwap(Type* other) { InternalSwap(other); } void Type::InternalSwap(Type* other) { - fields_.UnsafeArenaSwap(&other->fields_); - oneofs_.UnsafeArenaSwap(&other->oneofs_); - options_.UnsafeArenaSwap(&other->options_); + fields_.InternalSwap(&other->fields_); + oneofs_.InternalSwap(&other->oneofs_); + options_.InternalSwap(&other->options_); name_.Swap(&other->name_); std::swap(source_context_, other->source_context_); std::swap(syntax_, other->syntax_); @@ -842,7 +869,7 @@ void Type::InternalSwap(Type* other) { ::google::protobuf::Metadata Type::GetMetadata() const { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -862,6 +889,7 @@ void Type::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Type.name) } void Type::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -970,6 +998,7 @@ void Type::set_oneofs(int index, ::std::string&& value) { } #endif void Type::set_oneofs(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); oneofs_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs) } @@ -988,11 +1017,12 @@ void Type::add_oneofs(const ::std::string& value) { } #if LANG_CXX11 void Type::add_oneofs(::std::string&& value) { - oneofs_.Add()->assign(std::move(value)); + oneofs_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) } #endif void Type::add_oneofs(const char* value) { + GOOGLE_DCHECK(value != NULL); oneofs_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs) } @@ -1214,7 +1244,7 @@ void Field::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Field::descriptor() { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Field& Field::default_instance() { @@ -1355,13 +1385,11 @@ bool Field::MergePartialFromCodedStream( case 9: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(74u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -1421,6 +1449,9 @@ failure: void Field::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Field) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // .google.protobuf.Field.Kind kind = 1; if (this->kind() != 0) { ::google::protobuf::internal::WireFormatLite::WriteEnum( @@ -1499,8 +1530,10 @@ void Field::SerializeWithCachedSizes( ::google::protobuf::uint8* Field::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Field) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // .google.protobuf.Field.Kind kind = 1; if (this->kind() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray( @@ -1554,7 +1587,7 @@ void Field::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 9, this->options(i), false, target); + 9, this->options(i), deterministic, target); } // string json_name = 10; @@ -1683,6 +1716,9 @@ void Field::MergeFrom(const Field& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Field) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + options_.MergeFrom(from.options_); if (from.name().size() > 0) { set_name(from.name()); @@ -1751,7 +1787,7 @@ void Field::UnsafeArenaSwap(Field* other) { InternalSwap(other); } void Field::InternalSwap(Field* other) { - options_.UnsafeArenaSwap(&other->options_); + options_.InternalSwap(&other->options_); name_.Swap(&other->name_); type_url_.Swap(&other->type_url_); json_name_.Swap(&other->json_name_); @@ -1766,7 +1802,7 @@ void Field::InternalSwap(Field* other) { ::google::protobuf::Metadata Field::GetMetadata() const { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1828,6 +1864,7 @@ void Field::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.name) } void Field::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1894,6 +1931,7 @@ void Field::set_type_url(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) } void Field::set_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -2018,6 +2056,7 @@ void Field::set_json_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) } void Field::set_json_name(const char* value) { + GOOGLE_DCHECK(value != NULL); json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -2084,6 +2123,7 @@ void Field::set_default_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) } void Field::set_default_value(const char* value) { + GOOGLE_DCHECK(value != NULL); default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -2259,7 +2299,7 @@ void Enum::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Enum::descriptor() { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Enum& Enum::default_instance() { @@ -2313,13 +2353,11 @@ bool Enum::MergePartialFromCodedStream( case 2: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(18u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_enumvalue())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -2327,13 +2365,11 @@ bool Enum::MergePartialFromCodedStream( case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(26u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -2388,6 +2424,9 @@ failure: void Enum::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Enum) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2427,8 +2466,10 @@ void Enum::SerializeWithCachedSizes( ::google::protobuf::uint8* Enum::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Enum) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2444,21 +2485,21 @@ void Enum::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->enumvalue_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, this->enumvalue(i), false, target); + 2, this->enumvalue(i), deterministic, target); } // repeated .google.protobuf.Option options = 3; for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, this->options(i), false, target); + 3, this->options(i), deterministic, target); } // .google.protobuf.SourceContext source_context = 4; if (this->has_source_context()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 4, *this->source_context_, false, target); + 4, *this->source_context_, deterministic, target); } // .google.protobuf.Syntax syntax = 5; @@ -2543,6 +2584,9 @@ void Enum::MergeFrom(const Enum& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Enum) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + enumvalue_.MergeFrom(from.enumvalue_); options_.MergeFrom(from.options_); if (from.name().size() > 0) { @@ -2594,8 +2638,8 @@ void Enum::UnsafeArenaSwap(Enum* other) { InternalSwap(other); } void Enum::InternalSwap(Enum* other) { - enumvalue_.UnsafeArenaSwap(&other->enumvalue_); - options_.UnsafeArenaSwap(&other->options_); + enumvalue_.InternalSwap(&other->enumvalue_); + options_.InternalSwap(&other->options_); name_.Swap(&other->name_); std::swap(source_context_, other->source_context_); std::swap(syntax_, other->syntax_); @@ -2604,7 +2648,7 @@ void Enum::InternalSwap(Enum* other) { ::google::protobuf::Metadata Enum::GetMetadata() const { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2624,6 +2668,7 @@ void Enum::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) } void Enum::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -2878,7 +2923,7 @@ void EnumValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* EnumValue::descriptor() { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[3].descriptor; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const EnumValue& EnumValue::default_instance() { @@ -2941,13 +2986,11 @@ bool EnumValue::MergePartialFromCodedStream( case 3: { if (static_cast< ::google::protobuf::uint8>(tag) == static_cast< ::google::protobuf::uint8>(26u)) { - DO_(input->IncrementRecursionDepth()); - DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( + DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual( input, add_options())); } else { goto handle_unusual; } - input->UnsafeDecrementRecursionDepth(); break; } @@ -2975,6 +3018,9 @@ failure: void EnumValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.EnumValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -3001,8 +3047,10 @@ void EnumValue::SerializeWithCachedSizes( ::google::protobuf::uint8* EnumValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.EnumValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -3023,7 +3071,7 @@ void EnumValue::SerializeWithCachedSizes( for (unsigned int i = 0, n = this->options_size(); i < n; i++) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 3, this->options(i), false, target); + 3, this->options(i), deterministic, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.EnumValue) @@ -3085,6 +3133,9 @@ void EnumValue::MergeFrom(const EnumValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.EnumValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + options_.MergeFrom(from.options_); if (from.name().size() > 0) { set_name(from.name()); @@ -3132,7 +3183,7 @@ void EnumValue::UnsafeArenaSwap(EnumValue* other) { InternalSwap(other); } void EnumValue::InternalSwap(EnumValue* other) { - options_.UnsafeArenaSwap(&other->options_); + options_.InternalSwap(&other->options_); name_.Swap(&other->name_); std::swap(number_, other->number_); std::swap(_cached_size_, other->_cached_size_); @@ -3140,7 +3191,7 @@ void EnumValue::InternalSwap(EnumValue* other) { ::google::protobuf::Metadata EnumValue::GetMetadata() const { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[3]; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -3160,6 +3211,7 @@ void EnumValue::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) } void EnumValue::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -3370,7 +3422,7 @@ void Option::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Option::descriptor() { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[4].descriptor; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Option& Option::default_instance() { @@ -3453,6 +3505,9 @@ failure: void Option::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Option) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -3474,8 +3529,10 @@ void Option::SerializeWithCachedSizes( ::google::protobuf::uint8* Option::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Option) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string name = 1; if (this->name().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -3491,7 +3548,7 @@ void Option::SerializeWithCachedSizes( if (this->has_value()) { target = ::google::protobuf::internal::WireFormatLite:: InternalWriteMessageNoVirtualToArray( - 2, *this->value_, false, target); + 2, *this->value_, deterministic, target); } // @@protoc_insertion_point(serialize_to_array_end:google.protobuf.Option) @@ -3542,6 +3599,9 @@ void Option::MergeFrom(const Option& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Option) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.name().size() > 0) { set_name(from.name()); } @@ -3595,7 +3655,7 @@ void Option::InternalSwap(Option* other) { ::google::protobuf::Metadata Option::GetMetadata() const { protobuf_google_2fprotobuf_2ftype_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[4]; + return protobuf_google_2fprotobuf_2ftype_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -3615,6 +3675,7 @@ void Option::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Option.name) } void Option::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index ae816008..56d77a42 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2ftype_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -181,6 +185,8 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i return reinterpret_cast( &_Type_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void UnsafeArenaSwap(Type* other); void Swap(Type* other); @@ -204,11 +210,6 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -331,7 +332,7 @@ class LIBPROTOBUF_EXPORT Type : public ::google::protobuf::Message /* @@protoc_i ::google::protobuf::SourceContext* source_context_; int syntax_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -360,6 +361,8 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ return reinterpret_cast( &_Field_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void UnsafeArenaSwap(Field* other); void Swap(Field* other); @@ -383,11 +386,6 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -620,7 +618,7 @@ class LIBPROTOBUF_EXPORT Field : public ::google::protobuf::Message /* @@protoc_ ::google::protobuf::int32 oneof_index_; bool packed_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -649,6 +647,8 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i return reinterpret_cast( &_Enum_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void UnsafeArenaSwap(Enum* other); void Swap(Enum* other); @@ -672,11 +672,6 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -776,7 +771,7 @@ class LIBPROTOBUF_EXPORT Enum : public ::google::protobuf::Message /* @@protoc_i ::google::protobuf::SourceContext* source_context_; int syntax_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -805,6 +800,8 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro return reinterpret_cast( &_EnumValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 3; void UnsafeArenaSwap(EnumValue* other); void Swap(EnumValue* other); @@ -828,11 +825,6 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -902,7 +894,7 @@ class LIBPROTOBUF_EXPORT EnumValue : public ::google::protobuf::Message /* @@pro ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::int32 number_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -931,6 +923,8 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc return reinterpret_cast( &_Option_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 4; void UnsafeArenaSwap(Option* other); void Swap(Option* other); @@ -954,11 +948,6 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -1025,7 +1014,7 @@ class LIBPROTOBUF_EXPORT Option : public ::google::protobuf::Message /* @@protoc ::google::protobuf::internal::ArenaStringPtr name_; ::google::protobuf::Any* value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2ftype_2eproto::TableStruct; }; // =================================================================== @@ -1049,6 +1038,7 @@ inline void Type::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Type.name) } inline void Type::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1157,6 +1147,7 @@ inline void Type::set_oneofs(int index, ::std::string&& value) { } #endif inline void Type::set_oneofs(int index, const char* value) { + GOOGLE_DCHECK(value != NULL); oneofs_.Mutable(index)->assign(value); // @@protoc_insertion_point(field_set_char:google.protobuf.Type.oneofs) } @@ -1175,11 +1166,12 @@ inline void Type::add_oneofs(const ::std::string& value) { } #if LANG_CXX11 inline void Type::add_oneofs(::std::string&& value) { - oneofs_.Add()->assign(std::move(value)); + oneofs_.Add(std::move(value)); // @@protoc_insertion_point(field_add:google.protobuf.Type.oneofs) } #endif inline void Type::add_oneofs(const char* value) { + GOOGLE_DCHECK(value != NULL); oneofs_.Add()->assign(value); // @@protoc_insertion_point(field_add_char:google.protobuf.Type.oneofs) } @@ -1353,6 +1345,7 @@ inline void Field::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.name) } inline void Field::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1419,6 +1412,7 @@ inline void Field::set_type_url(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.type_url) } inline void Field::set_type_url(const char* value) { + GOOGLE_DCHECK(value != NULL); type_url_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1543,6 +1537,7 @@ inline void Field::set_json_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.json_name) } inline void Field::set_json_name(const char* value) { + GOOGLE_DCHECK(value != NULL); json_name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1609,6 +1604,7 @@ inline void Field::set_default_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Field.default_value) } inline void Field::set_default_value(const char* value) { + GOOGLE_DCHECK(value != NULL); default_value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1679,6 +1675,7 @@ inline void Enum::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Enum.name) } inline void Enum::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1874,6 +1871,7 @@ inline void EnumValue::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.EnumValue.name) } inline void EnumValue::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1988,6 +1986,7 @@ inline void Option::set_name(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.Option.name) } inline void Option::set_name(const char* value) { + GOOGLE_DCHECK(value != NULL); name_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto index 188a4f47..2040487e 100644 --- a/src/google/protobuf/unittest.proto +++ b/src/google/protobuf/unittest.proto @@ -433,7 +433,14 @@ message TestRecursiveMessage { // Test that mutual recursion works. message TestMutualRecursionA { + message SubMessage { + optional TestMutualRecursionB b = 1; + } optional TestMutualRecursionB bb = 1; + optional group SubGroup = 2 { + optional SubMessage sub_message = 3; // Needed because of bug in javatest + optional TestAllTypes not_in_this_scc = 4; + } } message TestMutualRecursionB { @@ -441,6 +448,15 @@ message TestMutualRecursionB { optional int32 optional_int32 = 2; } +message TestIsInitialized { + message SubMessage { + optional group SubGroup = 1 { + required int32 i = 2; + } + } + optional SubMessage sub_message = 1; +} + // Test that groups have disjoint field numbers from their siblings and // parents. This is NOT possible in proto1; only google.protobuf. When attempting // to compile with proto1, this will emit an error; so we only include it diff --git a/src/google/protobuf/unittest_lazy_dependencies.proto b/src/google/protobuf/unittest_lazy_dependencies.proto new file mode 100644 index 00000000..2f5efd2a --- /dev/null +++ b/src/google/protobuf/unittest_lazy_dependencies.proto @@ -0,0 +1,75 @@ +// 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: trafacz@google.com (Todd Rafacz) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file we will use for unit testing. + +syntax = "proto2"; + +import "google/protobuf/unittest_lazy_dependencies_custom_option.proto"; + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +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 = true; + +// 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.lazy_imports; + +// Protos optimized for SPEED use a strict superset of the generated code +// of equivalent ones optimized for CODE_SIZE, so we should optimize all our +// tests for speed unless explicitly testing code size optimization. +option optimize_for = SPEED; + +option java_outer_classname = "UnittestLazyImportsProto"; + +// The following are used to test that the proto file +// with the definition of the following field types is +// not built when this proto file is built. Then test +// that calling message_type() etc will build the correct +// descriptor lazily and return it. + +message ImportedMessage { + optional LazyMessage lazy_message = 1; +} + +message MessageCustomOption { +} + +message MessageCustomOption2 { + option (lazy_enum_option) = LAZY_ENUM_0; +} diff --git a/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto b/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto new file mode 100644 index 00000000..22438257 --- /dev/null +++ b/src/google/protobuf/unittest_lazy_dependencies_custom_option.proto @@ -0,0 +1,67 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// https://developers.google.com/protocol-buffers/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Author: trafacz@google.com (Todd Rafacz) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file we will use for unit testing. + +syntax = "proto2"; + +import "google/protobuf/unittest_lazy_dependencies_enum.proto"; +import "google/protobuf/descriptor.proto"; + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +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 = true; + +// 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.lazy_imports; + +// Protos optimized for SPEED use a strict superset of the generated code +// of equivalent ones optimized for CODE_SIZE, so we should optimize all our +// tests for speed unless explicitly testing code size optimization. +option optimize_for = SPEED; + +option java_outer_classname = "UnittestLazyImportsCustomOptionProto"; + +message LazyMessage { + optional int32 a = 1; +} + +extend google.protobuf.MessageOptions { + optional LazyEnum lazy_enum_option = 138596335 [default = LAZY_ENUM_1]; +} diff --git a/src/google/protobuf/unittest_lazy_dependencies_enum.proto b/src/google/protobuf/unittest_lazy_dependencies_enum.proto new file mode 100644 index 00000000..9be64d85 --- /dev/null +++ b/src/google/protobuf/unittest_lazy_dependencies_enum.proto @@ -0,0 +1,61 @@ +// 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: trafacz@google.com (Todd Rafacz) +// Based on original Protocol Buffers design by +// Sanjay Ghemawat, Jeff Dean, and others. +// +// A proto file we will use for unit testing. + +syntax = "proto2"; + +// Some generic_services option(s) added automatically. +// See: http://go/proto2-generic-services-default +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 = true; + +// 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.lazy_imports; + +// Protos optimized for SPEED use a strict superset of the generated code +// of equivalent ones optimized for CODE_SIZE, so we should optimize all our +// tests for speed unless explicitly testing code size optimization. +option optimize_for = SPEED; + +option java_outer_classname = "UnittestLazyImportsEnumProto"; + +enum LazyEnum { + LAZY_ENUM_0 = 0; + LAZY_ENUM_1 = 1; +} diff --git a/src/google/protobuf/unittest_proto3_arena.proto b/src/google/protobuf/unittest_proto3_arena.proto index b835a6ba..9375d85a 100644 --- a/src/google/protobuf/unittest_proto3_arena.proto +++ b/src/google/protobuf/unittest_proto3_arena.proto @@ -96,6 +96,8 @@ message TestAllTypes { optional_public_import_message = 26; NestedMessage optional_lazy_message = 27 [lazy=true]; + protobuf_unittest_import.ImportMessage optional_lazy_import_message = 115 + [lazy = true]; // Repeated repeated int32 repeated_int32 = 31; diff --git a/src/google/protobuf/unknown_field_set.cc b/src/google/protobuf/unknown_field_set.cc index 9472c4fa..0ada85e5 100644 --- a/src/google/protobuf/unknown_field_set.cc +++ b/src/google/protobuf/unknown_field_set.cc @@ -123,21 +123,21 @@ void UnknownFieldSet::MergeToInternalMetdata( metadata->mutable_unknown_fields()->MergeFrom(other); } -int UnknownFieldSet::SpaceUsedExcludingSelf() const { +size_t UnknownFieldSet::SpaceUsedExcludingSelfLong() const { if (fields_ == NULL) return 0; - int total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); + size_t total_size = sizeof(*fields_) + sizeof(UnknownField) * fields_->size(); for (int i = 0; i < fields_->size(); i++) { const UnknownField& field = (*fields_)[i]; switch (field.type()) { case UnknownField::TYPE_LENGTH_DELIMITED: - total_size += sizeof(*field.length_delimited_.string_value_) + - internal::StringSpaceUsedExcludingSelf( - *field.length_delimited_.string_value_); + total_size += sizeof(*field.data_.length_delimited_.string_value_) + + internal::StringSpaceUsedExcludingSelfLong( + *field.data_.length_delimited_.string_value_); break; case UnknownField::TYPE_GROUP: - total_size += field.group_->SpaceUsed(); + total_size += field.data_.group_->SpaceUsedLong(); break; default: break; @@ -146,7 +146,7 @@ int UnknownFieldSet::SpaceUsedExcludingSelf() const { return total_size; } -int UnknownFieldSet::SpaceUsed() const { +size_t UnknownFieldSet::SpaceUsedLong() const { return sizeof(*this) + SpaceUsedExcludingSelf(); } @@ -154,7 +154,7 @@ void UnknownFieldSet::AddVarint(int number, uint64 value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_VARINT); - field.varint_ = value; + field.data_.varint_ = value; if (fields_ == NULL) fields_ = new std::vector(); fields_->push_back(field); } @@ -163,7 +163,7 @@ void UnknownFieldSet::AddFixed32(int number, uint32 value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_FIXED32); - field.fixed32_ = value; + field.data_.fixed32_ = value; if (fields_ == NULL) fields_ = new std::vector(); fields_->push_back(field); } @@ -172,7 +172,7 @@ void UnknownFieldSet::AddFixed64(int number, uint64 value) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_FIXED64); - field.fixed64_ = value; + field.data_.fixed64_ = value; if (fields_ == NULL) fields_ = new std::vector(); fields_->push_back(field); } @@ -181,10 +181,10 @@ string* UnknownFieldSet::AddLengthDelimited(int number) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_LENGTH_DELIMITED); - field.length_delimited_.string_value_ = new string; + field.data_.length_delimited_.string_value_ = new string; if (fields_ == NULL) fields_ = new std::vector(); fields_->push_back(field); - return field.length_delimited_.string_value_; + return field.data_.length_delimited_.string_value_; } @@ -192,10 +192,10 @@ UnknownFieldSet* UnknownFieldSet::AddGroup(int number) { UnknownField field; field.number_ = number; field.SetType(UnknownField::TYPE_GROUP); - field.group_ = new UnknownFieldSet; + field.data_.group_ = new UnknownFieldSet; if (fields_ == NULL) fields_ = new std::vector(); fields_->push_back(field); - return field.group_; + return field.data_.group_; } void UnknownFieldSet::AddField(const UnknownField& field) { @@ -276,10 +276,10 @@ bool UnknownFieldSet::ParseFromArray(const void* data, int size) { void UnknownField::Delete() { switch (type()) { case UnknownField::TYPE_LENGTH_DELIMITED: - delete length_delimited_.string_value_; + delete data_.length_delimited_.string_value_; break; case UnknownField::TYPE_GROUP: - delete group_; + delete data_.group_; break; default: break; @@ -291,10 +291,10 @@ void UnknownField::Delete() { void UnknownField::Reset() { switch (type()) { case UnknownField::TYPE_LENGTH_DELIMITED: - length_delimited_.string_value_ = NULL; + data_.length_delimited_.string_value_ = NULL; break; case UnknownField::TYPE_GROUP: { - group_ = NULL; + data_.group_ = NULL; break; } default: @@ -305,13 +305,13 @@ void UnknownField::Reset() { void UnknownField::DeepCopy(const UnknownField& other) { switch (type()) { case UnknownField::TYPE_LENGTH_DELIMITED: - length_delimited_.string_value_ = new string( - *length_delimited_.string_value_); + data_.length_delimited_.string_value_ = new string( + *data_.length_delimited_.string_value_); break; case UnknownField::TYPE_GROUP: { UnknownFieldSet* group = new UnknownFieldSet(); - group->InternalMergeFrom(*group_); - group_ = group; + group->InternalMergeFrom(*data_.group_); + data_.group_ = group; break; } default: @@ -323,14 +323,14 @@ void UnknownField::DeepCopy(const UnknownField& other) { void UnknownField::SerializeLengthDelimitedNoTag( io::CodedOutputStream* output) const { GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); - const string& data = *length_delimited_.string_value_; + const string& data = *data_.length_delimited_.string_value_; output->WriteVarint32(data.size()); output->WriteRawMaybeAliased(data.data(), data.size()); } uint8* UnknownField::SerializeLengthDelimitedNoTagToArray(uint8* target) const { GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); - const string& data = *length_delimited_.string_value_; + const string& data = *data_.length_delimited_.string_value_; target = io::CodedOutputStream::WriteVarint32ToArray(data.size(), target); target = io::CodedOutputStream::WriteStringToArray(data, target); return target; diff --git a/src/google/protobuf/unknown_field_set.h b/src/google/protobuf/unknown_field_set.h index c2ad8918..002ea8e8 100644 --- a/src/google/protobuf/unknown_field_set.h +++ b/src/google/protobuf/unknown_field_set.h @@ -43,6 +43,7 @@ #include #include #include +#include namespace google { namespace protobuf { @@ -106,10 +107,18 @@ class LIBPROTOBUF_EXPORT UnknownFieldSet { // Computes (an estimate of) the total number of bytes currently used for // storing the unknown fields in memory. Does NOT include // sizeof(*this) in the calculation. - int SpaceUsedExcludingSelf() const; + size_t SpaceUsedExcludingSelfLong() const; + + int SpaceUsedExcludingSelf() const { + return internal::ToIntSize(SpaceUsedExcludingSelfLong()); + } // Version of SpaceUsed() including sizeof(*this). - int SpaceUsed() const; + size_t SpaceUsedLong() const; + + int SpaceUsed() const { + return internal::ToIntSize(SpaceUsedLong()); + } // Returns the number of fields present in the UnknownFieldSet. inline int field_count() const; @@ -214,8 +223,6 @@ class LIBPROTOBUF_EXPORT UnknownField { inline size_t GetLengthDelimitedSize() const; - private: - friend class UnknownFieldSet; // If this UnknownField contains a pointer, delete it. void Delete(); @@ -243,7 +250,7 @@ class LIBPROTOBUF_EXPORT UnknownField { uint64 fixed64_; mutable union LengthDelimited length_delimited_; UnknownFieldSet* group_; - }; + } data_; }; // =================================================================== @@ -287,6 +294,8 @@ inline void UnknownFieldSet::AddLengthDelimited( } + + inline int UnknownField::number() const { return number_; } inline UnknownField::Type UnknownField::type() const { return static_cast(type_); @@ -294,53 +303,53 @@ inline UnknownField::Type UnknownField::type() const { inline uint64 UnknownField::varint() const { assert(type() == TYPE_VARINT); - return varint_; + return data_.varint_; } inline uint32 UnknownField::fixed32() const { assert(type() == TYPE_FIXED32); - return fixed32_; + return data_.fixed32_; } inline uint64 UnknownField::fixed64() const { assert(type() == TYPE_FIXED64); - return fixed64_; + return data_.fixed64_; } inline const string& UnknownField::length_delimited() const { assert(type() == TYPE_LENGTH_DELIMITED); - return *length_delimited_.string_value_; + return *data_.length_delimited_.string_value_; } inline const UnknownFieldSet& UnknownField::group() const { assert(type() == TYPE_GROUP); - return *group_; + return *data_.group_; } inline void UnknownField::set_varint(uint64 value) { assert(type() == TYPE_VARINT); - varint_ = value; + data_.varint_ = value; } inline void UnknownField::set_fixed32(uint32 value) { assert(type() == TYPE_FIXED32); - fixed32_ = value; + data_.fixed32_ = value; } inline void UnknownField::set_fixed64(uint64 value) { assert(type() == TYPE_FIXED64); - fixed64_ = value; + data_.fixed64_ = value; } inline void UnknownField::set_length_delimited(const string& value) { assert(type() == TYPE_LENGTH_DELIMITED); - length_delimited_.string_value_->assign(value); + data_.length_delimited_.string_value_->assign(value); } inline string* UnknownField::mutable_length_delimited() { assert(type() == TYPE_LENGTH_DELIMITED); - return length_delimited_.string_value_; + return data_.length_delimited_.string_value_; } inline UnknownFieldSet* UnknownField::mutable_group() { assert(type() == TYPE_GROUP); - return group_; + return data_.group_; } inline size_t UnknownField::GetLengthDelimitedSize() const { GOOGLE_DCHECK_EQ(TYPE_LENGTH_DELIMITED, type()); - return length_delimited_.string_value_->size(); + return data_.length_delimited_.string_value_->size(); } inline void UnknownField::SetType(Type type) { diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc index b33ad206..5763d0c6 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.cc +++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc @@ -189,6 +189,39 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack( field_scrub_callback_.reset(field_scrub_callback.release()); } +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector& path, + bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) { + return new Node(name, type, kind, data, is_placeholder, path, + suppress_empty_list, field_scrub_callback); +} + +DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector& path, + bool suppress_empty_list, bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback) { + return new Node(name, type, kind, data, is_placeholder, path, + suppress_empty_list, preserve_proto_field_names, + field_scrub_callback); +} + +DefaultValueObjectWriter::Node::Node( + const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, const std::vector& path, + bool suppress_empty_list, FieldScrubCallBack* field_scrub_callback) + : name_(name), + type_(type), + kind_(kind), + is_any_(false), + data_(data), + is_placeholder_(is_placeholder), + path_(path), + suppress_empty_list_(suppress_empty_list), + preserve_proto_field_names_(false), + field_scrub_callback_(field_scrub_callback) {} + DefaultValueObjectWriter::Node::Node( const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector& path, @@ -473,10 +506,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( StringPiece name) { if (current_ == NULL) { std::vector path; - root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(), - false, path, suppress_empty_list_, - preserve_proto_field_names_, - field_scrub_callback_.get())); + root_.reset(CreateNewNode(string(name), &type_, OBJECT, + DataPiece::NullData(), false, path, + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); root_->PopulateChildren(typeinfo_); current_ = root_.get(); return this; @@ -486,14 +519,15 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject( if (current_->kind() == LIST || current_->kind() == MAP || child == NULL) { // If current_ is a list or a map node, we should create a new child and use // the type of current_ as the type of the new child. - google::protobuf::scoped_ptr node(new Node( - name.ToString(), ((current_->kind() == LIST || current_->kind() == MAP) - ? current_->type() - : NULL), - OBJECT, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + google::protobuf::scoped_ptr node( + CreateNewNode(string(name), + ((current_->kind() == LIST || current_->kind() == MAP) + ? current_->type() + : NULL), + OBJECT, DataPiece::NullData(), false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -523,10 +557,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( StringPiece name) { if (current_ == NULL) { std::vector path; - root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(), - false, path, suppress_empty_list_, - preserve_proto_field_names_, - field_scrub_callback_.get())); + root_.reset(CreateNewNode(string(name), &type_, LIST, DataPiece::NullData(), + false, path, suppress_empty_list_, + preserve_proto_field_names_, + field_scrub_callback_.get())); current_ = root_.get(); return this; } @@ -534,10 +568,10 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList( Node* child = current_->FindChild(name); if (child == NULL || child->kind() != LIST) { google::protobuf::scoped_ptr node( - new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + CreateNewNode(string(name), NULL, LIST, DataPiece::NullData(), false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); child = node.get(); current_->AddChild(node.release()); } @@ -596,10 +630,10 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name, if (child == NULL || child->kind() != PRIMITIVE) { // No children are found, creates a new child. google::protobuf::scoped_ptr node( - new Node(name.ToString(), NULL, PRIMITIVE, data, false, - child == NULL ? current_->path() : child->path(), - suppress_empty_list_, preserve_proto_field_names_, - field_scrub_callback_.get())); + CreateNewNode(string(name), NULL, PRIMITIVE, data, false, + child == NULL ? current_->path() : child->path(), + suppress_empty_list_, preserve_proto_field_names_, + field_scrub_callback_.get())); current_->AddChild(node.release()); } else { child->set_data(data); diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h index ddf23594..ef2cc981 100644 --- a/src/google/protobuf/util/internal/default_value_objectwriter.h +++ b/src/google/protobuf/util/internal/default_value_objectwriter.h @@ -127,9 +127,11 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; } // If set to true, original proto field names are used - void set_preserve_proto_field_names(bool value) { preserve_proto_field_names_ = value; } + void set_preserve_proto_field_names(bool value) { + preserve_proto_field_names_ = value; + } - private: + protected: enum NodeKind { PRIMITIVE = 0, OBJECT = 1, @@ -144,7 +146,12 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { Node(const string& name, const google::protobuf::Type* type, NodeKind kind, const DataPiece& data, bool is_placeholder, const std::vector& path, bool suppress_empty_list, - bool preserve_proto_field_names, FieldScrubCallBack* field_scrub_callback); + FieldScrubCallBack* field_scrub_callback); + Node(const string& name, const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector& path, bool suppress_empty_list, + bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback); virtual ~Node() { for (int i = 0; i < children_.size(); ++i) { delete children_[i]; @@ -160,7 +167,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(const TypeInfo* typeinfo); + virtual 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 @@ -190,7 +197,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { is_placeholder_ = is_placeholder; } - private: + protected: // Returns the Value Type of a map given the Type of the map entry and a // TypeInfo instance. const google::protobuf::Type* GetMapValueType( @@ -230,9 +237,32 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // or not. This callback is owned by the creator of this node. FieldScrubCallBack* field_scrub_callback_; + private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Node); }; + // Creates a new Node and returns it. Caller owns memory of returned object. + virtual Node* CreateNewNode(const string& name, + const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector& path, + bool suppress_empty_list, + FieldScrubCallBack* field_scrub_callback); + + // Creates a new Node and returns it. Caller owns memory of returned object. + virtual Node* CreateNewNode(const string& name, + const google::protobuf::Type* type, NodeKind kind, + const DataPiece& data, bool is_placeholder, + const std::vector& path, + bool suppress_empty_list, + bool preserve_proto_field_names, + FieldScrubCallBack* field_scrub_callback); + + // Creates a DataPiece containing the default value of the type of the field. + static DataPiece CreateDefaultDataPieceForField( + const google::protobuf::Field& field, const TypeInfo* typeinfo); + + private: // Populates children of "node" if it is an "any" Node and its real type has // been given. void MaybePopulateChildrenOfAny(Node* node); @@ -241,10 +271,6 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter { // NULL. void WriteRoot(); - // Creates a DataPiece containing the default value of the type of the field. - static DataPiece CreateDefaultDataPieceForField( - const google::protobuf::Field& field, const TypeInfo* typeinfo); - // Adds or replaces the data_ of a primitive child node. void RenderDataPiece(StringPiece name, const DataPiece& data); diff --git a/src/google/protobuf/util/internal/field_mask_utility.cc b/src/google/protobuf/util/internal/field_mask_utility.cc index 53b90fb0..38835f67 100644 --- a/src/google/protobuf/util/internal/field_mask_utility.cc +++ b/src/google/protobuf/util/internal/field_mask_utility.cc @@ -44,11 +44,6 @@ inline util::Status CallPathSink(PathSinkCallback path_sink, return path_sink->Run(arg); } -util::Status CreatePublicError(util::error::Code code, - const string& message) { - return util::Status(code, message); -} - // Appends a FieldMask path segment to a prefix. string AppendPathSegmentToPrefix(StringPiece prefix, StringPiece segment) { if (prefix.empty()) { @@ -216,7 +211,7 @@ util::Status DecodeCompactFieldMaskPaths(StringPiece paths, StrCat("Invalid FieldMask '", paths, "'. Cannot find matching ')' for all '('.")); } - return util::Status::OK; + return util::Status(); } } // namespace converter diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc index 47e4dd6d..18b7f923 100644 --- a/src/google/protobuf/util/internal/json_escaping.cc +++ b/src/google/protobuf/util/internal/json_escaping.cc @@ -84,30 +84,6 @@ static const char kCommonEscapes[160][7] = { "\\u009c", "\\u009d", "\\u009e", "\\u009f" }; -// Determines if the given char value is a unicode high-surrogate code unit. -// Such values do not represent characters by themselves, but are used in the -// representation of supplementary characters in the utf-16 encoding. -inline bool IsHighSurrogate(uint16 c) { - // Optimized form of: - // return c >= kMinHighSurrogate && c <= kMaxHighSurrogate; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (c & ~(JsonEscaping::kMaxHighSurrogate - - JsonEscaping::kMinHighSurrogate)) - == JsonEscaping::kMinHighSurrogate; -} - -// Determines if the given char value is a unicode low-surrogate code unit. -// Such values do not represent characters by themselves, but are used in the -// representation of supplementary characters in the utf-16 encoding. -inline bool IsLowSurrogate(uint16 c) { - // Optimized form of: - // return c >= kMinLowSurrogate && c <= kMaxLowSurrogate; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (c & ~(JsonEscaping::kMaxLowSurrogate - - JsonEscaping::kMinLowSurrogate)) - == JsonEscaping::kMinLowSurrogate; -} - // Determines if the given char value is a unicode surrogate code unit (either // high-surrogate or low-surrogate). inline bool IsSurrogate(uint32 c) { @@ -117,36 +93,12 @@ inline bool IsSurrogate(uint32 c) { return (c & 0xfffff800) == JsonEscaping::kMinHighSurrogate; } -// Returns true if the given unicode code point cp is -// in the supplementary character range. -inline bool IsSupplementalCodePoint(uint32 cp) { - // Optimized form of: - // return kMinSupplementaryCodePoint <= cp && cp <= kMaxCodePoint; - // (Reduced from 3 ALU instructions to 2 ALU instructions) - return (cp & ~(JsonEscaping::kMinSupplementaryCodePoint - 1)) - < JsonEscaping::kMaxCodePoint; -} - // Returns true if the given unicode code point cp is a valid // unicode code point (i.e. in the range 0 <= cp <= kMaxCodePoint). inline bool IsValidCodePoint(uint32 cp) { return cp <= JsonEscaping::kMaxCodePoint; } -// Converts the specified surrogate pair to its supplementary code point value. -// It is the callers' responsibility to validate the specified surrogate pair. -inline uint32 ToCodePoint(uint16 high, uint16 low) { - // Optimized form of: - // return ((high - kMinHighSurrogate) << 10) - // + (low - kMinLowSurrogate) - // + kMinSupplementaryCodePoint; - // (Reduced from 5 ALU instructions to 3 ALU instructions) - return (high << 10) + low + - (JsonEscaping::kMinSupplementaryCodePoint - - (static_cast(JsonEscaping::kMinHighSurrogate) << 10) - - JsonEscaping::kMinLowSurrogate); -} - // Returns the low surrogate for the given unicode code point. The result is // meaningless if the given code point is not a supplementary character. inline uint16 ToLowSurrogate(uint32 cp) { diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc index b38030c3..047c14e1 100644 --- a/src/google/protobuf/util/internal/json_stream_parser.cc +++ b/src/google/protobuf/util/internal/json_stream_parser.cc @@ -130,7 +130,7 @@ util::Status JsonStreamParser::Parse(StringPiece json) { // Don't point chunk to leftover_ because leftover_ will be updated in // ParseChunk(chunk). chunk_storage_.swap(leftover_); - json.AppendToString(&chunk_storage_); + StrAppend(&chunk_storage_, json); chunk = StringPiece(chunk_storage_); } @@ -141,11 +141,11 @@ util::Status JsonStreamParser::Parse(StringPiece json) { // Any leftover characters are stashed in leftover_ for later parsing when // there is more data available. - chunk.substr(n).AppendToString(&leftover_); + StrAppend(&leftover_, chunk.substr(n)); return status; } else { - chunk.CopyToString(&leftover_); - return util::Status::OK; + leftover_.assign(chunk.data(), chunk.size()); + return util::Status(); } } @@ -153,7 +153,7 @@ util::Status JsonStreamParser::FinishParse() { // If we do not expect anything and there is nothing left to parse we're all // done. if (stack_.empty() && leftover_.empty()) { - return util::Status::OK; + return util::Status(); } // Storage for UTF8-coerced string. @@ -184,7 +184,7 @@ util::Status JsonStreamParser::FinishParse() { util::Status JsonStreamParser::ParseChunk(StringPiece chunk) { // Do not do any work if the chunk is empty. - if (chunk.empty()) return util::Status::OK; + if (chunk.empty()) return util::Status(); p_ = json_ = chunk; @@ -206,7 +206,7 @@ util::Status JsonStreamParser::ParseChunk(StringPiece chunk) { // unparsed data left, we save it for later parse. leftover_ = p_.ToString(); } - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::RunParser() { @@ -252,15 +252,15 @@ util::Status JsonStreamParser::RunParser() { // If we have a key we still need to render, make sure to save off the // contents in our own storage. if (!key_.empty() && key_storage_.empty()) { - key_.AppendToString(&key_storage_); + StrAppend(&key_storage_, key_); key_ = StringPiece(key_storage_); } - result = util::Status::OK; + result = util::Status(); } return result; } } - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseValue(TokenType type) { @@ -386,7 +386,7 @@ util::Status JsonStreamParser::ParseStringHelper() { // start fresh. string_open_ = 0; Advance(); - return util::Status::OK; + return util::Status(); } // Normal character, just advance past it. Advance(); @@ -468,7 +468,7 @@ util::Status JsonStreamParser::ParseUnicodeEscape() { // Advance past the [final] code unit escape. p_.remove_prefix(kUnicodeEscapedLength); parsed_storage_.append(buf, len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseNumber() { @@ -542,7 +542,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::DOUBLE; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } // Positive non-floating point number, parse as a uint64. @@ -556,7 +556,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::UINT; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } // Octal/Hex numbers are not valid JSON values. @@ -569,7 +569,7 @@ util::Status JsonStreamParser::ParseNumberHelper(NumberResult* result) { } result->type = NumberResult::INT; p_.remove_prefix(index); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::HandleBeginObject() { @@ -578,7 +578,7 @@ util::Status JsonStreamParser::HandleBeginObject() { ow_->StartObject(key_); key_ = StringPiece(); stack_.push(ENTRY); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseObjectMid(TokenType type) { @@ -590,13 +590,13 @@ util::Status JsonStreamParser::ParseObjectMid(TokenType type) { if (type == END_OBJECT) { Advance(); ow_->EndObject(); - return util::Status::OK; + return util::Status(); } // Found a comma, advance past it and get ready for an entry. if (type == VALUE_SEPARATOR) { Advance(); stack_.push(ENTRY); - return util::Status::OK; + return util::Status(); } // Illegal token after key:value pair. return ReportFailure("Expected , or } after key:value pair."); @@ -611,7 +611,7 @@ util::Status JsonStreamParser::ParseEntry(TokenType type) { if (type == END_OBJECT) { ow_->EndObject(); Advance(); - return util::Status::OK; + return util::Status(); } util::Status result; @@ -650,7 +650,7 @@ util::Status JsonStreamParser::ParseEntryMid(TokenType type) { if (type == ENTRY_SEPARATOR) { Advance(); stack_.push(VALUE); - return util::Status::OK; + return util::Status(); } return ReportFailure("Expected : between key:value pair."); } @@ -661,7 +661,7 @@ util::Status JsonStreamParser::HandleBeginArray() { ow_->StartList(key_); key_ = StringPiece(); stack_.push(ARRAY_VALUE); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseArrayValue(TokenType type) { @@ -672,7 +672,7 @@ util::Status JsonStreamParser::ParseArrayValue(TokenType type) { if (type == END_ARRAY) { ow_->EndList(); Advance(); - return util::Status::OK; + return util::Status(); } // The ParseValue call may push something onto the stack so we need to make @@ -696,14 +696,14 @@ util::Status JsonStreamParser::ParseArrayMid(TokenType type) { if (type == END_ARRAY) { ow_->EndList(); Advance(); - return util::Status::OK; + return util::Status(); } // Found a comma, advance past it and expect an array value next. if (type == VALUE_SEPARATOR) { Advance(); stack_.push(ARRAY_VALUE); - return util::Status::OK; + return util::Status(); } // Illegal token after array value. return ReportFailure("Expected , or ] after array value."); @@ -713,27 +713,27 @@ util::Status JsonStreamParser::ParseTrue() { ow_->RenderBool(key_, true); key_ = StringPiece(); p_.remove_prefix(true_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseFalse() { ow_->RenderBool(key_, false); key_ = StringPiece(); p_.remove_prefix(false_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseNull() { ow_->RenderNull(key_); key_ = StringPiece(); p_.remove_prefix(null_len); - return util::Status::OK; + return util::Status(); } util::Status JsonStreamParser::ParseEmptyNull() { ow_->RenderNull(key_); key_ = StringPiece(); - return util::Status::OK; + return util::Status(); } bool JsonStreamParser::IsEmptyNullAllowed(TokenType type) { @@ -793,7 +793,7 @@ util::Status JsonStreamParser::ParseKey() { } // Since we aren't using the key storage, clear it out. key_storage_.clear(); - return util::Status::OK; + return util::Status(); } JsonStreamParser::TokenType JsonStreamParser::GetNextTokenType() { diff --git a/src/google/protobuf/util/internal/proto_writer.h b/src/google/protobuf/util/internal/proto_writer.h index 21dff88d..0db8485c 100644 --- a/src/google/protobuf/util/internal/proto_writer.h +++ b/src/google/protobuf/util/internal/proto_writer.h @@ -81,32 +81,32 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { virtual ~ProtoWriter(); // ObjectWriter methods. - virtual ProtoWriter* StartObject(StringPiece name); - virtual ProtoWriter* EndObject(); - virtual ProtoWriter* StartList(StringPiece name); - virtual ProtoWriter* EndList(); - virtual ProtoWriter* RenderBool(StringPiece name, bool value) { + ProtoWriter* StartObject(StringPiece name); + ProtoWriter* EndObject(); + ProtoWriter* StartList(StringPiece name); + ProtoWriter* EndList(); + ProtoWriter* RenderBool(StringPiece name, bool value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderInt32(StringPiece name, int32 value) { + ProtoWriter* RenderInt32(StringPiece name, int32 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderUint32(StringPiece name, uint32 value) { + ProtoWriter* RenderUint32(StringPiece name, uint32 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderInt64(StringPiece name, int64 value) { + ProtoWriter* RenderInt64(StringPiece name, int64 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderUint64(StringPiece name, uint64 value) { + ProtoWriter* RenderUint64(StringPiece name, uint64 value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderDouble(StringPiece name, double value) { + ProtoWriter* RenderDouble(StringPiece name, double value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderFloat(StringPiece name, float value) { + ProtoWriter* RenderFloat(StringPiece name, float value) { return RenderDataPiece(name, DataPiece(value)); } - virtual ProtoWriter* RenderString(StringPiece name, StringPiece value) { + ProtoWriter* RenderString(StringPiece name, StringPiece value) { return RenderDataPiece(name, DataPiece(value, use_strict_base64_decoding())); } @@ -114,7 +114,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { return RenderDataPiece( name, DataPiece(value, false, use_strict_base64_decoding())); } - virtual ProtoWriter* RenderNull(StringPiece name) { + ProtoWriter* RenderNull(StringPiece name) { return RenderDataPiece(name, DataPiece::NullData()); } @@ -242,7 +242,7 @@ class LIBPROTOBUF_EXPORT ProtoWriter : public StructuredObjectWriter { ProtoWriter(const TypeInfo* typeinfo, const google::protobuf::Type& type, strings::ByteSink* output, ErrorListener* listener); - virtual ProtoElement* element() { return element_.get(); } + ProtoElement* element() { return element_.get(); } // Helper methods for calling ErrorListener. See error_listener.h. void InvalidName(StringPiece unknown_name, StringPiece message); diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc index 61491af0..025fbd40 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource.cc @@ -240,7 +240,7 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type, if (include_start_and_end) { ow->EndObject(); } - return Status::OK; + return util::Status(); } StatusOr ProtoStreamObjectSource::RenderList( @@ -322,7 +322,7 @@ Status ProtoStreamObjectSource::RenderPacked( RETURN_IF_ERROR(RenderField(field, StringPiece(), ow)); } stream_->PopLimit(old_limit); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderTimestamp( @@ -346,7 +346,7 @@ Status ProtoStreamObjectSource::RenderTimestamp( ow->RenderString(field_name, ::google::protobuf::internal::FormatTime(seconds, nanos)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderDuration( @@ -387,7 +387,7 @@ Status ProtoStreamObjectSource::RenderDuration( FormatNanos(nanos, os->add_trailing_zeros_for_timestamp_and_duration_) .c_str()); ow->RenderString(field_name, formatted_duration); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, @@ -401,7 +401,7 @@ Status ProtoStreamObjectSource::RenderDouble(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderDouble(field_name, bit_cast(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, @@ -415,7 +415,7 @@ Status ProtoStreamObjectSource::RenderFloat(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderFloat(field_name, bit_cast(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, @@ -429,7 +429,7 @@ Status ProtoStreamObjectSource::RenderInt64(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderInt64(field_name, bit_cast(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, @@ -443,7 +443,7 @@ Status ProtoStreamObjectSource::RenderUInt64(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderUint64(field_name, bit_cast(buffer64)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, @@ -457,7 +457,7 @@ Status ProtoStreamObjectSource::RenderInt32(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderInt32(field_name, bit_cast(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, @@ -471,7 +471,7 @@ Status ProtoStreamObjectSource::RenderUInt32(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderUint32(field_name, bit_cast(buffer32)); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, @@ -486,7 +486,7 @@ Status ProtoStreamObjectSource::RenderBool(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderBool(field_name, buffer64 != 0); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, @@ -502,7 +502,7 @@ Status ProtoStreamObjectSource::RenderString(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderString(field_name, str); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, @@ -518,7 +518,7 @@ Status ProtoStreamObjectSource::RenderBytes(const ProtoStreamObjectSource* os, os->stream_->ReadTag(); } ow->RenderBytes(field_name, str); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, @@ -537,7 +537,7 @@ Status ProtoStreamObjectSource::RenderStruct(const ProtoStreamObjectSource* os, } } ow->EndObject(); - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderStructValue( @@ -553,7 +553,7 @@ Status ProtoStreamObjectSource::RenderStructValue( } RETURN_IF_ERROR(os->RenderField(field, field_name, ow)); } - return Status::OK; + return util::Status(); } // TODO(skarvaje): Avoid code duplication of for loops and SkipField logic. @@ -566,7 +566,7 @@ Status ProtoStreamObjectSource::RenderStructListValue( if (tag == 0) { ow->StartList(field_name); ow->EndList(); - return Status::OK; + return util::Status(); } while (tag != 0) { @@ -578,7 +578,7 @@ Status ProtoStreamObjectSource::RenderStructListValue( } ASSIGN_OR_RETURN(tag, os->RenderList(field, field_name, tag, ow)); } - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, @@ -620,7 +620,7 @@ Status ProtoStreamObjectSource::RenderAny(const ProtoStreamObjectSource* os, ow->RenderString("@type", type_url); } ow->EndObject(); - return util::Status::OK; + return util::Status(); } // If there is a value but no type, we cannot render it, so report an error. @@ -685,7 +685,7 @@ Status ProtoStreamObjectSource::RenderFieldMask( combined.append(ConvertFieldMaskPath(str, &ToCamelCase)); } ow->RenderString(field_name, combined); - return Status::OK; + return util::Status(); } @@ -781,7 +781,7 @@ Status ProtoStreamObjectSource::RenderField( // Render all other non-message types. return RenderNonMessageField(field, field_name, ow); } - return Status::OK; + return util::Status(); } Status ProtoStreamObjectSource::RenderNonMessageField( @@ -910,7 +910,7 @@ Status ProtoStreamObjectSource::RenderNonMessageField( default: break; } - return Status::OK; + return util::Status(); } // TODO(skarvaje): Fix this to avoid code duplication. @@ -1079,7 +1079,7 @@ Status ProtoStreamObjectSource::IncrementRecursionDepth( StrCat("Message too deep. Max recursion depth reached for type '", type_name, "', field '", field_name, "'")); } - return Status::OK; + return util::Status(); } namespace { diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h index 5f443d9d..58d77c2c 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource.h +++ b/src/google/protobuf/util/internal/protostream_objectsource.h @@ -112,9 +112,7 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource { // Sets whether to always output enums as ints, by default this is off, and // enums are rendered as strings. - void set_use_ints_for_enums(bool value) { - use_ints_for_enums_ = value; - } + void set_use_ints_for_enums(bool value) { use_ints_for_enums_ = value; } // Sets whether to use original proto field names void set_preserve_proto_field_names(bool value) { diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc index e215c4ab..06c9bb6d 100644 --- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc @@ -111,7 +111,7 @@ class ProtostreamObjectSourceTest void DoTest(const Message& msg, const Descriptor* descriptor) { Status status = ExecuteTest(msg, descriptor); - EXPECT_EQ(Status::OK, status); + EXPECT_EQ(util::Status(), status); } Status ExecuteTest(const Message& msg, const Descriptor* descriptor) { @@ -509,9 +509,7 @@ TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) { UseIntsForEnums(); - ow_.StartObject("") - ->RenderInt32("type", 3) - ->EndObject(); + ow_.StartObject("")->RenderInt32("type", 3)->EndObject(); DoTest(book, Book::descriptor()); } diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc index 6c9bc30e..d4e15bca 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc @@ -173,7 +173,7 @@ Status GetNanosFromStringPiece(StringPiece s_nanos, *nanos = i_nanos * conversion; } - return Status::OK; + return Status(); } } // namespace @@ -409,7 +409,7 @@ void ProtoStreamObjectWriter::AnyWriter::Event::DeepCopy() { // string value stays valid, we make a copy of the string value and update // DataPiece to reference our own copy. if (value_.type() == DataPiece::TYPE_STRING) { - value_.str().AppendToString(&value_storage_); + StrAppend(&value_storage_, value_.str()); value_ = DataPiece(value_storage_, value_.use_strict_base64_decoding()); } else if (value_.type() == DataPiece::TYPE_BYTES) { value_storage_ = value_.ToBytes().ValueOrDie(); @@ -862,7 +862,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); - return Status::OK; + return Status(); } } struct_field_name = "number_value"; @@ -877,13 +877,22 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece( "string_value", DataPiece(SimpleItoa(int_value.ValueOrDie()), true)); - return Status::OK; + return Status(); } } struct_field_name = "number_value"; break; } case DataPiece::TYPE_DOUBLE: { + if (ow->options_.struct_integers_as_strings) { + StatusOr double_value = data.ToDouble(); + if (double_value.ok()) { + ow->ProtoWriter::RenderDataPiece( + "string_value", + DataPiece(SimpleDtoa(double_value.ValueOrDie()), true)); + return Status(); + } + } struct_field_name = "number_value"; break; } @@ -906,12 +915,12 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow, } } ow->ProtoWriter::RenderDataPiece(struct_field_name, data); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for timestamp, value is ", @@ -930,19 +939,19 @@ Status ProtoStreamObjectWriter::RenderTimestamp(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); - return Status::OK; + return Status(); } static inline util::Status RenderOneFieldPath(ProtoStreamObjectWriter* ow, StringPiece path) { ow->ProtoWriter::RenderDataPiece( "paths", DataPiece(ConvertFieldMaskPath(path, &ToSnakeCase), true)); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for field mask, value is ", @@ -959,7 +968,7 @@ Status ProtoStreamObjectWriter::RenderFieldMask(ProtoStreamObjectWriter* ow, Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); if (data.type() != DataPiece::TYPE_STRING) { return Status(INVALID_ARGUMENT, StrCat("Invalid data type for duration, value is ", @@ -1004,14 +1013,14 @@ Status ProtoStreamObjectWriter::RenderDuration(ProtoStreamObjectWriter* ow, ow->ProtoWriter::RenderDataPiece("seconds", DataPiece(seconds)); ow->ProtoWriter::RenderDataPiece("nanos", DataPiece(nanos)); - return Status::OK; + return Status(); } Status ProtoStreamObjectWriter::RenderWrapperType(ProtoStreamObjectWriter* ow, const DataPiece& data) { - if (data.type() == DataPiece::TYPE_NULL) return Status::OK; + if (data.type() == DataPiece::TYPE_NULL) return Status(); ow->ProtoWriter::RenderDataPiece("value", data); - return Status::OK; + return Status(); } ProtoStreamObjectWriter* ProtoStreamObjectWriter::RenderDataPiece( diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.h b/src/google/protobuf/util/internal/protostream_objectwriter.h index 732971e1..ab534912 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter.h +++ b/src/google/protobuf/util/internal/protostream_objectwriter.h @@ -76,11 +76,14 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter { public: // Options that control ProtoStreamObjectWriter class's behavior. struct Options { - // Treats integer inputs in google.protobuf.Struct as strings. Normally, - // integer values are returned in double field "number_value" of + // Treats numeric inputs in google.protobuf.Struct as strings. Normally, + // numeric values are returned in double field "number_value" of // google.protobuf.Struct. However, this can cause precision loss for - // int64/uint64 inputs. This option is provided for cases that want to - // preserve integer precision. + // int64/uint64/double inputs. This option is provided for cases that want + // to preserve number precision. + // + // TODO(skarvaje): Rename to struct_numbers_as_strings as it covers double + // as well. bool struct_integers_as_strings; // Not treat unknown fields as an error. If there is an unknown fields, diff --git a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc index 97ef8fff..87d35b08 100644 --- a/src/google/protobuf/util/internal/protostream_objectwriter_test.cc +++ b/src/google/protobuf/util/internal/protostream_objectwriter_test.cc @@ -279,17 +279,13 @@ TEST_P(ProtoStreamObjectWriterTest, ConflictingJsonName) { ResetTypeInfo(TestJsonName1::descriptor()); TestJsonName1 message1; message1.set_one_value(12345); - ow_->StartObject("") - ->RenderInt32("value", 12345) - ->EndObject(); + ow_->StartObject("")->RenderInt32("value", 12345)->EndObject(); CheckOutput(message1); ResetTypeInfo(TestJsonName2::descriptor()); TestJsonName2 message2; message2.set_another_value(12345); - ow_->StartObject("") - ->RenderInt32("value", 12345) - ->EndObject(); + ow_->StartObject("")->RenderInt32("value", 12345)->EndObject(); CheckOutput(message2); } @@ -1615,7 +1611,7 @@ TEST_P(ProtoStreamObjectWriterStructTest, RepeatedStructMapObjectKeyTest) { TEST_P(ProtoStreamObjectWriterStructTest, OptionStructIntAsStringsTest) { StructType struct_type; google::protobuf::Struct* s = struct_type.mutable_object(); - s->mutable_fields()->operator[]("k1").set_number_value(123); + s->mutable_fields()->operator[]("k1").set_string_value("123"); s->mutable_fields()->operator[]("k2").set_bool_value(true); s->mutable_fields()->operator[]("k3").set_string_value("-222222222"); s->mutable_fields()->operator[]("k4").set_string_value("33333333"); diff --git a/src/google/protobuf/util/internal/type_info.cc b/src/google/protobuf/util/internal/type_info.cc index a5d903f1..85d0d5c9 100644 --- a/src/google/protobuf/util/internal/type_info.cc +++ b/src/google/protobuf/util/internal/type_info.cc @@ -107,10 +107,12 @@ class TypeInfoForTypeResolver : public TypeInfo { virtual const google::protobuf::Field* FindField( const google::protobuf::Type* type, StringPiece camel_case_name) const { - std::map::const_iterator it = indexed_types_.find(type); - const CamelCaseNameTable& camel_case_name_table = (it == indexed_types_.end()) - ? PopulateNameLookupTable(type, &indexed_types_[type]) : it->second; + std::map::const_iterator + it = indexed_types_.find(type); + const CamelCaseNameTable& camel_case_name_table = + (it == indexed_types_.end()) + ? PopulateNameLookupTable(type, &indexed_types_[type]) + : it->second; StringPiece name = FindWithDefault(camel_case_name_table, camel_case_name, StringPiece()); if (name.empty()) { @@ -142,8 +144,8 @@ class TypeInfoForTypeResolver : public TypeInfo { const google::protobuf::Field& field = type->fields(i); StringPiece name = field.name(); StringPiece camel_case_name = field.json_name(); - const StringPiece* existing = InsertOrReturnExisting( - camel_case_name_table, camel_case_name, name); + const StringPiece* existing = + InsertOrReturnExisting(camel_case_name_table, camel_case_name, name); if (existing && *existing != name) { GOOGLE_LOG(WARNING) << "Field '" << name << "' and '" << *existing << "' map to the same camel case name '" << camel_case_name @@ -162,8 +164,8 @@ class TypeInfoForTypeResolver : public TypeInfo { mutable std::map cached_types_; mutable std::map cached_enums_; - mutable std::map indexed_types_; + mutable std::map + indexed_types_; }; } // namespace diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc index 6daf24eb..8cf42e49 100644 --- a/src/google/protobuf/util/internal/utility.cc +++ b/src/google/protobuf/util/internal/utility.cc @@ -48,16 +48,6 @@ namespace protobuf { namespace util { namespace converter { -namespace { -const StringPiece SkipWhiteSpace(StringPiece str) { - StringPiece::size_type i; - for (i = 0; i < str.size() && isspace(str[i]); ++i) { - } - GOOGLE_DCHECK(i == str.size() || !isspace(str[i])); - return str.substr(i); -} -} // namespace - bool GetBoolOptionOrDefault( const google::protobuf::RepeatedPtrField& options, const string& option_name, bool default_value) { diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc index 8595a881..c85f1899 100644 --- a/src/google/protobuf/util/json_util.cc +++ b/src/google/protobuf/util/json_util.cc @@ -84,7 +84,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver, converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type); proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints); proto_source.set_preserve_proto_field_names( - options.preserve_proto_field_names); + options.preserve_proto_field_names); io::CodedOutputStream out_stream(json_output); converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "", &out_stream); @@ -92,7 +92,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver, converter::DefaultValueObjectWriter default_value_writer( resolver, type, &json_writer); default_value_writer.set_preserve_proto_field_names( - options.preserve_proto_field_names); + options.preserve_proto_field_names); return proto_source.WriteTo(&default_value_writer); } else { return proto_source.WriteTo(&json_writer); @@ -113,7 +113,7 @@ util::Status BinaryToJsonString(TypeResolver* resolver, namespace { class StatusErrorListener : public converter::ErrorListener { public: - StatusErrorListener() : status_(util::Status::OK) {} + StatusErrorListener() {} virtual ~StatusErrorListener() {} util::Status GetStatus() { return status_; } diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h index dd9a736f..f4f4380a 100644 --- a/src/google/protobuf/util/json_util.h +++ b/src/google/protobuf/util/json_util.h @@ -67,11 +67,11 @@ struct JsonPrintOptions { // Whether to preserve proto field names bool preserve_proto_field_names; - JsonPrintOptions() : add_whitespace(false), - always_print_primitive_fields(false), - always_print_enums_as_ints(false), - preserve_proto_field_names(false) { - } + JsonPrintOptions() + : add_whitespace(false), + always_print_primitive_fields(false), + always_print_enums_as_ints(false), + preserve_proto_field_names(false) {} }; // DEPRECATED. Use JsonPrintOptions instead. diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc index 7c03d674..25c7e96c 100644 --- a/src/google/protobuf/util/json_util_test.cc +++ b/src/google/protobuf/util/json_util_test.cc @@ -52,14 +52,10 @@ using proto3::BAR; using proto3::TestMessage; using proto3::TestMap; using proto3::TestOneof; -using testing::MapIn; +using google::protobuf::testing::MapIn; static const char kTypeUrlPrefix[] = "type.googleapis.com"; -static string GetTypeUrl(const Descriptor* message) { - return string(kTypeUrlPrefix) + "/" + message->full_name(); -} - // As functions defined in json_util.h are just thin wrappers around the // JSON conversion code in //net/proto2/util/converter, in this test we // only cover some very basic cases to make sure the wrappers have forwarded @@ -207,8 +203,7 @@ TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) { JsonPrintOptions print_options; print_options.always_print_enums_as_ints = true; - string expected_json = - "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}"; + string expected_json = "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}"; EXPECT_EQ(expected_json, ToJson(orig, print_options)); TestMessage parsed; @@ -264,7 +259,8 @@ TEST_F(JsonUtilTest, ParsePrimitiveMapIn) { JsonPrintOptions print_options; print_options.always_print_primitive_fields = true; JsonParseOptions parse_options; - EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", ToJson(message, print_options)); + EXPECT_EQ("{\"other\":\"\",\"things\":[],\"mapInput\":{}}", + ToJson(message, print_options)); MapIn other; ASSERT_TRUE(FromJson(ToJson(message, print_options), &other, parse_options)); EXPECT_EQ(message.DebugString(), other.DebugString()); @@ -275,14 +271,10 @@ TEST_F(JsonUtilTest, PrintPrimitiveOneof) { JsonPrintOptions options; options.always_print_primitive_fields = true; message.mutable_oneof_message_value(); - EXPECT_EQ( - "{\"oneofMessageValue\":{\"value\":0}}", - ToJson(message, options)); + EXPECT_EQ("{\"oneofMessageValue\":{\"value\":0}}", ToJson(message, options)); message.set_oneof_int32_value(1); - EXPECT_EQ( - "{\"oneofInt32Value\":1}", - ToJson(message, options)); + EXPECT_EQ("{\"oneofInt32Value\":1}", ToJson(message, options)); } TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) { diff --git a/src/google/protobuf/util/message_differencer.cc b/src/google/protobuf/util/message_differencer.cc index 203d8388..830850be 100644 --- a/src/google/protobuf/util/message_differencer.cc +++ b/src/google/protobuf/util/message_differencer.cc @@ -467,6 +467,10 @@ bool MessageDifferencer::Compare( google::protobuf::scoped_ptr data1; google::protobuf::scoped_ptr data2; if (UnpackAny(message1, &data1) && UnpackAny(message2, &data2)) { + // Avoid DFATAL for different descriptors in google.protobuf.Any payloads. + if (data1->GetDescriptor() != data2->GetDescriptor()) { + return false; + } return Compare(*data1, *data2, parent_fields); } } @@ -849,7 +853,8 @@ bool MessageDifferencer::CompareRepeatedField( parent_fields->pop_back(); fieldDifferent = true; } else if (reporter_ != NULL && - specific_field.index != specific_field.new_index) { + specific_field.index != specific_field.new_index && + !specific_field.field->is_map()) { parent_fields->push_back(specific_field); reporter_->ReportMoved(message1, message2, *parent_fields); parent_fields->pop_back(); @@ -1503,6 +1508,10 @@ void MessageDifferencer::StreamReporter::PrintPath( } else { printer_->PrintRaw(specific_field.field->name()); } + if (specific_field.field->is_map()) { + // Don't print index in a map field; they are semantically unordered. + continue; + } } else { printer_->PrintRaw(SimpleItoa(specific_field.unknown_field_number)); } diff --git a/src/google/protobuf/util/message_differencer_unittest.cc b/src/google/protobuf/util/message_differencer_unittest.cc index 30b27dba..850b3977 100755 --- a/src/google/protobuf/util/message_differencer_unittest.cc +++ b/src/google/protobuf/util/message_differencer_unittest.cc @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -54,7 +55,6 @@ #include #include -#include #include #include @@ -2042,6 +2042,9 @@ class ComparisonTest : public testing::Test { unittest::TestEmptyMessage empty1_; unittest::TestEmptyMessage empty2_; + unittest::TestMap map_proto1_; + unittest::TestMap map_proto2_; + UnknownFieldSet* unknown1_; UnknownFieldSet* unknown2_; @@ -2802,6 +2805,24 @@ TEST_F(ComparisonTest, EquivalentIgnoresUnknown) { EXPECT_TRUE(util::MessageDifferencer::Equivalent(message1, message2)); } +TEST_F(ComparisonTest, MapTest) { + repeated_field_as_set(); + + Map& map1 = *map_proto1_.mutable_map_string_string(); + map1["1"] = "1"; + map1["2"] = "2"; + map1["3"] = "3"; + Map& map2 = *map_proto2_.mutable_map_string_string(); + map2["3"] = "0"; + map2["2"] = "2"; + map2["1"] = "1"; + + EXPECT_EQ( + "added: map_string_string: { key: \"3\" value: \"0\" }\n" + "deleted: map_string_string: { key: \"3\" value: \"3\" }\n", + Run(map_proto1_, map_proto2_)); +} + class MatchingTest : public testing::Test { public: typedef util::MessageDifferencer MessageDifferencer; @@ -3146,6 +3167,24 @@ TEST(Anytest, TreatAsSet) { EXPECT_TRUE(message_differencer.Compare(m1, m2)); } +TEST(Anytest, TreatAsSet_DifferentType) { + protobuf_unittest::TestField value1; + value1.set_a(20); + value1.set_b(30); + protobuf_unittest::TestDiffMessage value2; + value2.add_rv(40); + + protobuf_unittest::TestAny m1, m2; + m1.add_repeated_any_value()->PackFrom(value1); + m1.add_repeated_any_value()->PackFrom(value2); + m2.add_repeated_any_value()->PackFrom(value2); + m2.add_repeated_any_value()->PackFrom(value1); + + util::MessageDifferencer message_differencer; + message_differencer.TreatAsSet(GetFieldDescriptor(m1, "repeated_any_value")); + EXPECT_TRUE(message_differencer.Compare(m1, m2)); +} + } // namespace } // namespace protobuf diff --git a/src/google/protobuf/util/time_util.cc b/src/google/protobuf/util/time_util.cc index b11f822a..46a6f5a8 100644 --- a/src/google/protobuf/util/time_util.cc +++ b/src/google/protobuf/util/time_util.cc @@ -49,11 +49,9 @@ 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 T CreateNormalized(int64 seconds, int64 nanos); @@ -376,19 +374,6 @@ 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(-value.seconds()); - *result = *result * kNanosPerSecond - static_cast(value.nanos()); - } else { - *negative = false; - *result = static_cast(value.seconds()); - *result = *result * kNanosPerSecond + static_cast(value.nanos()); - } -} - // Convert a Duration to uint128. void ToUint128(const Duration& value, uint128* result, bool* negative) { if (value.seconds() < 0 || value.nanos() < 0) { @@ -402,21 +387,6 @@ void ToUint128(const Duration& value, uint128* result, bool* negative) { } } -void ToTimestamp(const uint128& value, bool negative, Timestamp* timestamp) { - int64 seconds = static_cast(Uint128Low64(value / kNanosPerSecond)); - int32 nanos = static_cast(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(Uint128Low64(value / kNanosPerSecond)); int32 nanos = static_cast(Uint128Low64(value % kNanosPerSecond)); diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index bd5b2489..d3d21c09 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -76,6 +76,8 @@ void UnknownFieldSetFieldSkipper::SkipUnknownEnum( bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag, UnknownFieldSet* unknown_fields) { int number = WireFormatLite::GetTagFieldNumber(tag); + // Field number 0 is illegal. + if (number == 0) return false; switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { diff --git a/src/google/protobuf/wire_format_lite.cc b/src/google/protobuf/wire_format_lite.cc index e46ac400..3b139e37 100644 --- a/src/google/protobuf/wire_format_lite.cc +++ b/src/google/protobuf/wire_format_lite.cc @@ -47,8 +47,8 @@ #include #include - namespace google { + namespace protobuf { namespace internal { @@ -123,6 +123,8 @@ WireFormatLite::kWireTypeForFieldType[MAX_FIELD_TYPE + 1] = { bool WireFormatLite::SkipField( io::CodedInputStream* input, uint32 tag) { + // Field number 0 is illegal. + if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { uint64 value; @@ -168,6 +170,8 @@ bool WireFormatLite::SkipField( bool WireFormatLite::SkipField( io::CodedInputStream* input, uint32 tag, io::CodedOutputStream* output) { + // Field number 0 is illegal. + if (WireFormatLite::GetTagFieldNumber(tag) == 0) return false; switch (WireFormatLite::GetTagWireType(tag)) { case WireFormatLite::WIRETYPE_VARINT: { uint64 value; @@ -340,6 +344,8 @@ bool WireFormatLite::ReadPackedEnumPreserveUnknowns( return true; } +#if !defined(PROTOBUF_LITTLE_ENDIAN) + namespace { void EncodeFixedSizeValue(float v, uint8* dest) { WireFormatLite::WriteFloatNoTagToArray(v, dest); @@ -370,6 +376,8 @@ void EncodeFixedSizeValue(bool v, uint8* dest) { } } // anonymous namespace +#endif // !defined(PROTOBUF_LITTLE_ENDIAN) + template static void WriteArray(const CType* a, int n, io::CodedOutputStream* output) { #if defined(PROTOBUF_LITTLE_ENDIAN) diff --git a/src/google/protobuf/wire_format_lite.h b/src/google/protobuf/wire_format_lite.h index 60355144..18b38eae 100644 --- a/src/google/protobuf/wire_format_lite.h +++ b/src/google/protobuf/wire_format_lite.h @@ -250,10 +250,6 @@ class LIBPROTOBUF_EXPORT WireFormatLite { // of these methods are defined in wire_format_lite_inl.h; you must #include // that file to use these. -// Avoid ugly line wrapping -#define input io::CodedInputStream* input_arg -#define output io::CodedOutputStream* output_arg -#define field_number int field_number_arg #ifdef NDEBUG #define INL GOOGLE_ATTRIBUTE_ALWAYS_INLINE #else @@ -270,24 +266,22 @@ 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 INL - static bool ReadPrimitive(input, CType* value); + template + INL static bool ReadPrimitive(io::CodedInputStream* 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 INL - static bool ReadRepeatedPrimitive(int tag_size, - uint32 tag, - input, - RepeatedField* value); + template + INL static bool ReadRepeatedPrimitive(int tag_size, uint32 tag, + io::CodedInputStream* input, + RepeatedField* value); // Identical to ReadRepeatedPrimitive, except will not inline the // implementation. template - static bool ReadRepeatedPrimitiveNoInline(int tag_size, - uint32 tag, - input, + static bool ReadRepeatedPrimitiveNoInline(int tag_size, uint32 tag, + io::CodedInputStream* input, RepeatedField* value); // Reads a primitive value directly from the provided buffer. It returns a @@ -301,39 +295,39 @@ class LIBPROTOBUF_EXPORT WireFormatLite { // Reads a primitive packed field. // // This is only implemented for packable types. - template INL - static bool ReadPackedPrimitive(input, RepeatedField* value); + template + INL static bool ReadPackedPrimitive(io::CodedInputStream* input, + RepeatedField* value); // Identical to ReadPackedPrimitive, except will not inline the // implementation. template - static bool ReadPackedPrimitiveNoInline(input, RepeatedField* value); + static bool ReadPackedPrimitiveNoInline(io::CodedInputStream* input, + RepeatedField* value); // Read a packed enum field. If the is_valid function is not NULL, values for // which is_valid(value) returns false are silently dropped. - static bool ReadPackedEnumNoInline(input, + static bool ReadPackedEnumNoInline(io::CodedInputStream* input, bool (*is_valid)(int), RepeatedField* values); // Read a packed enum field. If the is_valid function is not NULL, values for // which is_valid(value) returns false are appended to unknown_fields_stream. static bool ReadPackedEnumPreserveUnknowns( - input, - field_number, - bool (*is_valid)(int), - io::CodedOutputStream* unknown_fields_stream, - RepeatedField* values); + io::CodedInputStream* input, int field_number, bool (*is_valid)(int), + io::CodedOutputStream* unknown_fields_stream, RepeatedField* values); // Read a string. ReadString(..., string* value) requires an existing string. - static inline bool ReadString(input, string* value); + static inline bool ReadString(io::CodedInputStream* input, string* value); // ReadString(..., string** p) is internal-only, and should only be called // from generated code. It starts by setting *p to "new string" // if *p == &GetEmptyStringAlreadyInited(). It then invokes - // ReadString(input, *p). This is useful for reducing code size. - static inline bool ReadString(input, string** p); + // ReadString(io::CodedInputStream* input, *p). This is useful for reducing + // code size. + static inline bool ReadString(io::CodedInputStream* input, string** p); // Analogous to ReadString(). - static bool ReadBytes(input, string* value); - static bool ReadBytes(input, string** p); + static bool ReadBytes(io::CodedInputStream* input, string* value); + static bool ReadBytes(io::CodedInputStream* input, string** p); enum Operation { @@ -346,195 +340,322 @@ class LIBPROTOBUF_EXPORT WireFormatLite { Operation op, const char* field_name); - static inline bool ReadGroup (field_number, input, MessageLite* value); - static inline bool ReadMessage(input, MessageLite* value); + static inline bool ReadGroup(int field_number, io::CodedInputStream* input, + MessageLite* value); + static inline bool ReadMessage(io::CodedInputStream* input, + MessageLite* value); // Like above, but de-virtualize the call to MergePartialFromCodedStream(). // The pointer must point at an instance of MessageType, *not* a subclass (or // the subclass must not override MergePartialFromCodedStream()). - template - static inline bool ReadGroupNoVirtual(field_number, input, + template + static inline bool ReadGroupNoVirtual(int field_number, + io::CodedInputStream* input, MessageType* value); template - static inline bool ReadMessageNoVirtual(input, MessageType* value); + static inline bool ReadMessageNoVirtual(io::CodedInputStream* input, + MessageType* value); // The same, but do not modify input's recursion depth. This is useful // when reading a bunch of groups or messages in a loop, because then the // recursion depth can be incremented before the loop and decremented after. template - static inline bool ReadGroupNoVirtualNoRecursionDepth(field_number, input, - MessageType* value); + static inline bool ReadGroupNoVirtualNoRecursionDepth( + int field_number, io::CodedInputStream* input, MessageType* value); template - static inline bool ReadMessageNoVirtualNoRecursionDepth(input, - MessageType* value); + static inline bool ReadMessageNoVirtualNoRecursionDepth( + io::CodedInputStream* input, MessageType* value); // 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. - INL static void WriteTag(field_number, WireType type, output); + INL static void WriteTag(int field_number, WireType type, + io::CodedOutputStream* output); // Write fields, without tags. - 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); + INL static void WriteInt32NoTag(int32 value, io::CodedOutputStream* output); + INL static void WriteInt64NoTag(int64 value, io::CodedOutputStream* output); + INL static void WriteUInt32NoTag(uint32 value, io::CodedOutputStream* output); + INL static void WriteUInt64NoTag(uint64 value, io::CodedOutputStream* output); + INL static void WriteSInt32NoTag(int32 value, io::CodedOutputStream* output); + INL static void WriteSInt64NoTag(int64 value, io::CodedOutputStream* output); + INL static void WriteFixed32NoTag(uint32 value, + io::CodedOutputStream* output); + INL static void WriteFixed64NoTag(uint64 value, + io::CodedOutputStream* output); + INL static void WriteSFixed32NoTag(int32 value, + io::CodedOutputStream* output); + INL static void WriteSFixed64NoTag(int64 value, + io::CodedOutputStream* output); + INL static void WriteFloatNoTag(float value, io::CodedOutputStream* output); + INL static void WriteDoubleNoTag(double value, io::CodedOutputStream* output); + INL static void WriteBoolNoTag(bool value, io::CodedOutputStream* output); + INL static void WriteEnumNoTag(int value, io::CodedOutputStream* output); // Write array of primitive fields, without tags - static void WriteFloatArray (const float* a, int n, output); - static void WriteDoubleArray (const double* a, int n, output); - static void WriteFixed32Array (const uint32* a, int n, output); - static void WriteFixed64Array (const uint64* a, int n, output); - static void WriteSFixed32Array(const int32* a, int n, output); - static void WriteSFixed64Array(const int64* a, int n, output); - static void WriteBoolArray (const bool* a, int n, output); + static void WriteFloatArray(const float* a, int n, + io::CodedOutputStream* output); + static void WriteDoubleArray(const double* a, int n, + io::CodedOutputStream* output); + static void WriteFixed32Array(const uint32* a, int n, + io::CodedOutputStream* output); + static void WriteFixed64Array(const uint64* a, int n, + io::CodedOutputStream* output); + static void WriteSFixed32Array(const int32* a, int n, + io::CodedOutputStream* output); + static void WriteSFixed64Array(const int64* a, int n, + io::CodedOutputStream* output); + static void WriteBoolArray(const bool* a, int n, + io::CodedOutputStream* output); // Write fields, including tags. - static void WriteInt32 (field_number, int32 value, output); - static void WriteInt64 (field_number, int64 value, output); - static void WriteUInt32 (field_number, uint32 value, output); - static void WriteUInt64 (field_number, uint64 value, output); - static void WriteSInt32 (field_number, int32 value, output); - static void WriteSInt64 (field_number, int64 value, output); - static void WriteFixed32 (field_number, uint32 value, output); - static void WriteFixed64 (field_number, uint64 value, output); - static void WriteSFixed32(field_number, int32 value, output); - static void WriteSFixed64(field_number, int64 value, output); - static void WriteFloat (field_number, float value, output); - static void WriteDouble (field_number, double value, output); - static void WriteBool (field_number, bool value, output); - static void WriteEnum (field_number, int value, output); - - static void WriteString(field_number, const string& value, output); - static void WriteBytes (field_number, const string& value, output); - static void WriteStringMaybeAliased( - field_number, const string& value, output); - static void WriteBytesMaybeAliased( - field_number, const string& value, output); - - static void WriteGroup( - field_number, const MessageLite& value, output); - static void WriteMessage( - field_number, const MessageLite& value, output); + static void WriteInt32(int field_number, int32 value, + io::CodedOutputStream* output); + static void WriteInt64(int field_number, int64 value, + io::CodedOutputStream* output); + static void WriteUInt32(int field_number, uint32 value, + io::CodedOutputStream* output); + static void WriteUInt64(int field_number, uint64 value, + io::CodedOutputStream* output); + static void WriteSInt32(int field_number, int32 value, + io::CodedOutputStream* output); + static void WriteSInt64(int field_number, int64 value, + io::CodedOutputStream* output); + static void WriteFixed32(int field_number, uint32 value, + io::CodedOutputStream* output); + static void WriteFixed64(int field_number, uint64 value, + io::CodedOutputStream* output); + static void WriteSFixed32(int field_number, int32 value, + io::CodedOutputStream* output); + static void WriteSFixed64(int field_number, int64 value, + io::CodedOutputStream* output); + static void WriteFloat(int field_number, float value, + io::CodedOutputStream* output); + static void WriteDouble(int field_number, double value, + io::CodedOutputStream* output); + static void WriteBool(int field_number, bool value, + io::CodedOutputStream* output); + static void WriteEnum(int field_number, int value, + io::CodedOutputStream* output); + + static void WriteString(int field_number, const string& value, + io::CodedOutputStream* output); + static void WriteBytes(int field_number, const string& value, + io::CodedOutputStream* output); + static void WriteStringMaybeAliased(int field_number, const string& value, + io::CodedOutputStream* output); + static void WriteBytesMaybeAliased(int field_number, const string& value, + io::CodedOutputStream* output); + + static void WriteGroup(int field_number, const MessageLite& value, + io::CodedOutputStream* output); + static void WriteMessage(int field_number, const MessageLite& value, + io::CodedOutputStream* output); // Like above, but these will check if the output stream has enough // space to write directly to a flat array. - static void WriteGroupMaybeToArray( - field_number, const MessageLite& value, output); - static void WriteMessageMaybeToArray( - field_number, const MessageLite& value, output); + static void WriteGroupMaybeToArray(int field_number, const MessageLite& value, + io::CodedOutputStream* output); + static void WriteMessageMaybeToArray(int field_number, + const MessageLite& value, + io::CodedOutputStream* 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 - static inline void WriteGroupNoVirtual( - field_number, const MessageType& value, output); - template - static inline void WriteMessageNoVirtual( - field_number, const MessageType& value, output); - -#undef output -#define output uint8* target + template + static inline void WriteGroupNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output); + template + static inline void WriteMessageNoVirtual(int field_number, + const MessageType& value, + io::CodedOutputStream* output); // Like above, but use only *ToArray methods of CodedOutputStream. - INL static uint8* WriteTagToArray(field_number, WireType type, output); + INL static uint8* WriteTagToArray(int field_number, WireType type, + uint8* target); // Write fields, without tags. - 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); + INL static uint8* WriteInt32NoTagToArray(int32 value, uint8* target); + INL static uint8* WriteInt64NoTagToArray(int64 value, uint8* target); + INL static uint8* WriteUInt32NoTagToArray(uint32 value, uint8* target); + INL static uint8* WriteUInt64NoTagToArray(uint64 value, uint8* target); + INL static uint8* WriteSInt32NoTagToArray(int32 value, uint8* target); + INL static uint8* WriteSInt64NoTagToArray(int64 value, uint8* target); + INL static uint8* WriteFixed32NoTagToArray(uint32 value, uint8* target); + INL static uint8* WriteFixed64NoTagToArray(uint64 value, uint8* target); + INL static uint8* WriteSFixed32NoTagToArray(int32 value, uint8* target); + INL static uint8* WriteSFixed64NoTagToArray(int64 value, uint8* target); + INL static uint8* WriteFloatNoTagToArray(float value, uint8* target); + INL static uint8* WriteDoubleNoTagToArray(double value, uint8* target); + INL static uint8* WriteBoolNoTagToArray(bool value, uint8* target); + INL static uint8* WriteEnumNoTagToArray(int value, uint8* target); + + // Write fields, without tags. These require that value.size() > 0. + template + INL static uint8* WritePrimitiveNoTagToArray( + const RepeatedField& value, + uint8* (*Writer)(T, uint8*), uint8* target); + template + INL static uint8* WriteFixedNoTagToArray( + const RepeatedField& value, + uint8* (*Writer)(T, uint8*), uint8* target); + + INL static uint8* WriteInt32NoTagToArray( + const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteInt64NoTagToArray( + const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteUInt32NoTagToArray( + const RepeatedField& value, uint8* output); + INL static uint8* WriteUInt64NoTagToArray( + const RepeatedField& value, uint8* output); + INL static uint8* WriteSInt32NoTagToArray( + const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteSInt64NoTagToArray( + const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteFixed32NoTagToArray( + const RepeatedField& value, uint8* output); + INL static uint8* WriteFixed64NoTagToArray( + const RepeatedField& value, uint8* output); + INL static uint8* WriteSFixed32NoTagToArray( + const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteSFixed64NoTagToArray( + const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteFloatNoTagToArray( + const RepeatedField< float>& value, uint8* output); + INL static uint8* WriteDoubleNoTagToArray( + const RepeatedField& value, uint8* output); + INL static uint8* WriteBoolNoTagToArray( + const RepeatedField< bool>& value, uint8* output); + INL static uint8* WriteEnumNoTagToArray( + const RepeatedField< int>& value, uint8* output); // Write fields, including tags. - 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* WriteInt32ToArray(int field_number, int32 value, + uint8* target); + INL static uint8* WriteInt64ToArray(int field_number, int64 value, + uint8* target); + INL static uint8* WriteUInt32ToArray(int field_number, uint32 value, + uint8* target); + INL static uint8* WriteUInt64ToArray(int field_number, uint64 value, + uint8* target); + INL static uint8* WriteSInt32ToArray(int field_number, int32 value, + uint8* target); + INL static uint8* WriteSInt64ToArray(int field_number, int64 value, + uint8* target); + INL static uint8* WriteFixed32ToArray(int field_number, uint32 value, + uint8* target); + INL static uint8* WriteFixed64ToArray(int field_number, uint64 value, + uint8* target); + INL static uint8* WriteSFixed32ToArray(int field_number, int32 value, + uint8* target); + INL static uint8* WriteSFixed64ToArray(int field_number, int64 value, + uint8* target); + INL static uint8* WriteFloatToArray(int field_number, float value, + uint8* target); + INL static uint8* WriteDoubleToArray(int field_number, double value, + uint8* target); + INL static uint8* WriteBoolToArray(int field_number, bool value, + uint8* target); + INL static uint8* WriteEnumToArray(int field_number, int value, + uint8* target); + + template + INL static uint8* WritePrimitiveToArray( + int field_number, + const RepeatedField& value, + uint8* (*Writer)(int, T, uint8*), uint8* target); + + INL static uint8* WriteInt32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteInt64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteUInt32ToArray( + int field_number, const RepeatedField& value, uint8* output); + INL static uint8* WriteUInt64ToArray( + int field_number, const RepeatedField& value, uint8* output); + INL static uint8* WriteSInt32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteSInt64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteFixed32ToArray( + int field_number, const RepeatedField& value, uint8* output); + INL static uint8* WriteFixed64ToArray( + int field_number, const RepeatedField& value, uint8* output); + INL static uint8* WriteSFixed32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* output); + INL static uint8* WriteSFixed64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* output); + INL static uint8* WriteFloatToArray( + int field_number, const RepeatedField< float>& value, uint8* output); + INL static uint8* WriteDoubleToArray( + int field_number, const RepeatedField& value, uint8* output); + INL static uint8* WriteBoolToArray( + int field_number, const RepeatedField< bool>& value, uint8* output); + INL static uint8* WriteEnumToArray( + int field_number, const RepeatedField< int>& value, uint8* output); + + INL static uint8* WriteStringToArray(int field_number, const string& value, + uint8* target); + INL static uint8* WriteBytesToArray(int field_number, const string& value, + uint8* target); // Whether to serialize deterministically (e.g., map keys are // sorted) is a property of a CodedOutputStream, and in the process // of serialization, the "ToArray" variants may be invoked. But they don't // have a CodedOutputStream available, so they get an additional parameter // telling them whether to serialize deterministically. - INL static uint8* InternalWriteGroupToArray( - field_number, const MessageLite& value, bool deterministic, output); - INL static uint8* InternalWriteMessageToArray( - field_number, const MessageLite& value, bool deterministic, output); + INL static uint8* InternalWriteGroupToArray(int field_number, + const MessageLite& value, + bool deterministic, + uint8* target); + INL static uint8* InternalWriteMessageToArray(int field_number, + const MessageLite& value, + bool deterministic, + uint8* target); // 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 - INL static uint8* InternalWriteGroupNoVirtualToArray( - field_number, const MessageType& value, bool deterministic, output); - template + template + INL static uint8* InternalWriteGroupNoVirtualToArray(int field_number, + const MessageType& value, + bool deterministic, + uint8* target); + template INL static uint8* InternalWriteMessageNoVirtualToArray( - field_number, const MessageType& value, bool deterministic, output); + int field_number, const MessageType& value, bool deterministic, + uint8* target); // For backward-compatibility, the last four methods also have versions // that are non-deterministic always. - INL static uint8* WriteGroupToArray( - field_number, const MessageLite& value, output) { - return InternalWriteGroupToArray(field_number_arg, value, false, target); + INL static uint8* WriteGroupToArray(int field_number, + const MessageLite& value, uint8* target) { + return InternalWriteGroupToArray(field_number, value, false, target); } - INL static uint8* WriteMessageToArray( - field_number, const MessageLite& value, output) { - return InternalWriteMessageToArray(field_number_arg, value, false, target); + INL static uint8* WriteMessageToArray(int field_number, + const MessageLite& value, + uint8* target) { + return InternalWriteMessageToArray(field_number, value, false, target); } - template - INL static uint8* WriteGroupNoVirtualToArray( - field_number, const MessageType& value, output) { - return InternalWriteGroupNoVirtualToArray(field_number_arg, value, false, + template + INL static uint8* WriteGroupNoVirtualToArray(int field_number, + const MessageType& value, + uint8* target) { + return InternalWriteGroupNoVirtualToArray(field_number, value, false, target); } - template - INL static uint8* WriteMessageNoVirtualToArray( - field_number, const MessageType& value, output) { - return InternalWriteMessageNoVirtualToArray(field_number_arg, value, false, + template + INL static uint8* WriteMessageNoVirtualToArray(int field_number, + const MessageType& value, + uint8* target) { + return InternalWriteMessageNoVirtualToArray(field_number, value, false, target); } -#undef output -#undef input #undef INL -#undef field_number - // Compute the byte size of a field. The XxSize() functions do NOT include // the tag, so you must also call TagSize(). (This is because, for repeated // fields, you should only call TagSize() once and multiply it by the element @@ -594,9 +715,9 @@ class LIBPROTOBUF_EXPORT WireFormatLite { RepeatedField* value); // Like ReadRepeatedFixedSizePrimitive but for packed primitive fields. - template GOOGLE_ATTRIBUTE_ALWAYS_INLINE - static bool ReadPackedFixedSizePrimitive(google::protobuf::io::CodedInputStream* input, - RepeatedField* value); + template + GOOGLE_ATTRIBUTE_ALWAYS_INLINE static bool ReadPackedFixedSizePrimitive( + google::protobuf::io::CodedInputStream* input, RepeatedField* 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 aa3bb3a6..05049017 100644 --- a/src/google/protobuf/wire_format_lite_inl.h +++ b/src/google/protobuf/wire_format_lite_inl.h @@ -36,11 +36,7 @@ #ifndef GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ #define GOOGLE_PROTOBUF_WIRE_FORMAT_LITE_INL_H__ -#ifdef _MSC_VER -// This is required for min/max on VS2013 only. #include -#endif - #include #include #include @@ -452,7 +448,7 @@ inline bool WireFormatLite::ReadMessage(io::CodedInputStream* input, if (p.second < 0 || !value->MergePartialFromCodedStream(input)) return false; // Make sure that parsing stopped when the limit was hit, not at an endgroup // tag. - return input->DecrementRecursionDepthAndPopLimit(p.first); + return input->DecrementRecursionDepthAndPopLimit(p.first); } // We name the template parameter something long and extremely unlikely to occur @@ -502,6 +498,7 @@ inline bool WireFormatLite::ReadMessageNoVirtual( // tag. return input->DecrementRecursionDepthAndPopLimit(p.first); } + template inline bool WireFormatLite::ReadMessageNoVirtualNoRecursionDepth( io::CodedInputStream* input, MessageType_WorkAroundCppLookupDefect* value) { @@ -671,6 +668,98 @@ inline uint8* WireFormatLite::WriteEnumNoTagToArray(int value, return io::CodedOutputStream::WriteVarint32SignExtendedToArray(value, target); } +template +inline uint8* WireFormatLite::WritePrimitiveNoTagToArray( + const RepeatedField& value, + uint8* (*Writer)(T, uint8*), uint8* target) { + const int n = value.size(); + GOOGLE_DCHECK_GT(n, 0); + + const T* ii = value.unsafe_data(); + int i = 0; + do { + target = Writer(ii[i], target); + } while (++i < n); + + return target; +} + +template +inline uint8* WireFormatLite::WriteFixedNoTagToArray( + const RepeatedField& value, + uint8* (*Writer)(T, uint8*), uint8* target) { +#if defined(PROTOBUF_LITTLE_ENDIAN) + (void) Writer; + + const int n = value.size(); + GOOGLE_DCHECK_GT(n, 0); + + const T* ii = value.unsafe_data(); + const int bytes = n * sizeof(ii[0]); + memcpy(target, ii, bytes); + return target + bytes; +#else + return WritePrimitiveNoTagToArray(value, Writer, target); +#endif +} + +inline uint8* WireFormatLite::WriteInt32NoTagToArray( + const RepeatedField< int32>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteInt32NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteInt64NoTagToArray( + const RepeatedField< int64>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteInt64NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteUInt32NoTagToArray( + const RepeatedField& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteUInt32NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteUInt64NoTagToArray( + const RepeatedField& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteUInt64NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteSInt32NoTagToArray( + const RepeatedField< int32>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteSInt32NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteSInt64NoTagToArray( + const RepeatedField< int64>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteSInt64NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteFixed32NoTagToArray( + const RepeatedField& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteFixed32NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteFixed64NoTagToArray( + const RepeatedField& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteFixed64NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteSFixed32NoTagToArray( + const RepeatedField< int32>& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteSFixed32NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteSFixed64NoTagToArray( + const RepeatedField< int64>& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteSFixed64NoTagToArray, target); +} +inline uint8* WireFormatLite::WriteFloatNoTagToArray( + const RepeatedField< float>& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteFloatNoTagToArray, target); +} +inline uint8* WireFormatLite::WriteDoubleNoTagToArray( + const RepeatedField& value, uint8* target) { + return WriteFixedNoTagToArray(value, WriteDoubleNoTagToArray, target); +} +inline uint8* WireFormatLite::WriteBoolNoTagToArray( + const RepeatedField< bool>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteBoolNoTagToArray, target); +} +inline uint8* WireFormatLite::WriteEnumNoTagToArray( + const RepeatedField< int>& value, uint8* target) { + return WritePrimitiveNoTagToArray(value, WriteEnumNoTagToArray, target); +} + inline uint8* WireFormatLite::WriteInt32ToArray(int field_number, int32 value, uint8* target) { @@ -756,6 +845,85 @@ inline uint8* WireFormatLite::WriteEnumToArray(int field_number, return WriteEnumNoTagToArray(value, target); } +template +inline uint8* WireFormatLite::WritePrimitiveToArray( + int field_number, + const RepeatedField& value, + uint8* (*Writer)(int, T, uint8*), uint8* target) { + const int n = value.size(); + if (n == 0) { + return target; + } + + const T* ii = value.unsafe_data(); + int i = 0; + do { + target = Writer(field_number, ii[i], target); + } while (++i < n); + + return target; +} + +inline uint8* WireFormatLite::WriteInt32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteInt32ToArray, target); +} +inline uint8* WireFormatLite::WriteInt64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteInt64ToArray, target); +} +inline uint8* WireFormatLite::WriteUInt32ToArray( + int field_number, const RepeatedField& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteUInt32ToArray, target); +} +inline uint8* WireFormatLite::WriteUInt64ToArray( + int field_number, const RepeatedField& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteUInt64ToArray, target); +} +inline uint8* WireFormatLite::WriteSInt32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteSInt32ToArray, target); +} +inline uint8* WireFormatLite::WriteSInt64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteSInt64ToArray, target); +} +inline uint8* WireFormatLite::WriteFixed32ToArray( + int field_number, const RepeatedField& value, uint8* target) { + return WritePrimitiveToArray( + field_number, value, WriteFixed32ToArray, target); +} +inline uint8* WireFormatLite::WriteFixed64ToArray( + int field_number, const RepeatedField& value, uint8* target) { + return WritePrimitiveToArray( + field_number, value, WriteFixed64ToArray, target); +} +inline uint8* WireFormatLite::WriteSFixed32ToArray( + int field_number, const RepeatedField< int32>& value, uint8* target) { + return WritePrimitiveToArray( + field_number, value, WriteSFixed32ToArray, target); +} +inline uint8* WireFormatLite::WriteSFixed64ToArray( + int field_number, const RepeatedField< int64>& value, uint8* target) { + return WritePrimitiveToArray( + field_number, value, WriteSFixed64ToArray, target); +} +inline uint8* WireFormatLite::WriteFloatToArray( + int field_number, const RepeatedField< float>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteFloatToArray, target); +} +inline uint8* WireFormatLite::WriteDoubleToArray( + int field_number, const RepeatedField& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteDoubleToArray, target); +} +inline uint8* WireFormatLite::WriteBoolToArray( + int field_number, const RepeatedField< bool>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteBoolToArray, target); +} +inline uint8* WireFormatLite::WriteEnumToArray( + int field_number, const RepeatedField< int>& value, uint8* target) { + return WritePrimitiveToArray(field_number, value, WriteEnumToArray, target); +} inline uint8* WireFormatLite::WriteStringToArray(int field_number, const string& value, uint8* target) { @@ -797,7 +965,8 @@ inline uint8* WireFormatLite::InternalWriteGroupNoVirtualToArray( int field_number, const MessageType_WorkAroundCppLookupDefect& value, bool deterministic, uint8* target) { target = WriteTagToArray(field_number, WIRETYPE_START_GROUP, target); - target = value.InternalSerializeWithCachedSizesToArray(deterministic, target); + target = value.MessageType_WorkAroundCppLookupDefect:: + InternalSerializeWithCachedSizesToArray(deterministic, target); return WriteTagToArray(field_number, WIRETYPE_END_GROUP, target); } template @@ -807,7 +976,8 @@ inline uint8* WireFormatLite::InternalWriteMessageNoVirtualToArray( target = WriteTagToArray(field_number, WIRETYPE_LENGTH_DELIMITED, target); target = io::CodedOutputStream::WriteVarint32ToArray( value.MessageType_WorkAroundCppLookupDefect::GetCachedSize(), target); - return value.InternalSerializeWithCachedSizesToArray(deterministic, target); + return value.MessageType_WorkAroundCppLookupDefect:: + InternalSerializeWithCachedSizesToArray(deterministic, target); } // =================================================================== diff --git a/src/google/protobuf/wire_format_unittest.cc b/src/google/protobuf/wire_format_unittest.cc index 897fec00..cafe9a48 100644 --- a/src/google/protobuf/wire_format_unittest.cc +++ b/src/google/protobuf/wire_format_unittest.cc @@ -1029,6 +1029,29 @@ TEST_F(WireFormatInvalidInputTest, InvalidSubMessage) { EXPECT_FALSE(message.ParseFromString(MakeInvalidEmbeddedMessage("\017", 1))); } +TEST_F(WireFormatInvalidInputTest, InvalidMessageWithExtraZero) { + string data; + { + // Serialize a valid proto + unittest::TestAllTypes message; + message.set_optional_int32(1); + message.SerializeToString(&data); + data.push_back(0); // Append invalid zero tag + } + + // Control case. + { + io::ArrayInputStream ais(data.data(), data.size()); + io::CodedInputStream is(&ais); + unittest::TestAllTypes message; + // It should fail but currently passes. + EXPECT_TRUE(message.MergePartialFromCodedStream(&is)); + // Parsing from the string should fail. + EXPECT_FALSE(message.ParseFromString(data)); + } +} + + TEST_F(WireFormatInvalidInputTest, InvalidGroup) { unittest::TestAllTypes message; diff --git a/src/google/protobuf/wrappers.pb.cc b/src/google/protobuf/wrappers.pb.cc index d614de9d..12c04fd5 100644 --- a/src/google/protobuf/wrappers.pb.cc +++ b/src/google/protobuf/wrappers.pb.cc @@ -47,64 +47,95 @@ namespace { } // namespace +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTableField + const TableStruct::entries[] = { + {0, 0, 0, ::google::protobuf::internal::kInvalidMask, 0, 0}, +}; + +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::AuxillaryParseTableField + const TableStruct::aux[] = { + ::google::protobuf::internal::AuxillaryParseTableField(), +}; +PROTOBUF_CONSTEXPR_VAR ::google::protobuf::internal::ParseTable const + TableStruct::schema[] = { + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, + { NULL, NULL, 0, -1, -1, false }, +}; + const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DoubleValue, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FloatValue, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int64Value, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt64Value, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(Int32Value, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UInt32Value, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BoolValue, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(StringValue, value_), ~0u, // no _has_bits_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, _internal_metadata_), ~0u, // no _extensions_ ~0u, // no _oneof_case_ + ~0u, // no _weak_field_map_ GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(BytesValue, value_), }; static const ::google::protobuf::internal::MigrationSchema schemas[] = { { 0, -1, sizeof(DoubleValue)}, - { 5, -1, sizeof(FloatValue)}, - { 10, -1, sizeof(Int64Value)}, - { 15, -1, sizeof(UInt64Value)}, - { 20, -1, sizeof(Int32Value)}, - { 25, -1, sizeof(UInt32Value)}, - { 30, -1, sizeof(BoolValue)}, - { 35, -1, sizeof(StringValue)}, - { 40, -1, sizeof(BytesValue)}, + { 6, -1, sizeof(FloatValue)}, + { 12, -1, sizeof(Int64Value)}, + { 18, -1, sizeof(UInt64Value)}, + { 24, -1, sizeof(Int32Value)}, + { 30, -1, sizeof(UInt32Value)}, + { 36, -1, sizeof(BoolValue)}, + { 42, -1, sizeof(StringValue)}, + { 48, -1, sizeof(BytesValue)}, }; static ::google::protobuf::Message const * const file_default_instances[] = { @@ -283,7 +314,7 @@ void DoubleValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* DoubleValue::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[0].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const DoubleValue& DoubleValue::default_instance() { @@ -348,6 +379,9 @@ failure: void DoubleValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.DoubleValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // double value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteDouble(1, this->value(), output); @@ -358,8 +392,10 @@ void DoubleValue::SerializeWithCachedSizes( ::google::protobuf::uint8* DoubleValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.DoubleValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // double value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(1, this->value(), target); @@ -404,6 +440,9 @@ void DoubleValue::MergeFrom(const DoubleValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.DoubleValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -453,7 +492,7 @@ void DoubleValue::InternalSwap(DoubleValue* other) { ::google::protobuf::Metadata DoubleValue::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[0]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -539,7 +578,7 @@ void FloatValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* FloatValue::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[1].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const FloatValue& FloatValue::default_instance() { @@ -604,6 +643,9 @@ failure: void FloatValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.FloatValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // float value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteFloat(1, this->value(), output); @@ -614,8 +656,10 @@ void FloatValue::SerializeWithCachedSizes( ::google::protobuf::uint8* FloatValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.FloatValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // float value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteFloatToArray(1, this->value(), target); @@ -660,6 +704,9 @@ void FloatValue::MergeFrom(const FloatValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.FloatValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -709,7 +756,7 @@ void FloatValue::InternalSwap(FloatValue* other) { ::google::protobuf::Metadata FloatValue::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[1]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -795,7 +842,7 @@ void Int64Value::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Int64Value::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[2].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Int64Value& Int64Value::default_instance() { @@ -860,6 +907,9 @@ failure: void Int64Value::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Int64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteInt64(1, this->value(), output); @@ -870,8 +920,10 @@ void Int64Value::SerializeWithCachedSizes( ::google::protobuf::uint8* Int64Value::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int64 value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(1, this->value(), target); @@ -918,6 +970,9 @@ void Int64Value::MergeFrom(const Int64Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int64Value) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -967,7 +1022,7 @@ void Int64Value::InternalSwap(Int64Value* other) { ::google::protobuf::Metadata Int64Value::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[2]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1053,7 +1108,7 @@ void UInt64Value::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* UInt64Value::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[3].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const UInt64Value& UInt64Value::default_instance() { @@ -1118,6 +1173,9 @@ failure: void UInt64Value::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.UInt64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // uint64 value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteUInt64(1, this->value(), output); @@ -1128,8 +1186,10 @@ void UInt64Value::SerializeWithCachedSizes( ::google::protobuf::uint8* UInt64Value::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt64Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // uint64 value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(1, this->value(), target); @@ -1176,6 +1236,9 @@ void UInt64Value::MergeFrom(const UInt64Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt64Value) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -1225,7 +1288,7 @@ void UInt64Value::InternalSwap(UInt64Value* other) { ::google::protobuf::Metadata UInt64Value::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[3]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1311,7 +1374,7 @@ void Int32Value::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* Int32Value::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[4].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const Int32Value& Int32Value::default_instance() { @@ -1376,6 +1439,9 @@ failure: void Int32Value::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.Int32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int32 value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->value(), output); @@ -1386,8 +1452,10 @@ void Int32Value::SerializeWithCachedSizes( ::google::protobuf::uint8* Int32Value::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.Int32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // int32 value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->value(), target); @@ -1434,6 +1502,9 @@ void Int32Value::MergeFrom(const Int32Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.Int32Value) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -1483,7 +1554,7 @@ void Int32Value::InternalSwap(Int32Value* other) { ::google::protobuf::Metadata Int32Value::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[4]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1569,7 +1640,7 @@ void UInt32Value::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* UInt32Value::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[5].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const UInt32Value& UInt32Value::default_instance() { @@ -1634,6 +1705,9 @@ failure: void UInt32Value::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.UInt32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // uint32 value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteUInt32(1, this->value(), output); @@ -1644,8 +1718,10 @@ void UInt32Value::SerializeWithCachedSizes( ::google::protobuf::uint8* UInt32Value::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.UInt32Value) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // uint32 value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteUInt32ToArray(1, this->value(), target); @@ -1692,6 +1768,9 @@ void UInt32Value::MergeFrom(const UInt32Value& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.UInt32Value) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -1741,7 +1820,7 @@ void UInt32Value::InternalSwap(UInt32Value* other) { ::google::protobuf::Metadata UInt32Value::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[5]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -1827,7 +1906,7 @@ void BoolValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* BoolValue::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[6].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const BoolValue& BoolValue::default_instance() { @@ -1892,6 +1971,9 @@ failure: void BoolValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.BoolValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // bool value = 1; if (this->value() != 0) { ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->value(), output); @@ -1902,8 +1984,10 @@ void BoolValue::SerializeWithCachedSizes( ::google::protobuf::uint8* BoolValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BoolValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // bool value = 1; if (this->value() != 0) { target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->value(), target); @@ -1948,6 +2032,9 @@ void BoolValue::MergeFrom(const BoolValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BoolValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value() != 0) { set_value(from.value()); } @@ -1997,7 +2084,7 @@ void BoolValue::InternalSwap(BoolValue* other) { ::google::protobuf::Metadata BoolValue::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[6]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2088,7 +2175,7 @@ void StringValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* StringValue::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[7].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const StringValue& StringValue::default_instance() { @@ -2155,6 +2242,9 @@ failure: void StringValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.StringValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string value = 1; if (this->value().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2170,8 +2260,10 @@ void StringValue::SerializeWithCachedSizes( ::google::protobuf::uint8* StringValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.StringValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // string value = 1; if (this->value().size() > 0) { ::google::protobuf::internal::WireFormatLite::VerifyUtf8String( @@ -2224,6 +2316,9 @@ void StringValue::MergeFrom(const StringValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.StringValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value().size() > 0) { set_value(from.value()); } @@ -2273,7 +2368,7 @@ void StringValue::InternalSwap(StringValue* other) { ::google::protobuf::Metadata StringValue::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[7]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2293,6 +2388,7 @@ void StringValue::set_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) } void StringValue::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -2416,7 +2512,7 @@ void BytesValue::SetCachedSize(int size) const { } const ::google::protobuf::Descriptor* BytesValue::descriptor() { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[8].descriptor; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages].descriptor; } const BytesValue& BytesValue::default_instance() { @@ -2479,6 +2575,9 @@ failure: void BytesValue::SerializeWithCachedSizes( ::google::protobuf::io::CodedOutputStream* output) const { // @@protoc_insertion_point(serialize_start:google.protobuf.BytesValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // bytes value = 1; if (this->value().size() > 0) { ::google::protobuf::internal::WireFormatLite::WriteBytesMaybeAliased( @@ -2490,8 +2589,10 @@ void BytesValue::SerializeWithCachedSizes( ::google::protobuf::uint8* BytesValue::InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const { - (void)deterministic; // Unused // @@protoc_insertion_point(serialize_to_array_start:google.protobuf.BytesValue) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + // bytes value = 1; if (this->value().size() > 0) { target = @@ -2540,6 +2641,9 @@ void BytesValue::MergeFrom(const BytesValue& from) { // @@protoc_insertion_point(class_specific_merge_from_start:google.protobuf.BytesValue) GOOGLE_DCHECK_NE(&from, this); _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + if (from.value().size() > 0) { set_value(from.value()); } @@ -2589,7 +2693,7 @@ void BytesValue::InternalSwap(BytesValue* other) { ::google::protobuf::Metadata BytesValue::GetMetadata() const { protobuf_google_2fprotobuf_2fwrappers_2eproto::protobuf_AssignDescriptorsOnce(); - return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[8]; + return protobuf_google_2fprotobuf_2fwrappers_2eproto::file_level_metadata[kIndexInFileMessages]; } #if PROTOBUF_INLINE_NOT_IN_HEADERS @@ -2609,6 +2713,7 @@ void BytesValue::set_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) } void BytesValue::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 61b0510d..78631a19 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -67,6 +68,9 @@ namespace protobuf { namespace protobuf_google_2fprotobuf_2fwrappers_2eproto { // Internal implementation detail -- do not call these. struct LIBPROTOBUF_EXPORT TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[]; static const ::google::protobuf::uint32 offsets[]; static void InitDefaultsImpl(); static void Shutdown(); @@ -102,6 +106,8 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_DoubleValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; void UnsafeArenaSwap(DoubleValue* other); void Swap(DoubleValue* other); @@ -125,11 +131,6 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -171,7 +172,7 @@ class LIBPROTOBUF_EXPORT DoubleValue : public ::google::protobuf::Message /* @@p typedef void DestructorSkippable_; double value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -200,6 +201,8 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr return reinterpret_cast( &_FloatValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 1; void UnsafeArenaSwap(FloatValue* other); void Swap(FloatValue* other); @@ -223,11 +226,6 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -269,7 +267,7 @@ class LIBPROTOBUF_EXPORT FloatValue : public ::google::protobuf::Message /* @@pr typedef void DestructorSkippable_; float value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -298,6 +296,8 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr return reinterpret_cast( &_Int64Value_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 2; void UnsafeArenaSwap(Int64Value* other); void Swap(Int64Value* other); @@ -321,11 +321,6 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -367,7 +362,7 @@ class LIBPROTOBUF_EXPORT Int64Value : public ::google::protobuf::Message /* @@pr typedef void DestructorSkippable_; ::google::protobuf::int64 value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -396,6 +391,8 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_UInt64Value_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 3; void UnsafeArenaSwap(UInt64Value* other); void Swap(UInt64Value* other); @@ -419,11 +416,6 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -465,7 +457,7 @@ class LIBPROTOBUF_EXPORT UInt64Value : public ::google::protobuf::Message /* @@p typedef void DestructorSkippable_; ::google::protobuf::uint64 value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -494,6 +486,8 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr return reinterpret_cast( &_Int32Value_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 4; void UnsafeArenaSwap(Int32Value* other); void Swap(Int32Value* other); @@ -517,11 +511,6 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -563,7 +552,7 @@ class LIBPROTOBUF_EXPORT Int32Value : public ::google::protobuf::Message /* @@pr typedef void DestructorSkippable_; ::google::protobuf::int32 value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -592,6 +581,8 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_UInt32Value_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 5; void UnsafeArenaSwap(UInt32Value* other); void Swap(UInt32Value* other); @@ -615,11 +606,6 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -661,7 +647,7 @@ class LIBPROTOBUF_EXPORT UInt32Value : public ::google::protobuf::Message /* @@p typedef void DestructorSkippable_; ::google::protobuf::uint32 value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -690,6 +676,8 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro return reinterpret_cast( &_BoolValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 6; void UnsafeArenaSwap(BoolValue* other); void Swap(BoolValue* other); @@ -713,11 +701,6 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -759,7 +742,7 @@ class LIBPROTOBUF_EXPORT BoolValue : public ::google::protobuf::Message /* @@pro typedef void DestructorSkippable_; bool value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -788,6 +771,8 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p return reinterpret_cast( &_StringValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 7; void UnsafeArenaSwap(StringValue* other); void Swap(StringValue* other); @@ -811,11 +796,6 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -865,7 +845,7 @@ class LIBPROTOBUF_EXPORT StringValue : public ::google::protobuf::Message /* @@p typedef void DestructorSkippable_; ::google::protobuf::internal::ArenaStringPtr value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // ------------------------------------------------------------------- @@ -894,6 +874,8 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr return reinterpret_cast( &_BytesValue_default_instance_); } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 8; void UnsafeArenaSwap(BytesValue* other); void Swap(BytesValue* other); @@ -917,11 +899,6 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray( bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL; - ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) - const PROTOBUF_FINAL { - return InternalSerializeWithCachedSizesToArray( - ::google::protobuf::io::CodedOutputStream::IsDefaultSerializationDeterministic(), output); - } int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } private: void SharedCtor(); @@ -971,7 +948,7 @@ class LIBPROTOBUF_EXPORT BytesValue : public ::google::protobuf::Message /* @@pr typedef void DestructorSkippable_; ::google::protobuf::internal::ArenaStringPtr value_; mutable int _cached_size_; - friend struct LIBPROTOBUF_EXPORT protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; + friend struct protobuf_google_2fprotobuf_2fwrappers_2eproto::TableStruct; }; // =================================================================== @@ -1121,6 +1098,7 @@ inline void StringValue::set_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.StringValue.value) } inline void StringValue::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); @@ -1191,6 +1169,7 @@ inline void BytesValue::set_value(const ::std::string& value) { // @@protoc_insertion_point(field_set:google.protobuf.BytesValue.value) } inline void BytesValue::set_value(const char* value) { + GOOGLE_DCHECK(value != NULL); value_.Set(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value), GetArenaNoVirtual()); -- cgit v1.2.3 From 32d7830e4b3966fb7ba9a8b46c04ba25fdb7d6e4 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 14:01:40 -0700 Subject: Fix C++ build for down-integration. --- BUILD | 6 ++ cmake/extract_includes.bat.in | 2 + .../src/Google.Protobuf/Reflection/Descriptor.cs | 93 +++++++++++----------- .../src/Google.Protobuf/WellKnownTypes/Duration.cs | 15 +++- .../Google.Protobuf/WellKnownTypes/Timestamp.cs | 25 ++++++ objectivec/google/protobuf/Duration.pbobjc.h | 15 +++- objectivec/google/protobuf/Timestamp.pbobjc.h | 25 ++++++ update_file_lists.sh | 2 +- 8 files changed, 134 insertions(+), 49 deletions(-) diff --git a/BUILD b/BUILD index d08b7a09..e080f7b3 100644 --- a/BUILD +++ b/BUILD @@ -206,6 +206,7 @@ RELATIVE_WELL_KNOWN_PROTOS = [ "google/protobuf/any.proto", "google/protobuf/api.proto", "google/protobuf/compiler/plugin.proto", + "google/protobuf/compiler/profile.proto", "google/protobuf/descriptor.proto", "google/protobuf/duration.proto", "google/protobuf/empty.proto", @@ -350,6 +351,7 @@ cc_library( "src/google/protobuf/compiler/php/php_generator.cc", "src/google/protobuf/compiler/plugin.cc", "src/google/protobuf/compiler/plugin.pb.cc", + "src/google/protobuf/compiler/profile.pb.cc", "src/google/protobuf/compiler/python/python_generator.cc", "src/google/protobuf/compiler/ruby/ruby_generator.cc", "src/google/protobuf/compiler/subprocess.cc", @@ -401,6 +403,9 @@ RELATIVE_TEST_PROTOS = [ "google/protobuf/unittest_enormous_descriptor.proto", "google/protobuf/unittest_import.proto", "google/protobuf/unittest_import_public.proto", + "google/protobuf/unittest_lazy_dependencies.proto", + "google/protobuf/unittest_lazy_dependencies_custom_option.proto", + "google/protobuf/unittest_lazy_dependencies_enum.proto", "google/protobuf/unittest_lite_imports_nonlite.proto", "google/protobuf/unittest_mset.proto", "google/protobuf/unittest_mset_wire_format.proto", @@ -477,6 +482,7 @@ cc_test( "src/google/protobuf/compiler/cpp/cpp_plugin_unittest.cc", "src/google/protobuf/compiler/cpp/cpp_unittest.cc", "src/google/protobuf/compiler/cpp/metadata_test.cc", + "src/google/protobuf/compiler/csharp/csharp_bootstrap_unittest.cc", "src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc", "src/google/protobuf/compiler/importer_unittest.cc", "src/google/protobuf/compiler/java/java_doc_comment_unittest.cc", diff --git a/cmake/extract_includes.bat.in b/cmake/extract_includes.bat.in index a4fd7622..245e917f 100644 --- a/cmake/extract_includes.bat.in +++ b/cmake/extract_includes.bat.in @@ -36,6 +36,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\parser.h" in copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\php\php_generator.h" include\google\protobuf\compiler\php\php_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.h" include\google\protobuf\compiler\plugin.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\plugin.pb.h" include\google\protobuf\compiler\plugin.pb.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\profile.pb.h" include\google\protobuf\compiler\profile.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\python\python_generator.h" include\google\protobuf\compiler\python\python_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\compiler\ruby\ruby_generator.h" include\google\protobuf\compiler\ruby\ruby_generator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\descriptor.h" include\google\protobuf\descriptor.h @@ -114,6 +115,7 @@ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\text_format.h" includ copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\timestamp.pb.h" include\google\protobuf\timestamp.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\type.pb.h" include\google\protobuf\type.pb.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\unknown_field_set.h" include\google\protobuf\unknown_field_set.h +copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\delimited_message_util.h" include\google\protobuf\util\delimited_message_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_comparator.h" include\google\protobuf\util\field_comparator.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\field_mask_util.h" include\google\protobuf\util\field_mask_util.h copy "${PROTOBUF_SOURCE_WIN32_PATH}\..\src\google\protobuf\util\json_util.h" include\google\protobuf\util\json_util.h diff --git a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs index d4b78dae..2960d1cd 100644 --- a/csharp/src/Google.Protobuf/Reflection/Descriptor.cs +++ b/csharp/src/Google.Protobuf/Reflection/Descriptor.cs @@ -95,57 +95,58 @@ namespace Google.Protobuf.Reflection { "X3ByZWZpeBgoIAEoCRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsy", "JC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiI6CgxPcHRp", "bWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RFX1NJWkUQAhIQCgxMSVRFX1JV", - "TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIuwBCg5NZXNzYWdlT3B0aW9ucxIm", + "TlRJTUUQAyoJCOgHEICAgIACSgQIJhAnIvIBCg5NZXNzYWdlT3B0aW9ucxIm", "ChdtZXNzYWdlX3NldF93aXJlX2Zvcm1hdBgBIAEoCDoFZmFsc2USLgofbm9f", "c3RhbmRhcmRfZGVzY3JpcHRvcl9hY2Nlc3NvchgCIAEoCDoFZmFsc2USGQoK", "ZGVwcmVjYXRlZBgDIAEoCDoFZmFsc2USEQoJbWFwX2VudHJ5GAcgASgIEkMK", "FHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1", - "Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAkingMKDEZp", - "ZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90b2J1Zi5G", - "aWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiABKAgSPwoG", - "anN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5K", - "U1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZCgpkZXBy", - "ZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxzZRJDChR1", - "bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu", - "VW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQABIICgRD", - "T1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpTX05PUk1B", - "TBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQgICAgAJK", - "BAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", + "Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgIEAlKBAgJEAoi", + "ngMKDEZpZWxkT3B0aW9ucxI6CgVjdHlwZRgBIAEoDjIjLmdvb2dsZS5wcm90", + "b2J1Zi5GaWVsZE9wdGlvbnMuQ1R5cGU6BlNUUklORxIOCgZwYWNrZWQYAiAB", + "KAgSPwoGanN0eXBlGAYgASgOMiQuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0", + "aW9ucy5KU1R5cGU6CUpTX05PUk1BTBITCgRsYXp5GAUgASgIOgVmYWxzZRIZ", + "CgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRITCgR3ZWFrGAogASgIOgVmYWxz", + "ZRJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJv", + "dG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbiIvCgVDVHlwZRIKCgZTVFJJTkcQ", + "ABIICgRDT1JEEAESEAoMU1RSSU5HX1BJRUNFEAIiNQoGSlNUeXBlEg0KCUpT", + "X05PUk1BTBAAEg0KCUpTX1NUUklORxABEg0KCUpTX05VTUJFUhACKgkI6AcQ", + "gICAgAJKBAgEEAUiXgoMT25lb2ZPcHRpb25zEkMKFHVuaW50ZXJwcmV0ZWRf", + "b3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVk", + "T3B0aW9uKgkI6AcQgICAgAIikwEKC0VudW1PcHRpb25zEhMKC2FsbG93X2Fs", + "aWFzGAIgASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50", + "ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5Vbmlu", + "dGVycHJldGVkT3B0aW9uKgkI6AcQgICAgAJKBAgFEAYifQoQRW51bVZhbHVl", + "T3B0aW9ucxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVy", + "cHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRl", + "cnByZXRlZE9wdGlvbioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkK", + "CmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0", + "aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0", + "aW9uKgkI6AcQgICAgAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRl", + "ZBghIAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5n", + "b29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVs", + "OhNJREVNUE9URU5DWV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9u", "GOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u", - "KgkI6AcQgICAgAIijQEKC0VudW1PcHRpb25zEhMKC2FsbG93X2FsaWFzGAIg", - "ASgIEhkKCmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0", - "ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJl", - "dGVkT3B0aW9uKgkI6AcQgICAgAIifQoQRW51bVZhbHVlT3B0aW9ucxIZCgpk", - "ZXByZWNhdGVkGAEgASgIOgVmYWxzZRJDChR1bmludGVycHJldGVkX29wdGlv", - "bhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlv", - "bioJCOgHEICAgIACInsKDlNlcnZpY2VPcHRpb25zEhkKCmRlcHJlY2F0ZWQY", - "ISABKAg6BWZhbHNlEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIk", - "Lmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uKgkI6AcQgICA", - "gAIirQIKDU1ldGhvZE9wdGlvbnMSGQoKZGVwcmVjYXRlZBghIAEoCDoFZmFs", - "c2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwYIiABKA4yLy5nb29nbGUucHJvdG9i", - "dWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90ZW5jeUxldmVsOhNJREVNUE9URU5D", - "WV9VTktOT1dOEkMKFHVuaW50ZXJwcmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdv", - "b2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9uIlAKEElkZW1wb3Rl", - "bmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAAEhMKD05PX1NJREVf", - "RUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICAgIACIp4CChNVbmlu", - "dGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5nb29nbGUucHJvdG9i", - "dWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIYChBpZGVudGlmaWVy", - "X3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1ZRgEIAEoBBIaChJu", - "ZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91YmxlX3ZhbHVlGAYgASgB", - "EhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdhdGVfdmFsdWUYCCAB", - "KAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJEhQKDGlzX2V4dGVu", - "c2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASAD", - "KAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24a", - "hgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVC", - "AhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29t", - "bWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMo", - "CSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3RhdGlvbhgBIAMoCzIt", - "Lmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5mby5Bbm5vdGF0aW9u", - "Gk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2Zp", - "bGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFQowBChNjb20u", - "Z29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9zSAFaPmdpdGh1Yi5j", - "b20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28vZGVzY3JpcHRvcjtk", - "ZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24=")); + "IlAKEElkZW1wb3RlbmN5TGV2ZWwSFwoTSURFTVBPVEVOQ1lfVU5LTk9XThAA", + "EhMKD05PX1NJREVfRUZGRUNUUxABEg4KCklERU1QT1RFTlQQAioJCOgHEICA", + "gIACIp4CChNVbmludGVycHJldGVkT3B0aW9uEjsKBG5hbWUYAiADKAsyLS5n", + "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbi5OYW1lUGFydBIY", + "ChBpZGVudGlmaWVyX3ZhbHVlGAMgASgJEhoKEnBvc2l0aXZlX2ludF92YWx1", + "ZRgEIAEoBBIaChJuZWdhdGl2ZV9pbnRfdmFsdWUYBSABKAMSFAoMZG91Ymxl", + "X3ZhbHVlGAYgASgBEhQKDHN0cmluZ192YWx1ZRgHIAEoDBIXCg9hZ2dyZWdh", + "dGVfdmFsdWUYCCABKAkaMwoITmFtZVBhcnQSEQoJbmFtZV9wYXJ0GAEgAigJ", + "EhQKDGlzX2V4dGVuc2lvbhgCIAIoCCLVAQoOU291cmNlQ29kZUluZm8SOgoI", + "bG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9idWYuU291cmNlQ29kZUlu", + "Zm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBhdGgYASADKAVCAhABEhAK", + "BHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29tbWVudHMYAyABKAkSGQoR", + "dHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVhZGluZ19kZXRhY2hlZF9j", + "b21tZW50cxgGIAMoCSKnAQoRR2VuZXJhdGVkQ29kZUluZm8SQQoKYW5ub3Rh", + "dGlvbhgBIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5HZW5lcmF0ZWRDb2RlSW5m", + "by5Bbm5vdGF0aW9uGk8KCkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAES", + "EwoLc291cmNlX2ZpbGUYAiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQg", + "ASgFQowBChNjb20uZ29vZ2xlLnByb3RvYnVmQhBEZXNjcmlwdG9yUHJvdG9z", + "SAFaPmdpdGh1Yi5jb20vZ29sYW5nL3Byb3RvYnVmL3Byb3RvYy1nZW4tZ28v", + "ZGVzY3JpcHRvcjtkZXNjcmlwdG9yogIDR1BCqgIaR29vZ2xlLlByb3RvYnVm", + "LlJlZmxlY3Rpb24=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs index 03b19c77..94159cb8 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Duration.cs @@ -46,6 +46,8 @@ namespace Google.Protobuf.WellKnownTypes { /// two Timestamp values is a Duration and it can be added or subtracted /// from a Timestamp. Range is approximately +-10,000 years. /// + /// # Examples + /// /// Example 1: Compute Duration from two Timestamps in pseudo code. /// /// Timestamp start = ...; @@ -85,6 +87,16 @@ namespace Google.Protobuf.WellKnownTypes { /// td = datetime.timedelta(days=3, minutes=10) /// duration = Duration() /// duration.FromTimedelta(td) + /// + /// # JSON Mapping + /// + /// In JSON format, the Duration type is encoded as a string rather than an + /// object, where the string ends in the suffix "s" (indicating seconds) and + /// is preceded by the number of seconds, with nanoseconds expressed as + /// fractional seconds. For example, 3 seconds with 0 nanoseconds should be + /// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should + /// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 + /// microsecond should be expressed in JSON format as "3.000001s". /// public sealed partial class Duration : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Duration()); @@ -124,7 +136,8 @@ namespace Google.Protobuf.WellKnownTypes { private long seconds_; ///

/// Signed seconds of the span of time. Must be from -315,576,000,000 - /// to +315,576,000,000 inclusive. + /// to +315,576,000,000 inclusive. Note: these bounds are computed from: + /// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years /// [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public long Seconds { diff --git a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs index b789f6da..911f797e 100644 --- a/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs +++ b/csharp/src/Google.Protobuf/WellKnownTypes/Timestamp.cs @@ -51,6 +51,8 @@ namespace Google.Protobuf.WellKnownTypes { /// and from RFC 3339 date strings. /// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). /// + /// # Examples + /// /// Example 1: Compute Timestamp from POSIX `time()`. /// /// Timestamp timestamp; @@ -89,6 +91,29 @@ namespace Google.Protobuf.WellKnownTypes { /// /// timestamp = Timestamp() /// timestamp.GetCurrentTime() + /// + /// # JSON Mapping + /// + /// In JSON format, the Timestamp type is encoded as a string in the + /// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the + /// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" + /// where {year} is always expressed using four digits while {month}, {day}, + /// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional + /// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), + /// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone + /// is required, though only UTC (as indicated by "Z") is presently supported. + /// + /// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past + /// 01:30 UTC on January 15, 2017. + /// + /// In JavaScript, one can convert a Date object to this format using the + /// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] + /// method. In Python, a standard `datetime.datetime` object can be converted + /// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) + /// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one + /// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( + /// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()) + /// to obtain a formatter capable of generating timestamps in this format. /// public sealed partial class Timestamp : pb::IMessage { private static readonly pb::MessageParser _parser = new pb::MessageParser(() => new Timestamp()); diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h index e70138a0..d9a388ac 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.h +++ b/objectivec/google/protobuf/Duration.pbobjc.h @@ -59,6 +59,8 @@ typedef GPB_ENUM(GPBDuration_FieldNumber) { * two Timestamp values is a Duration and it can be added or subtracted * from a Timestamp. Range is approximately +-10,000 years. * + * # Examples + * * Example 1: Compute Duration from two Timestamps in pseudo code. * * Timestamp start = ...; @@ -98,12 +100,23 @@ typedef GPB_ENUM(GPBDuration_FieldNumber) { * td = datetime.timedelta(days=3, minutes=10) * duration = Duration() * duration.FromTimedelta(td) + * + * # JSON Mapping + * + * In JSON format, the Duration type is encoded as a string rather than an + * object, where the string ends in the suffix "s" (indicating seconds) and + * is preceded by the number of seconds, with nanoseconds expressed as + * fractional seconds. For example, 3 seconds with 0 nanoseconds should be + * encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should + * be expressed in JSON format as "3.000000001s", and 3 seconds and 1 + * microsecond should be expressed in JSON format as "3.000001s". **/ @interface GPBDuration : GPBMessage /** * Signed seconds of the span of time. Must be from -315,576,000,000 - * to +315,576,000,000 inclusive. + * to +315,576,000,000 inclusive. Note: these bounds are computed from: + * 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years **/ @property(nonatomic, readwrite) int64_t seconds; diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h index 9c83d094..5d74bd32 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.h +++ b/objectivec/google/protobuf/Timestamp.pbobjc.h @@ -64,6 +64,8 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) { * and from RFC 3339 date strings. * See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). * + * # Examples + * * Example 1: Compute Timestamp from POSIX `time()`. * * Timestamp timestamp; @@ -103,6 +105,29 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) { * * timestamp = Timestamp() * timestamp.GetCurrentTime() + * + * # JSON Mapping + * + * In JSON format, the Timestamp type is encoded as a string in the + * [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the + * format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" + * where {year} is always expressed using four digits while {month}, {day}, + * {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional + * seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), + * are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone + * is required, though only UTC (as indicated by "Z") is presently supported. + * + * For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past + * 01:30 UTC on January 15, 2017. + * + * In JavaScript, one can convert a Date object to this format using the + * standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] + * method. In Python, a standard `datetime.datetime` object can be converted + * to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) + * with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one + * can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( + * http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime()) + * to obtain a formatter capable of generating timestamps in this format. **/ @interface GPBTimestamp : GPBMessage diff --git a/update_file_lists.sh b/update_file_lists.sh index d76a1610..9c0fbdc5 100755 --- a/update_file_lists.sh +++ b/update_file_lists.sh @@ -135,7 +135,7 @@ for HEADER in $PUBLIC_HEADERS; do done | sort | uniq | sed "s/^/mkdir include\\\\/" >> $EXTRACT_INCLUDES_BAT for HEADER in $PUBLIC_HEADERS; do WINPATH=$(echo $HEADER | sed 's;/;\\;g') - echo "copy \${PROTOBUF_SOURCE_WIN32_PATH}\\..\\src\\$WINPATH include\\$WINPATH" >> $EXTRACT_INCLUDES_BAT + echo "copy \"\${PROTOBUF_SOURCE_WIN32_PATH}\\..\\src\\$WINPATH\" include\\$WINPATH" >> $EXTRACT_INCLUDES_BAT done ################################################################################ -- cgit v1.2.3 From acde1651b53ddc50f0e37907acd109b2e10e5274 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 15:14:18 -0700 Subject: Update BUILD file for C# tests. --- BUILD | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/BUILD b/BUILD index e080f7b3..e5662c4d 100644 --- a/BUILD +++ b/BUILD @@ -549,6 +549,10 @@ cc_test( ":test_plugin", ] + glob([ "src/google/protobuf/**/*", + # Files for csharp_bootstrap_unittest.cc. + "conformance/**/*", + "csharp/src/**/*", + "examples/**/*", ]), includes = [ "src/", -- cgit v1.2.3 From 84f6954ca91e7dbe57e4c972f9ac260361beaa49 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 16:03:53 -0700 Subject: Fix Java build. --- java/core/pom.xml | 5 +++++ java/core/src/test/java/com/google/protobuf/MapTest.java | 3 ++- java/util/src/main/java/com/google/protobuf/util/JsonFormat.java | 5 +++-- java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/java/core/pom.xml b/java/core/pom.xml index be0da5ea..79160f2e 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -34,6 +34,11 @@ easymockclassextension test + + com.google.truth + truth + test + diff --git a/java/core/src/test/java/com/google/protobuf/MapTest.java b/java/core/src/test/java/com/google/protobuf/MapTest.java index 01b371a3..9ce5ebc9 100644 --- a/java/core/src/test/java/com/google/protobuf/MapTest.java +++ b/java/core/src/test/java/com/google/protobuf/MapTest.java @@ -1516,7 +1516,8 @@ public class MapTest extends TestCase { } try { - builder.putAllInt32ToMessageField(newMap(4, null, 5, null)); + builder.putAllInt32ToMessageField( + MapTest.newMap(4, null, 5, null)); fail(); } catch (NullPointerException expected) { } diff --git a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java index 5e0f5fe3..37fa194a 100644 --- a/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java +++ b/java/util/src/main/java/com/google/protobuf/util/JsonFormat.java @@ -104,7 +104,8 @@ public class JsonFormat { */ public static Printer printer() { return new Printer( - TypeRegistry.getEmptyTypeRegistry(), false, Collections.emptySet(), false, false); + TypeRegistry.getEmptyTypeRegistry(), false, Collections.emptySet(), + false, false); } /** @@ -167,7 +168,7 @@ public class JsonFormat { return new Printer( registry, true, - Collections.emptySet(), + Collections.emptySet(), preservingProtoFieldNames, omittingInsignificantWhitespace); } diff --git a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java index 6943093f..695176ed 100644 --- a/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java +++ b/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java @@ -1319,7 +1319,7 @@ public class JsonFormatTest extends TestCase { } try { - JsonFormat.printer().includingDefaultValueFields(Collections.emptySet()); + JsonFormat.printer().includingDefaultValueFields(Collections.emptySet()); fail("IllegalArgumentException is expected."); } catch (IllegalArgumentException e) { // Expected. -- cgit v1.2.3 From e47c068cfa37678651112452f93453d2c6cfec86 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 16:17:18 -0700 Subject: Update python conformance failure list. --- conformance/failure_list_python.txt | 595 -------------------------------- conformance/failure_list_python_cpp.txt | 586 ------------------------------- 2 files changed, 1181 deletions(-) diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 0e907fe1..84a7dd75 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -1,615 +1,20 @@ -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput -Recommended.JsonInput.BoolFieldAllCapitalFalse -Recommended.JsonInput.BoolFieldAllCapitalTrue -Recommended.JsonInput.BoolFieldCamelCaseFalse -Recommended.JsonInput.BoolFieldCamelCaseTrue -Recommended.JsonInput.BoolFieldDoubleQuotedFalse -Recommended.JsonInput.BoolFieldDoubleQuotedTrue -Recommended.JsonInput.BoolFieldIntegerOne -Recommended.JsonInput.BoolFieldIntegerZero -Recommended.JsonInput.BoolMapFieldKeyNotQuoted Recommended.JsonInput.DoubleFieldInfinityNotQuoted Recommended.JsonInput.DoubleFieldNanNotQuoted Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.JsonInput.DurationHas3FractionalDigits.Validator -Recommended.JsonInput.DurationHas6FractionalDigits.Validator -Recommended.JsonInput.DurationHas9FractionalDigits.Validator -Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator -Recommended.JsonInput.FieldMaskInvalidCharacter -Recommended.JsonInput.FieldNameDuplicate -Recommended.JsonInput.FieldNameDuplicateDifferentCasing1 -Recommended.JsonInput.FieldNameDuplicateDifferentCasing2 -Recommended.JsonInput.FieldNameNotQuoted -Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput -Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput -Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator Recommended.JsonInput.FloatFieldInfinityNotQuoted Recommended.JsonInput.FloatFieldNanNotQuoted Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted -Recommended.JsonInput.Int32MapFieldKeyNotQuoted -Recommended.JsonInput.Int64FieldBeString.Validator -Recommended.JsonInput.Int64MapFieldKeyNotQuoted -Recommended.JsonInput.JsonWithComments -Recommended.JsonInput.MapFieldKeyIsNull -Recommended.JsonInput.MapFieldValueIsNull -Recommended.JsonInput.MissingCommaMultiline -Recommended.JsonInput.MissingCommaOneLine -Recommended.JsonInput.MultilineNoSpaces.JsonOutput -Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput -Recommended.JsonInput.MultilineWithSpaces.JsonOutput -Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput -Recommended.JsonInput.OneLineNoSpaces.JsonOutput -Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput -Recommended.JsonInput.OneLineWithSpaces.JsonOutput -Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput -Recommended.JsonInput.OneofZeroBool.JsonOutput -Recommended.JsonInput.OneofZeroBool.ProtobufOutput -Recommended.JsonInput.OneofZeroBytes.JsonOutput -Recommended.JsonInput.OneofZeroBytes.ProtobufOutput -Recommended.JsonInput.OneofZeroDouble.JsonOutput -Recommended.JsonInput.OneofZeroDouble.ProtobufOutput -Recommended.JsonInput.OneofZeroEnum.JsonOutput -Recommended.JsonInput.OneofZeroEnum.ProtobufOutput -Recommended.JsonInput.OneofZeroFloat.JsonOutput -Recommended.JsonInput.OneofZeroFloat.ProtobufOutput -Recommended.JsonInput.OneofZeroMessage.JsonOutput -Recommended.JsonInput.OneofZeroMessage.ProtobufOutput -Recommended.JsonInput.OneofZeroString.JsonOutput -Recommended.JsonInput.OneofZeroString.ProtobufOutput -Recommended.JsonInput.OneofZeroUint32.JsonOutput -Recommended.JsonInput.OneofZeroUint32.ProtobufOutput -Recommended.JsonInput.OneofZeroUint64.JsonOutput -Recommended.JsonInput.OneofZeroUint64.ProtobufOutput -Recommended.JsonInput.RepeatedFieldMessageElementIsNull -Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull -Recommended.JsonInput.RepeatedFieldTrailingComma -Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines -Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace -Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace -Recommended.JsonInput.StringEndsWithEscapeChar -Recommended.JsonInput.StringFieldInvalidEscape -Recommended.JsonInput.StringFieldSingleQuoteBoth -Recommended.JsonInput.StringFieldSingleQuoteKey -Recommended.JsonInput.StringFieldSingleQuoteValue -Recommended.JsonInput.StringFieldSurrogateInWrongOrder -Recommended.JsonInput.StringFieldUnpairedHighSurrogate -Recommended.JsonInput.StringFieldUnpairedLowSurrogate -Recommended.JsonInput.StringFieldUnterminatedEscape -Recommended.JsonInput.StringFieldUppercaseEscapeLetter -Recommended.JsonInput.TimestampHas3FractionalDigits.Validator -Recommended.JsonInput.TimestampHas6FractionalDigits.Validator -Recommended.JsonInput.TimestampHas9FractionalDigits.Validator -Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator -Recommended.JsonInput.TimestampZeroNormalized.Validator -Recommended.JsonInput.TrailingCommaInAnObject -Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines -Recommended.JsonInput.TrailingCommaInAnObjectWithSpace -Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace -Recommended.JsonInput.Uint32MapFieldKeyNotQuoted -Recommended.JsonInput.Uint64FieldBeString.Validator -Recommended.JsonInput.Uint64MapFieldKeyNotQuoted -Recommended.ProtobufInput.OneofZeroBool.JsonOutput -Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput -Recommended.ProtobufInput.OneofZeroBytes.JsonOutput -Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput -Recommended.ProtobufInput.OneofZeroDouble.JsonOutput -Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput -Recommended.ProtobufInput.OneofZeroEnum.JsonOutput -Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput -Recommended.ProtobufInput.OneofZeroFloat.JsonOutput -Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput -Recommended.ProtobufInput.OneofZeroMessage.JsonOutput -Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput -Recommended.ProtobufInput.OneofZeroString.JsonOutput -Recommended.ProtobufInput.OneofZeroString.ProtobufOutput -Recommended.ProtobufInput.OneofZeroUint32.JsonOutput -Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput -Recommended.ProtobufInput.OneofZeroUint64.JsonOutput -Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput -Required.DurationProtoInputTooLarge.JsonOutput -Required.DurationProtoInputTooSmall.JsonOutput -Required.JsonInput.AllFieldAcceptNull.JsonOutput -Required.JsonInput.AllFieldAcceptNull.ProtobufOutput -Required.JsonInput.Any.JsonOutput -Required.JsonInput.Any.ProtobufOutput -Required.JsonInput.AnyNested.JsonOutput -Required.JsonInput.AnyNested.ProtobufOutput -Required.JsonInput.AnyUnorderedTypeTag.JsonOutput -Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput -Required.JsonInput.AnyWithDuration.JsonOutput -Required.JsonInput.AnyWithDuration.ProtobufOutput -Required.JsonInput.AnyWithFieldMask.JsonOutput -Required.JsonInput.AnyWithFieldMask.ProtobufOutput -Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput -Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput -Required.JsonInput.AnyWithStruct.JsonOutput -Required.JsonInput.AnyWithStruct.ProtobufOutput -Required.JsonInput.AnyWithTimestamp.JsonOutput -Required.JsonInput.AnyWithTimestamp.ProtobufOutput -Required.JsonInput.AnyWithValueForInteger.JsonOutput -Required.JsonInput.AnyWithValueForInteger.ProtobufOutput -Required.JsonInput.AnyWithValueForJsonObject.JsonOutput -Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput -Required.JsonInput.BoolFieldFalse.JsonOutput -Required.JsonInput.BoolFieldFalse.ProtobufOutput -Required.JsonInput.BoolFieldTrue.JsonOutput -Required.JsonInput.BoolFieldTrue.ProtobufOutput -Required.JsonInput.BoolMapEscapedKey.JsonOutput -Required.JsonInput.BoolMapEscapedKey.ProtobufOutput -Required.JsonInput.BoolMapField.JsonOutput -Required.JsonInput.BoolMapField.ProtobufOutput -Required.JsonInput.BytesField.JsonOutput -Required.JsonInput.BytesField.ProtobufOutput Required.JsonInput.BytesFieldInvalidBase64Characters -Required.JsonInput.BytesRepeatedField.JsonOutput -Required.JsonInput.BytesRepeatedField.ProtobufOutput -Required.JsonInput.DoubleFieldInfinity.JsonOutput -Required.JsonInput.DoubleFieldInfinity.ProtobufOutput -Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput -Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput -Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput -Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput -Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput -Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput -Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput -Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput -Required.JsonInput.DoubleFieldNan.JsonOutput -Required.JsonInput.DoubleFieldNan.ProtobufOutput -Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput -Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput -Required.JsonInput.DoubleFieldQuotedValue.JsonOutput -Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput -Required.JsonInput.DoubleFieldTooLarge Required.JsonInput.DoubleFieldTooSmall -Required.JsonInput.DurationJsonInputTooLarge -Required.JsonInput.DurationJsonInputTooSmall -Required.JsonInput.DurationMaxValue.JsonOutput -Required.JsonInput.DurationMaxValue.ProtobufOutput -Required.JsonInput.DurationMinValue.JsonOutput -Required.JsonInput.DurationMinValue.ProtobufOutput -Required.JsonInput.DurationMissingS -Required.JsonInput.DurationRepeatedValue.JsonOutput -Required.JsonInput.DurationRepeatedValue.ProtobufOutput -Required.JsonInput.EnumField.JsonOutput -Required.JsonInput.EnumField.ProtobufOutput -Required.JsonInput.EnumFieldNotQuoted -Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput -Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput -Required.JsonInput.EnumFieldNumericValueZero.JsonOutput -Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput Required.JsonInput.EnumFieldUnknownValue.Validator -Required.JsonInput.EnumRepeatedField.JsonOutput -Required.JsonInput.EnumRepeatedField.ProtobufOutput -Required.JsonInput.FieldMask.JsonOutput -Required.JsonInput.FieldMask.ProtobufOutput -Required.JsonInput.FieldNameEscaped.JsonOutput -Required.JsonInput.FieldNameEscaped.ProtobufOutput -Required.JsonInput.FieldNameInLowerCamelCase.Validator -Required.JsonInput.FieldNameInSnakeCase.JsonOutput -Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput -Required.JsonInput.FieldNameWithMixedCases.JsonOutput -Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput -Required.JsonInput.FieldNameWithMixedCases.Validator -Required.JsonInput.FieldNameWithNumbers.JsonOutput -Required.JsonInput.FieldNameWithNumbers.ProtobufOutput -Required.JsonInput.FieldNameWithNumbers.Validator -Required.JsonInput.FloatFieldInfinity.JsonOutput -Required.JsonInput.FloatFieldInfinity.ProtobufOutput -Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput -Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput -Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput -Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput -Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput -Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput -Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput -Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput -Required.JsonInput.FloatFieldNan.JsonOutput -Required.JsonInput.FloatFieldNan.ProtobufOutput -Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput -Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput -Required.JsonInput.FloatFieldQuotedValue.JsonOutput -Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput Required.JsonInput.FloatFieldTooLarge Required.JsonInput.FloatFieldTooSmall -Required.JsonInput.HelloWorld.JsonOutput -Required.JsonInput.HelloWorld.ProtobufOutput -Required.JsonInput.Int32FieldExponentialFormat.JsonOutput -Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput -Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput -Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput -Required.JsonInput.Int32FieldLeadingSpace -Required.JsonInput.Int32FieldLeadingZero -Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput -Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput -Required.JsonInput.Int32FieldMaxValue.JsonOutput -Required.JsonInput.Int32FieldMaxValue.ProtobufOutput -Required.JsonInput.Int32FieldMinFloatValue.JsonOutput -Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput -Required.JsonInput.Int32FieldMinValue.JsonOutput -Required.JsonInput.Int32FieldMinValue.ProtobufOutput -Required.JsonInput.Int32FieldNegativeWithLeadingZero -Required.JsonInput.Int32FieldNotInteger -Required.JsonInput.Int32FieldNotNumber -Required.JsonInput.Int32FieldPlusSign -Required.JsonInput.Int32FieldStringValue.JsonOutput -Required.JsonInput.Int32FieldStringValue.ProtobufOutput -Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput -Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput -Required.JsonInput.Int32FieldTooLarge -Required.JsonInput.Int32FieldTooSmall -Required.JsonInput.Int32FieldTrailingSpace -Required.JsonInput.Int32MapEscapedKey.JsonOutput -Required.JsonInput.Int32MapEscapedKey.ProtobufOutput -Required.JsonInput.Int32MapField.JsonOutput -Required.JsonInput.Int32MapField.ProtobufOutput -Required.JsonInput.Int64FieldMaxValue.JsonOutput -Required.JsonInput.Int64FieldMaxValue.ProtobufOutput -Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput -Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput -Required.JsonInput.Int64FieldMinValue.JsonOutput -Required.JsonInput.Int64FieldMinValue.ProtobufOutput -Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput -Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput -Required.JsonInput.Int64FieldNotInteger -Required.JsonInput.Int64FieldNotNumber -Required.JsonInput.Int64FieldTooLarge -Required.JsonInput.Int64FieldTooSmall -Required.JsonInput.Int64MapEscapedKey.JsonOutput -Required.JsonInput.Int64MapEscapedKey.ProtobufOutput -Required.JsonInput.Int64MapField.JsonOutput -Required.JsonInput.Int64MapField.ProtobufOutput -Required.JsonInput.MessageField.JsonOutput -Required.JsonInput.MessageField.ProtobufOutput -Required.JsonInput.MessageMapField.JsonOutput -Required.JsonInput.MessageMapField.ProtobufOutput -Required.JsonInput.MessageRepeatedField.JsonOutput -Required.JsonInput.MessageRepeatedField.ProtobufOutput -Required.JsonInput.OneofFieldDuplicate -Required.JsonInput.OptionalBoolWrapper.JsonOutput -Required.JsonInput.OptionalBoolWrapper.ProtobufOutput -Required.JsonInput.OptionalBytesWrapper.JsonOutput -Required.JsonInput.OptionalBytesWrapper.ProtobufOutput -Required.JsonInput.OptionalDoubleWrapper.JsonOutput -Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput -Required.JsonInput.OptionalFloatWrapper.JsonOutput -Required.JsonInput.OptionalFloatWrapper.ProtobufOutput -Required.JsonInput.OptionalInt32Wrapper.JsonOutput -Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput -Required.JsonInput.OptionalInt64Wrapper.JsonOutput -Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput -Required.JsonInput.OptionalStringWrapper.JsonOutput -Required.JsonInput.OptionalStringWrapper.ProtobufOutput -Required.JsonInput.OptionalUint32Wrapper.JsonOutput -Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput -Required.JsonInput.OptionalUint64Wrapper.JsonOutput -Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput -Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput -Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput -Required.JsonInput.OriginalProtoFieldName.JsonOutput -Required.JsonInput.OriginalProtoFieldName.ProtobufOutput -Required.JsonInput.PrimitiveRepeatedField.JsonOutput -Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput -Required.JsonInput.RepeatedBoolWrapper.JsonOutput -Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput -Required.JsonInput.RepeatedBytesWrapper.JsonOutput -Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput -Required.JsonInput.RepeatedDoubleWrapper.JsonOutput -Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage -Required.JsonInput.RepeatedFloatWrapper.JsonOutput -Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput -Required.JsonInput.RepeatedInt32Wrapper.JsonOutput -Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput -Required.JsonInput.RepeatedInt64Wrapper.JsonOutput -Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput -Required.JsonInput.RepeatedStringWrapper.JsonOutput -Required.JsonInput.RepeatedStringWrapper.ProtobufOutput -Required.JsonInput.RepeatedUint32Wrapper.JsonOutput -Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput -Required.JsonInput.RepeatedUint64Wrapper.JsonOutput -Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput -Required.JsonInput.StringField.JsonOutput -Required.JsonInput.StringField.ProtobufOutput -Required.JsonInput.StringFieldEscape.JsonOutput -Required.JsonInput.StringFieldEscape.ProtobufOutput -Required.JsonInput.StringFieldNotAString -Required.JsonInput.StringFieldSurrogatePair.JsonOutput -Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput -Required.JsonInput.StringFieldUnicode.JsonOutput -Required.JsonInput.StringFieldUnicode.ProtobufOutput -Required.JsonInput.StringFieldUnicodeEscape.JsonOutput -Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput -Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput -Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput -Required.JsonInput.StringRepeatedField.JsonOutput -Required.JsonInput.StringRepeatedField.ProtobufOutput -Required.JsonInput.Struct.JsonOutput -Required.JsonInput.Struct.ProtobufOutput Required.JsonInput.TimestampJsonInputLowercaseT -Required.JsonInput.TimestampJsonInputLowercaseZ -Required.JsonInput.TimestampJsonInputMissingT -Required.JsonInput.TimestampJsonInputMissingZ -Required.JsonInput.TimestampJsonInputTooLarge -Required.JsonInput.TimestampJsonInputTooSmall -Required.JsonInput.TimestampMaxValue.JsonOutput -Required.JsonInput.TimestampMaxValue.ProtobufOutput -Required.JsonInput.TimestampMinValue.JsonOutput -Required.JsonInput.TimestampMinValue.ProtobufOutput -Required.JsonInput.TimestampRepeatedValue.JsonOutput -Required.JsonInput.TimestampRepeatedValue.ProtobufOutput -Required.JsonInput.TimestampWithNegativeOffset.JsonOutput -Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput -Required.JsonInput.TimestampWithPositiveOffset.JsonOutput -Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput -Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput -Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -Required.JsonInput.Uint32FieldMaxValue.JsonOutput -Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput -Required.JsonInput.Uint32FieldNotInteger -Required.JsonInput.Uint32FieldNotNumber -Required.JsonInput.Uint32FieldTooLarge -Required.JsonInput.Uint32MapField.JsonOutput -Required.JsonInput.Uint32MapField.ProtobufOutput -Required.JsonInput.Uint64FieldMaxValue.JsonOutput -Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput -Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput -Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput -Required.JsonInput.Uint64FieldNotInteger -Required.JsonInput.Uint64FieldNotNumber -Required.JsonInput.Uint64FieldTooLarge -Required.JsonInput.Uint64MapField.JsonOutput -Required.JsonInput.Uint64MapField.ProtobufOutput -Required.JsonInput.ValueAcceptBool.JsonOutput -Required.JsonInput.ValueAcceptBool.ProtobufOutput -Required.JsonInput.ValueAcceptFloat.JsonOutput -Required.JsonInput.ValueAcceptFloat.ProtobufOutput -Required.JsonInput.ValueAcceptInteger.JsonOutput -Required.JsonInput.ValueAcceptInteger.ProtobufOutput -Required.JsonInput.ValueAcceptList.JsonOutput -Required.JsonInput.ValueAcceptList.ProtobufOutput -Required.JsonInput.ValueAcceptNull.JsonOutput -Required.JsonInput.ValueAcceptNull.ProtobufOutput -Required.JsonInput.ValueAcceptObject.JsonOutput -Required.JsonInput.ValueAcceptObject.ProtobufOutput -Required.JsonInput.ValueAcceptString.JsonOutput -Required.JsonInput.ValueAcceptString.ProtobufOutput -Required.JsonInput.WrapperTypesWithNullValue.JsonOutput -Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput -Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput -Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput -Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput -Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput Required.ProtobufInput.IllegalZeroFieldNum_Case_0 Required.ProtobufInput.IllegalZeroFieldNum_Case_1 Required.ProtobufInput.IllegalZeroFieldNum_Case_2 Required.ProtobufInput.IllegalZeroFieldNum_Case_3 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL -Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES -Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING -Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64 -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING -Required.ProtobufInput.PrematureEofInPackedField.BOOL -Required.ProtobufInput.PrematureEofInPackedField.DOUBLE -Required.ProtobufInput.PrematureEofInPackedField.ENUM -Required.ProtobufInput.PrematureEofInPackedField.FIXED32 -Required.ProtobufInput.PrematureEofInPackedField.FIXED64 -Required.ProtobufInput.PrematureEofInPackedField.FLOAT -Required.ProtobufInput.PrematureEofInPackedField.INT32 -Required.ProtobufInput.PrematureEofInPackedField.INT64 -Required.ProtobufInput.PrematureEofInPackedField.SFIXED32 -Required.ProtobufInput.PrematureEofInPackedField.SFIXED64 -Required.ProtobufInput.PrematureEofInPackedField.SINT32 -Required.ProtobufInput.PrematureEofInPackedField.SINT64 -Required.ProtobufInput.PrematureEofInPackedField.UINT32 -Required.ProtobufInput.PrematureEofInPackedField.UINT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL -Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE -Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM -Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT -Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64 -Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL -Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES -Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM -Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT -Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING -Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64 -Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput -Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput -Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput -Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput -Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput -Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput -Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput -Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput -Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput -Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput -Required.TimestampProtoInputTooLarge.JsonOutput -Required.TimestampProtoInputTooSmall.JsonOutput diff --git a/conformance/failure_list_python_cpp.txt b/conformance/failure_list_python_cpp.txt index d72d79cd..92404d2f 100644 --- a/conformance/failure_list_python_cpp.txt +++ b/conformance/failure_list_python_cpp.txt @@ -7,461 +7,21 @@ # TODO(haberman): insert links to corresponding bugs tracking the issue. # Should we use GitHub issues or the Google-internal bug tracker? -Recommended.FieldMaskNumbersDontRoundTrip.JsonOutput -Recommended.FieldMaskPathsDontRoundTrip.JsonOutput -Recommended.FieldMaskTooManyUnderscore.JsonOutput -Recommended.JsonInput.BoolFieldAllCapitalFalse -Recommended.JsonInput.BoolFieldAllCapitalTrue -Recommended.JsonInput.BoolFieldCamelCaseFalse -Recommended.JsonInput.BoolFieldCamelCaseTrue -Recommended.JsonInput.BoolFieldDoubleQuotedFalse -Recommended.JsonInput.BoolFieldDoubleQuotedTrue -Recommended.JsonInput.BoolFieldIntegerOne -Recommended.JsonInput.BoolFieldIntegerZero -Recommended.JsonInput.BoolMapFieldKeyNotQuoted Recommended.JsonInput.DoubleFieldInfinityNotQuoted Recommended.JsonInput.DoubleFieldNanNotQuoted Recommended.JsonInput.DoubleFieldNegativeInfinityNotQuoted -Recommended.JsonInput.DurationHas3FractionalDigits.Validator -Recommended.JsonInput.DurationHas6FractionalDigits.Validator -Recommended.JsonInput.DurationHas9FractionalDigits.Validator -Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator -Recommended.JsonInput.FieldMaskInvalidCharacter -Recommended.JsonInput.FieldNameDuplicate -Recommended.JsonInput.FieldNameDuplicateDifferentCasing1 -Recommended.JsonInput.FieldNameDuplicateDifferentCasing2 -Recommended.JsonInput.FieldNameNotQuoted -Recommended.JsonInput.FieldNameWithDoubleUnderscores.JsonOutput -Recommended.JsonInput.FieldNameWithDoubleUnderscores.ProtobufOutput -Recommended.JsonInput.FieldNameWithDoubleUnderscores.Validator Recommended.JsonInput.FloatFieldInfinityNotQuoted Recommended.JsonInput.FloatFieldNanNotQuoted Recommended.JsonInput.FloatFieldNegativeInfinityNotQuoted -Recommended.JsonInput.Int32MapFieldKeyNotQuoted -Recommended.JsonInput.Int64FieldBeString.Validator -Recommended.JsonInput.Int64MapFieldKeyNotQuoted -Recommended.JsonInput.JsonWithComments -Recommended.JsonInput.MapFieldKeyIsNull -Recommended.JsonInput.MapFieldValueIsNull -Recommended.JsonInput.MissingCommaMultiline -Recommended.JsonInput.MissingCommaOneLine -Recommended.JsonInput.MultilineNoSpaces.JsonOutput -Recommended.JsonInput.MultilineNoSpaces.ProtobufOutput -Recommended.JsonInput.MultilineWithSpaces.JsonOutput -Recommended.JsonInput.MultilineWithSpaces.ProtobufOutput -Recommended.JsonInput.OneLineNoSpaces.JsonOutput -Recommended.JsonInput.OneLineNoSpaces.ProtobufOutput -Recommended.JsonInput.OneLineWithSpaces.JsonOutput -Recommended.JsonInput.OneLineWithSpaces.ProtobufOutput -Recommended.JsonInput.OneofZeroBool.JsonOutput -Recommended.JsonInput.OneofZeroBool.ProtobufOutput -Recommended.JsonInput.OneofZeroBytes.JsonOutput -Recommended.JsonInput.OneofZeroBytes.ProtobufOutput -Recommended.JsonInput.OneofZeroDouble.JsonOutput -Recommended.JsonInput.OneofZeroDouble.ProtobufOutput -Recommended.JsonInput.OneofZeroEnum.JsonOutput -Recommended.JsonInput.OneofZeroEnum.ProtobufOutput -Recommended.JsonInput.OneofZeroFloat.JsonOutput -Recommended.JsonInput.OneofZeroFloat.ProtobufOutput -Recommended.JsonInput.OneofZeroMessage.JsonOutput -Recommended.JsonInput.OneofZeroMessage.ProtobufOutput -Recommended.JsonInput.OneofZeroString.JsonOutput -Recommended.JsonInput.OneofZeroString.ProtobufOutput -Recommended.JsonInput.OneofZeroUint32.JsonOutput -Recommended.JsonInput.OneofZeroUint32.ProtobufOutput -Recommended.JsonInput.OneofZeroUint64.JsonOutput -Recommended.JsonInput.OneofZeroUint64.ProtobufOutput -Recommended.JsonInput.RepeatedFieldMessageElementIsNull -Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull -Recommended.JsonInput.RepeatedFieldTrailingComma -Recommended.JsonInput.RepeatedFieldTrailingCommaWithNewlines -Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpace -Recommended.JsonInput.RepeatedFieldTrailingCommaWithSpaceCommaSpace -Recommended.JsonInput.StringEndsWithEscapeChar -Recommended.JsonInput.StringFieldInvalidEscape -Recommended.JsonInput.StringFieldSingleQuoteBoth -Recommended.JsonInput.StringFieldSingleQuoteKey -Recommended.JsonInput.StringFieldSingleQuoteValue -Recommended.JsonInput.StringFieldSurrogateInWrongOrder -Recommended.JsonInput.StringFieldUnpairedHighSurrogate -Recommended.JsonInput.StringFieldUnpairedLowSurrogate -Recommended.JsonInput.StringFieldUnterminatedEscape -Recommended.JsonInput.StringFieldUppercaseEscapeLetter -Recommended.JsonInput.TimestampHas3FractionalDigits.Validator -Recommended.JsonInput.TimestampHas6FractionalDigits.Validator -Recommended.JsonInput.TimestampHas9FractionalDigits.Validator -Recommended.JsonInput.TimestampHasZeroFractionalDigit.Validator -Recommended.JsonInput.TimestampZeroNormalized.Validator -Recommended.JsonInput.TrailingCommaInAnObject -Recommended.JsonInput.TrailingCommaInAnObjectWithNewlines -Recommended.JsonInput.TrailingCommaInAnObjectWithSpace -Recommended.JsonInput.TrailingCommaInAnObjectWithSpaceCommaSpace -Recommended.JsonInput.Uint32MapFieldKeyNotQuoted -Recommended.JsonInput.Uint64FieldBeString.Validator -Recommended.JsonInput.Uint64MapFieldKeyNotQuoted -Recommended.ProtobufInput.OneofZeroBool.JsonOutput -Recommended.ProtobufInput.OneofZeroBool.ProtobufOutput -Recommended.ProtobufInput.OneofZeroBytes.JsonOutput -Recommended.ProtobufInput.OneofZeroBytes.ProtobufOutput -Recommended.ProtobufInput.OneofZeroDouble.JsonOutput -Recommended.ProtobufInput.OneofZeroDouble.ProtobufOutput -Recommended.ProtobufInput.OneofZeroEnum.JsonOutput -Recommended.ProtobufInput.OneofZeroEnum.ProtobufOutput -Recommended.ProtobufInput.OneofZeroFloat.JsonOutput -Recommended.ProtobufInput.OneofZeroFloat.ProtobufOutput -Recommended.ProtobufInput.OneofZeroMessage.JsonOutput -Recommended.ProtobufInput.OneofZeroMessage.ProtobufOutput -Recommended.ProtobufInput.OneofZeroString.JsonOutput -Recommended.ProtobufInput.OneofZeroString.ProtobufOutput -Recommended.ProtobufInput.OneofZeroUint32.JsonOutput -Recommended.ProtobufInput.OneofZeroUint32.ProtobufOutput -Recommended.ProtobufInput.OneofZeroUint64.JsonOutput -Recommended.ProtobufInput.OneofZeroUint64.ProtobufOutput -Required.DurationProtoInputTooLarge.JsonOutput -Required.DurationProtoInputTooSmall.JsonOutput -Required.JsonInput.AllFieldAcceptNull.JsonOutput -Required.JsonInput.AllFieldAcceptNull.ProtobufOutput -Required.JsonInput.Any.JsonOutput -Required.JsonInput.Any.ProtobufOutput -Required.JsonInput.AnyNested.JsonOutput -Required.JsonInput.AnyNested.ProtobufOutput -Required.JsonInput.AnyUnorderedTypeTag.JsonOutput -Required.JsonInput.AnyUnorderedTypeTag.ProtobufOutput -Required.JsonInput.AnyWithDuration.JsonOutput -Required.JsonInput.AnyWithDuration.ProtobufOutput -Required.JsonInput.AnyWithFieldMask.JsonOutput -Required.JsonInput.AnyWithFieldMask.ProtobufOutput -Required.JsonInput.AnyWithInt32ValueWrapper.JsonOutput -Required.JsonInput.AnyWithInt32ValueWrapper.ProtobufOutput -Required.JsonInput.AnyWithStruct.JsonOutput -Required.JsonInput.AnyWithStruct.ProtobufOutput -Required.JsonInput.AnyWithTimestamp.JsonOutput -Required.JsonInput.AnyWithTimestamp.ProtobufOutput -Required.JsonInput.AnyWithValueForInteger.JsonOutput -Required.JsonInput.AnyWithValueForInteger.ProtobufOutput -Required.JsonInput.AnyWithValueForJsonObject.JsonOutput -Required.JsonInput.AnyWithValueForJsonObject.ProtobufOutput -Required.JsonInput.BoolFieldFalse.JsonOutput -Required.JsonInput.BoolFieldFalse.ProtobufOutput -Required.JsonInput.BoolFieldTrue.JsonOutput -Required.JsonInput.BoolFieldTrue.ProtobufOutput -Required.JsonInput.BoolMapEscapedKey.JsonOutput -Required.JsonInput.BoolMapEscapedKey.ProtobufOutput -Required.JsonInput.BoolMapField.JsonOutput -Required.JsonInput.BoolMapField.ProtobufOutput -Required.JsonInput.BytesField.JsonOutput -Required.JsonInput.BytesField.ProtobufOutput Required.JsonInput.BytesFieldInvalidBase64Characters -Required.JsonInput.BytesRepeatedField.JsonOutput -Required.JsonInput.BytesRepeatedField.ProtobufOutput -Required.JsonInput.DoubleFieldInfinity.JsonOutput -Required.JsonInput.DoubleFieldInfinity.ProtobufOutput -Required.JsonInput.DoubleFieldMaxNegativeValue.JsonOutput -Required.JsonInput.DoubleFieldMaxNegativeValue.ProtobufOutput -Required.JsonInput.DoubleFieldMaxPositiveValue.JsonOutput -Required.JsonInput.DoubleFieldMaxPositiveValue.ProtobufOutput -Required.JsonInput.DoubleFieldMinNegativeValue.JsonOutput -Required.JsonInput.DoubleFieldMinNegativeValue.ProtobufOutput -Required.JsonInput.DoubleFieldMinPositiveValue.JsonOutput -Required.JsonInput.DoubleFieldMinPositiveValue.ProtobufOutput -Required.JsonInput.DoubleFieldNan.JsonOutput -Required.JsonInput.DoubleFieldNan.ProtobufOutput -Required.JsonInput.DoubleFieldNegativeInfinity.JsonOutput -Required.JsonInput.DoubleFieldNegativeInfinity.ProtobufOutput -Required.JsonInput.DoubleFieldQuotedValue.JsonOutput -Required.JsonInput.DoubleFieldQuotedValue.ProtobufOutput -Required.JsonInput.DoubleFieldTooLarge Required.JsonInput.DoubleFieldTooSmall -Required.JsonInput.DurationJsonInputTooLarge -Required.JsonInput.DurationJsonInputTooSmall -Required.JsonInput.DurationMaxValue.JsonOutput -Required.JsonInput.DurationMaxValue.ProtobufOutput -Required.JsonInput.DurationMinValue.JsonOutput -Required.JsonInput.DurationMinValue.ProtobufOutput -Required.JsonInput.DurationMissingS -Required.JsonInput.DurationRepeatedValue.JsonOutput -Required.JsonInput.DurationRepeatedValue.ProtobufOutput -Required.JsonInput.EnumField.JsonOutput -Required.JsonInput.EnumField.ProtobufOutput -Required.JsonInput.EnumFieldNotQuoted -Required.JsonInput.EnumFieldNumericValueNonZero.JsonOutput -Required.JsonInput.EnumFieldNumericValueNonZero.ProtobufOutput -Required.JsonInput.EnumFieldNumericValueZero.JsonOutput -Required.JsonInput.EnumFieldNumericValueZero.ProtobufOutput Required.JsonInput.EnumFieldUnknownValue.Validator -Required.JsonInput.EnumRepeatedField.JsonOutput -Required.JsonInput.EnumRepeatedField.ProtobufOutput -Required.JsonInput.FieldMask.JsonOutput -Required.JsonInput.FieldMask.ProtobufOutput -Required.JsonInput.FieldNameEscaped.JsonOutput -Required.JsonInput.FieldNameEscaped.ProtobufOutput -Required.JsonInput.FieldNameInLowerCamelCase.Validator -Required.JsonInput.FieldNameInSnakeCase.JsonOutput -Required.JsonInput.FieldNameInSnakeCase.ProtobufOutput -Required.JsonInput.FieldNameWithMixedCases.JsonOutput -Required.JsonInput.FieldNameWithMixedCases.ProtobufOutput -Required.JsonInput.FieldNameWithMixedCases.Validator -Required.JsonInput.FieldNameWithNumbers.JsonOutput -Required.JsonInput.FieldNameWithNumbers.ProtobufOutput -Required.JsonInput.FieldNameWithNumbers.Validator -Required.JsonInput.FloatFieldInfinity.JsonOutput -Required.JsonInput.FloatFieldInfinity.ProtobufOutput -Required.JsonInput.FloatFieldMaxNegativeValue.JsonOutput -Required.JsonInput.FloatFieldMaxNegativeValue.ProtobufOutput -Required.JsonInput.FloatFieldMaxPositiveValue.JsonOutput -Required.JsonInput.FloatFieldMaxPositiveValue.ProtobufOutput -Required.JsonInput.FloatFieldMinNegativeValue.JsonOutput -Required.JsonInput.FloatFieldMinNegativeValue.ProtobufOutput -Required.JsonInput.FloatFieldMinPositiveValue.JsonOutput -Required.JsonInput.FloatFieldMinPositiveValue.ProtobufOutput -Required.JsonInput.FloatFieldNan.JsonOutput -Required.JsonInput.FloatFieldNan.ProtobufOutput -Required.JsonInput.FloatFieldNegativeInfinity.JsonOutput -Required.JsonInput.FloatFieldNegativeInfinity.ProtobufOutput -Required.JsonInput.FloatFieldQuotedValue.JsonOutput -Required.JsonInput.FloatFieldQuotedValue.ProtobufOutput Required.JsonInput.FloatFieldTooLarge Required.JsonInput.FloatFieldTooSmall -Required.JsonInput.HelloWorld.JsonOutput -Required.JsonInput.HelloWorld.ProtobufOutput -Required.JsonInput.Int32FieldExponentialFormat.JsonOutput -Required.JsonInput.Int32FieldExponentialFormat.ProtobufOutput -Required.JsonInput.Int32FieldFloatTrailingZero.JsonOutput -Required.JsonInput.Int32FieldFloatTrailingZero.ProtobufOutput -Required.JsonInput.Int32FieldLeadingSpace -Required.JsonInput.Int32FieldLeadingZero -Required.JsonInput.Int32FieldMaxFloatValue.JsonOutput -Required.JsonInput.Int32FieldMaxFloatValue.ProtobufOutput -Required.JsonInput.Int32FieldMaxValue.JsonOutput -Required.JsonInput.Int32FieldMaxValue.ProtobufOutput -Required.JsonInput.Int32FieldMinFloatValue.JsonOutput -Required.JsonInput.Int32FieldMinFloatValue.ProtobufOutput -Required.JsonInput.Int32FieldMinValue.JsonOutput -Required.JsonInput.Int32FieldMinValue.ProtobufOutput -Required.JsonInput.Int32FieldNegativeWithLeadingZero -Required.JsonInput.Int32FieldNotInteger -Required.JsonInput.Int32FieldNotNumber -Required.JsonInput.Int32FieldPlusSign -Required.JsonInput.Int32FieldStringValue.JsonOutput -Required.JsonInput.Int32FieldStringValue.ProtobufOutput -Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput -Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput -Required.JsonInput.Int32FieldTooLarge -Required.JsonInput.Int32FieldTooSmall -Required.JsonInput.Int32FieldTrailingSpace -Required.JsonInput.Int32MapEscapedKey.JsonOutput -Required.JsonInput.Int32MapEscapedKey.ProtobufOutput -Required.JsonInput.Int32MapField.JsonOutput -Required.JsonInput.Int32MapField.ProtobufOutput -Required.JsonInput.Int64FieldMaxValue.JsonOutput -Required.JsonInput.Int64FieldMaxValue.ProtobufOutput -Required.JsonInput.Int64FieldMaxValueNotQuoted.JsonOutput -Required.JsonInput.Int64FieldMaxValueNotQuoted.ProtobufOutput -Required.JsonInput.Int64FieldMinValue.JsonOutput -Required.JsonInput.Int64FieldMinValue.ProtobufOutput -Required.JsonInput.Int64FieldMinValueNotQuoted.JsonOutput -Required.JsonInput.Int64FieldMinValueNotQuoted.ProtobufOutput -Required.JsonInput.Int64FieldNotInteger -Required.JsonInput.Int64FieldNotNumber -Required.JsonInput.Int64FieldTooLarge -Required.JsonInput.Int64FieldTooSmall -Required.JsonInput.Int64MapEscapedKey.JsonOutput -Required.JsonInput.Int64MapEscapedKey.ProtobufOutput -Required.JsonInput.Int64MapField.JsonOutput -Required.JsonInput.Int64MapField.ProtobufOutput -Required.JsonInput.MessageField.JsonOutput -Required.JsonInput.MessageField.ProtobufOutput -Required.JsonInput.MessageMapField.JsonOutput -Required.JsonInput.MessageMapField.ProtobufOutput -Required.JsonInput.MessageRepeatedField.JsonOutput -Required.JsonInput.MessageRepeatedField.ProtobufOutput -Required.JsonInput.OneofFieldDuplicate -Required.JsonInput.OptionalBoolWrapper.JsonOutput -Required.JsonInput.OptionalBoolWrapper.ProtobufOutput -Required.JsonInput.OptionalBytesWrapper.JsonOutput -Required.JsonInput.OptionalBytesWrapper.ProtobufOutput -Required.JsonInput.OptionalDoubleWrapper.JsonOutput -Required.JsonInput.OptionalDoubleWrapper.ProtobufOutput -Required.JsonInput.OptionalFloatWrapper.JsonOutput -Required.JsonInput.OptionalFloatWrapper.ProtobufOutput -Required.JsonInput.OptionalInt32Wrapper.JsonOutput -Required.JsonInput.OptionalInt32Wrapper.ProtobufOutput -Required.JsonInput.OptionalInt64Wrapper.JsonOutput -Required.JsonInput.OptionalInt64Wrapper.ProtobufOutput -Required.JsonInput.OptionalStringWrapper.JsonOutput -Required.JsonInput.OptionalStringWrapper.ProtobufOutput -Required.JsonInput.OptionalUint32Wrapper.JsonOutput -Required.JsonInput.OptionalUint32Wrapper.ProtobufOutput -Required.JsonInput.OptionalUint64Wrapper.JsonOutput -Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput -Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput -Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput -Required.JsonInput.OriginalProtoFieldName.JsonOutput -Required.JsonInput.OriginalProtoFieldName.ProtobufOutput -Required.JsonInput.PrimitiveRepeatedField.JsonOutput -Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput -Required.JsonInput.RepeatedBoolWrapper.JsonOutput -Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput -Required.JsonInput.RepeatedBytesWrapper.JsonOutput -Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput -Required.JsonInput.RepeatedDoubleWrapper.JsonOutput -Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotMessage -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingIntegersGotString -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotString -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotBool -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt -Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotMessage -Required.JsonInput.RepeatedFloatWrapper.JsonOutput -Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput -Required.JsonInput.RepeatedInt32Wrapper.JsonOutput -Required.JsonInput.RepeatedInt32Wrapper.ProtobufOutput -Required.JsonInput.RepeatedInt64Wrapper.JsonOutput -Required.JsonInput.RepeatedInt64Wrapper.ProtobufOutput -Required.JsonInput.RepeatedStringWrapper.JsonOutput -Required.JsonInput.RepeatedStringWrapper.ProtobufOutput -Required.JsonInput.RepeatedUint32Wrapper.JsonOutput -Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput -Required.JsonInput.RepeatedUint64Wrapper.JsonOutput -Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput -Required.JsonInput.StringField.JsonOutput -Required.JsonInput.StringField.ProtobufOutput -Required.JsonInput.StringFieldEscape.JsonOutput -Required.JsonInput.StringFieldEscape.ProtobufOutput -Required.JsonInput.StringFieldNotAString -Required.JsonInput.StringFieldSurrogatePair.JsonOutput -Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput -Required.JsonInput.StringFieldUnicode.JsonOutput -Required.JsonInput.StringFieldUnicode.ProtobufOutput -Required.JsonInput.StringFieldUnicodeEscape.JsonOutput -Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput -Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput -Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput -Required.JsonInput.StringRepeatedField.JsonOutput -Required.JsonInput.StringRepeatedField.ProtobufOutput -Required.JsonInput.Struct.JsonOutput -Required.JsonInput.Struct.ProtobufOutput Required.JsonInput.TimestampJsonInputLowercaseT -Required.JsonInput.TimestampJsonInputLowercaseZ -Required.JsonInput.TimestampJsonInputMissingT -Required.JsonInput.TimestampJsonInputMissingZ -Required.JsonInput.TimestampJsonInputTooLarge -Required.JsonInput.TimestampJsonInputTooSmall -Required.JsonInput.TimestampMaxValue.JsonOutput -Required.JsonInput.TimestampMaxValue.ProtobufOutput -Required.JsonInput.TimestampMinValue.JsonOutput -Required.JsonInput.TimestampMinValue.ProtobufOutput -Required.JsonInput.TimestampRepeatedValue.JsonOutput -Required.JsonInput.TimestampRepeatedValue.ProtobufOutput -Required.JsonInput.TimestampWithNegativeOffset.JsonOutput -Required.JsonInput.TimestampWithNegativeOffset.ProtobufOutput -Required.JsonInput.TimestampWithPositiveOffset.JsonOutput -Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput -Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput -Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -Required.JsonInput.Uint32FieldMaxValue.JsonOutput -Required.JsonInput.Uint32FieldMaxValue.ProtobufOutput -Required.JsonInput.Uint32FieldNotInteger -Required.JsonInput.Uint32FieldNotNumber -Required.JsonInput.Uint32FieldTooLarge -Required.JsonInput.Uint32MapField.JsonOutput -Required.JsonInput.Uint32MapField.ProtobufOutput -Required.JsonInput.Uint64FieldMaxValue.JsonOutput -Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput -Required.JsonInput.Uint64FieldMaxValueNotQuoted.JsonOutput -Required.JsonInput.Uint64FieldMaxValueNotQuoted.ProtobufOutput -Required.JsonInput.Uint64FieldNotInteger -Required.JsonInput.Uint64FieldNotNumber -Required.JsonInput.Uint64FieldTooLarge -Required.JsonInput.Uint64MapField.JsonOutput -Required.JsonInput.Uint64MapField.ProtobufOutput -Required.JsonInput.ValueAcceptBool.JsonOutput -Required.JsonInput.ValueAcceptBool.ProtobufOutput -Required.JsonInput.ValueAcceptFloat.JsonOutput -Required.JsonInput.ValueAcceptFloat.ProtobufOutput -Required.JsonInput.ValueAcceptInteger.JsonOutput -Required.JsonInput.ValueAcceptInteger.ProtobufOutput -Required.JsonInput.ValueAcceptList.JsonOutput -Required.JsonInput.ValueAcceptList.ProtobufOutput -Required.JsonInput.ValueAcceptNull.JsonOutput -Required.JsonInput.ValueAcceptNull.ProtobufOutput -Required.JsonInput.ValueAcceptObject.JsonOutput -Required.JsonInput.ValueAcceptObject.ProtobufOutput -Required.JsonInput.ValueAcceptString.JsonOutput -Required.JsonInput.ValueAcceptString.ProtobufOutput -Required.JsonInput.WrapperTypesWithNullValue.JsonOutput -Required.JsonInput.WrapperTypesWithNullValue.ProtobufOutput -Required.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput -Required.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput -Required.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput -Required.ProtobufInput.FloatFieldNormalizeSignalingNan.JsonOutput -Required.ProtobufInput.IllegalZeroFieldNum_Case_0 -Required.ProtobufInput.IllegalZeroFieldNum_Case_1 -Required.ProtobufInput.IllegalZeroFieldNum_Case_2 -Required.ProtobufInput.IllegalZeroFieldNum_Case_3 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeKnownNonRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeKnownRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.BOOL -Required.ProtobufInput.PrematureEofBeforeUnknownValue.BYTES -Required.ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE -Required.ProtobufInput.PrematureEofBeforeUnknownValue.ENUM -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT -Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.INT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.SINT64 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.STRING -Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT32 -Required.ProtobufInput.PrematureEofBeforeUnknownValue.UINT64 -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.BYTES Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.BYTES Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING Required.ProtobufInput.PrematureEofInPackedField.BOOL Required.ProtobufInput.PrematureEofInPackedField.DOUBLE Required.ProtobufInput.PrematureEofInPackedField.ENUM @@ -476,149 +36,3 @@ Required.ProtobufInput.PrematureEofInPackedField.SINT32 Required.ProtobufInput.PrematureEofInPackedField.SINT64 Required.ProtobufInput.PrematureEofInPackedField.UINT32 Required.ProtobufInput.PrematureEofInPackedField.UINT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.BOOL -Required.ProtobufInput.PrematureEofInPackedFieldValue.DOUBLE -Required.ProtobufInput.PrematureEofInPackedFieldValue.ENUM -Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.FIXED64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.FLOAT -Required.ProtobufInput.PrematureEofInPackedFieldValue.INT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.INT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SFIXED64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.SINT64 -Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT32 -Required.ProtobufInput.PrematureEofInPackedFieldValue.UINT64 -Required.ProtobufInput.PrematureEofInSubmessageValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofInsideKnownNonRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BOOL -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.BYTES -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.ENUM -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.FLOAT -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.INT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.SINT64 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.STRING -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT32 -Required.ProtobufInput.PrematureEofInsideKnownRepeatedValue.UINT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.BOOL -Required.ProtobufInput.PrematureEofInsideUnknownValue.BYTES -Required.ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE -Required.ProtobufInput.PrematureEofInsideUnknownValue.ENUM -Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.FIXED64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.FLOAT -Required.ProtobufInput.PrematureEofInsideUnknownValue.INT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.INT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.MESSAGE -Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.SINT64 -Required.ProtobufInput.PrematureEofInsideUnknownValue.STRING -Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT32 -Required.ProtobufInput.PrematureEofInsideUnknownValue.UINT64 -Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.BOOL.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.DOUBLE.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FIXED64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.FLOAT.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.INT64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SFIXED64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.SINT64.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT32.ProtobufOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.JsonOutput -Required.ProtobufInput.RepeatedScalarSelectsLast.UINT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.BOOL.JsonOutput -Required.ProtobufInput.ValidDataRepeated.BOOL.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.DOUBLE.JsonOutput -Required.ProtobufInput.ValidDataRepeated.DOUBLE.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FIXED32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FIXED64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.FLOAT.JsonOutput -Required.ProtobufInput.ValidDataRepeated.FLOAT.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.INT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.INT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SFIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SINT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SINT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.SINT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.SINT64.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.UINT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.UINT32.ProtobufOutput -Required.ProtobufInput.ValidDataRepeated.UINT64.JsonOutput -Required.ProtobufInput.ValidDataRepeated.UINT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.BOOL.JsonOutput -Required.ProtobufInput.ValidDataScalar.BOOL.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.DOUBLE.JsonOutput -Required.ProtobufInput.ValidDataScalar.DOUBLE.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FIXED32.JsonOutput -Required.ProtobufInput.ValidDataScalar.FIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FIXED64.JsonOutput -Required.ProtobufInput.ValidDataScalar.FIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.FLOAT.JsonOutput -Required.ProtobufInput.ValidDataScalar.FLOAT.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.INT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.INT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.INT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.INT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SFIXED32.JsonOutput -Required.ProtobufInput.ValidDataScalar.SFIXED32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SFIXED64.JsonOutput -Required.ProtobufInput.ValidDataScalar.SFIXED64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SINT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.SINT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.SINT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.SINT64.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.UINT32.JsonOutput -Required.ProtobufInput.ValidDataScalar.UINT32.ProtobufOutput -Required.ProtobufInput.ValidDataScalar.UINT64.JsonOutput -Required.ProtobufInput.ValidDataScalar.UINT64.ProtobufOutput -Required.TimestampProtoInputTooLarge.JsonOutput -Required.TimestampProtoInputTooSmall.JsonOutput -- cgit v1.2.3 From 057a2851e41e9a0ad95d2cd76aba8bc39ba2e6e3 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 29 Mar 2017 16:19:00 -0700 Subject: Update C# conformance failure list. --- conformance/failure_list_csharp.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conformance/failure_list_csharp.txt b/conformance/failure_list_csharp.txt index e69de29b..922db94c 100644 --- a/conformance/failure_list_csharp.txt +++ b/conformance/failure_list_csharp.txt @@ -0,0 +1,4 @@ +Required.ProtobufInput.IllegalZeroFieldNum_Case_0 +Required.ProtobufInput.IllegalZeroFieldNum_Case_1 +Required.ProtobufInput.IllegalZeroFieldNum_Case_2 +Required.ProtobufInput.IllegalZeroFieldNum_Case_3 -- cgit v1.2.3 From c52e54f62b824fbc9647ff68150926c7cd9b8aea Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 15:57:18 -0700 Subject: Update jenkins Java maven dependencies. --- jenkins/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index 659336d8..ea0c283d 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -129,7 +129,7 @@ ENV MVN mvn --batch-mode RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ + git reset 057a2851e41e9a0ad95d2cd76aba8bc39ba2e6e3 && \ ./autogen.sh && \ ./configure && \ make -j4 && \ -- cgit v1.2.3 From fab8812cc1bb9db0683e7d0b0182a63ee1159874 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 16:05:25 -0700 Subject: Update python conformance failure list. --- conformance/failure_list_python.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/conformance/failure_list_python.txt b/conformance/failure_list_python.txt index 84a7dd75..965b8212 100644 --- a/conformance/failure_list_python.txt +++ b/conformance/failure_list_python.txt @@ -15,6 +15,3 @@ Required.ProtobufInput.IllegalZeroFieldNum_Case_0 Required.ProtobufInput.IllegalZeroFieldNum_Case_1 Required.ProtobufInput.IllegalZeroFieldNum_Case_2 Required.ProtobufInput.IllegalZeroFieldNum_Case_3 -Required.ProtobufInput.RepeatedScalarSelectsLast.INT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.INT32.JsonOutput -Required.ProtobufInput.ValidDataRepeated.INT32.ProtobufOutput -- cgit v1.2.3 From fe97d79abf610fdccfadcd4b503ab3bc0a162d30 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 23:54:39 +0000 Subject: Fix MSVC DLL build. --- src/google/protobuf/extension_set.h | 4 +--- src/google/protobuf/extension_set_heavy.cc | 4 ++++ src/google/protobuf/generated_message_reflection.h | 2 +- src/google/protobuf/generated_message_util.h | 2 +- src/google/protobuf/map_entry.h | 2 +- src/google/protobuf/map_entry_lite.h | 4 ++-- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h index cb8ed217..cf5f652d 100644 --- a/src/google/protobuf/extension_set.h +++ b/src/google/protobuf/extension_set.h @@ -438,9 +438,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet { // SpaceUsed()). size_t SpaceUsedExcludingSelfLong() const; - int SpaceUsedExcludingSelf() const { - return internal::FromIntSize(SpaceUsedExcludingSelfLong()); - } + int SpaceUsedExcludingSelf() const; private: diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc index 3649104f..f545fe30 100644 --- a/src/google/protobuf/extension_set_heavy.cc +++ b/src/google/protobuf/extension_set_heavy.cc @@ -340,6 +340,10 @@ bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input, } } +int ExtensionSet::SpaceUsedExcludingSelf() const { + return internal::FromIntSize(SpaceUsedExcludingSelfLong()); +} + size_t ExtensionSet::SpaceUsedExcludingSelfLong() const { size_t total_size = extensions_.size() * sizeof(ExtensionMap::value_type); diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index b4fdbb11..12b73ca3 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -255,7 +255,7 @@ struct MigrationSchema { // of whatever type the individual field would be. Strings and // Messages use RepeatedPtrFields while everything else uses // RepeatedFields. -class GeneratedMessageReflection PROTOBUF_FINAL : public Reflection { +class LIBPROTOBUF_EXPORT GeneratedMessageReflection PROTOBUF_FINAL : public Reflection { public: // Constructs a GeneratedMessageReflection. // Parameters: diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 903c4ee8..055304a1 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -177,7 +177,7 @@ LIBPROTOBUF_EXPORT inline const ::std::string& GetEmptyString() { return GetEmptyStringAlreadyInited(); } -size_t StringSpaceUsedExcludingSelfLong(const string& str); +LIBPROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const string& str); // True if IsInitialized() is true for all elements of t. Type is expected diff --git a/src/google/protobuf/map_entry.h b/src/google/protobuf/map_entry.h index 0a7d9a97..7c675568 100644 --- a/src/google/protobuf/map_entry.h +++ b/src/google/protobuf/map_entry.h @@ -83,7 +83,7 @@ namespace internal { template -class LIBPROTOBUF_EXPORT MapEntry +class MapEntry : public MapEntryImpl { public: diff --git a/src/google/protobuf/map_entry_lite.h b/src/google/protobuf/map_entry_lite.h index cd67f6e0..c466cc7b 100644 --- a/src/google/protobuf/map_entry_lite.h +++ b/src/google/protobuf/map_entry_lite.h @@ -92,7 +92,7 @@ struct MoveHelper { // strings and similar template -class LIBPROTOBUF_EXPORT MapEntryImpl : public Base { +class MapEntryImpl : public Base { protected: // Provide utilities to parse/serialize key/value. Provide utilities to // manipulate internal stored type. @@ -537,7 +537,7 @@ class LIBPROTOBUF_EXPORT MapEntryImpl : public Base { template -class LIBPROTOBUF_EXPORT MapEntryLite +class MapEntryLite : public MapEntryImpl, MessageLite, Key, Value, kKeyFieldType, -- cgit v1.2.3 From d5827784cf9e129c4165ba031fdc1e1d3fe4de8e Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 17:43:45 -0700 Subject: Fix C++ distcheck. --- src/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index 34abfcab..445474a0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -116,6 +116,7 @@ nobase_include_HEADERS = \ google/protobuf/generated_enum_reflection.h \ google/protobuf/generated_enum_util.h \ google/protobuf/generated_message_reflection.h \ + google/protobuf/generated_message_table_driven.h \ google/protobuf/generated_message_util.h \ google/protobuf/has_bits.h \ google/protobuf/map_entry.h \ @@ -128,6 +129,7 @@ nobase_include_HEADERS = \ google/protobuf/message.h \ google/protobuf/message_lite.h \ google/protobuf/metadata.h \ + google/protobuf/metadata_lite.h \ google/protobuf/reflection.h \ google/protobuf/reflection_ops.h \ google/protobuf/repeated_field.h \ -- cgit v1.2.3 From 624d44f042ece176c4bd2bd2b2976a87f03958dc Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 17:45:14 -0700 Subject: Update objective-c conformance failure list. --- conformance/failure_list_objc.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conformance/failure_list_objc.txt b/conformance/failure_list_objc.txt index dd538c10..6e0da6cf 100644 --- a/conformance/failure_list_objc.txt +++ b/conformance/failure_list_objc.txt @@ -1,4 +1,6 @@ -# All tests currently passing. -# # JSON input or output tests are skipped (in conformance_objc.m) as mobile # platforms don't support JSON wire format to avoid code bloat. +Required.ProtobufInput.IllegalZeroFieldNum_Case_0 +Required.ProtobufInput.IllegalZeroFieldNum_Case_1 +Required.ProtobufInput.IllegalZeroFieldNum_Case_2 +Required.ProtobufInput.IllegalZeroFieldNum_Case_3 -- cgit v1.2.3 From c2b3b3e04e7a023efe06f2107705b45428847800 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 30 Mar 2017 18:25:11 -0700 Subject: Update Java version number and dependency. --- java/core/pom.xml | 2 +- java/pom.xml | 10 ++++++++-- java/util/pom.xml | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/java/core/pom.xml b/java/core/pom.xml index 79160f2e..9c4e1b93 100644 --- a/java/core/pom.xml +++ b/java/core/pom.xml @@ -6,7 +6,7 @@ com.google.protobuf protobuf-parent - 3.2.0 + 3.3.0 protobuf-java diff --git a/java/pom.xml b/java/pom.xml index f89e4422..81ffc48a 100644 --- a/java/pom.xml +++ b/java/pom.xml @@ -11,7 +11,7 @@ com.google.protobuf protobuf-parent - 3.2.0 + 3.3.0 pom Protocol Buffers [Parent] @@ -84,7 +84,13 @@ com.google.guava guava - 18.0 + 20.0 + + + com.google.truth + truth + test + 0.32 diff --git a/java/util/pom.xml b/java/util/pom.xml index ac771f6e..c72fa650 100644 --- a/java/util/pom.xml +++ b/java/util/pom.xml @@ -6,7 +6,7 @@ com.google.protobuf protobuf-parent - 3.2.0 + 3.3.0 protobuf-java-util -- cgit v1.2.3 From b7c813fb67706c683f14b808679c9657b29c5a6e Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Fri, 31 Mar 2017 11:13:28 -0700 Subject: Update jenkins Java dependencies. --- jenkins/docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index ea0c283d..d75d4cef 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -129,7 +129,7 @@ ENV MVN mvn --batch-mode RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset 057a2851e41e9a0ad95d2cd76aba8bc39ba2e6e3 && \ + git reset c2b3b3e04e7a023efe06f2107705b45428847800 && \ ./autogen.sh && \ ./configure && \ make -j4 && \ -- cgit v1.2.3 From 32ad5a3e0d1a38440945a759a0dcb6245ac836d8 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Fri, 31 Mar 2017 14:04:29 -0700 Subject: Use "git reset --hard" to actually reset the code. --- jenkins/docker/Dockerfile | 4 ++-- jenkins/docker32/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index d75d4cef..685c05d6 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -129,7 +129,7 @@ ENV MVN mvn --batch-mode RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset c2b3b3e04e7a023efe06f2107705b45428847800 && \ + git reset --hard c2b3b3e04e7a023efe06f2107705b45428847800 && \ ./autogen.sh && \ ./configure && \ make -j4 && \ @@ -157,7 +157,7 @@ RUN cd /tmp && \ rm -rf protobuf && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset 46ae90dc5e145b12fffa7e053a908a9f3e066286 && \ + git reset --hard 46ae90dc5e145b12fffa7e053a908a9f3e066286 && \ cd php && \ ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \ ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \ diff --git a/jenkins/docker32/Dockerfile b/jenkins/docker32/Dockerfile index 02e9df17..2d83735d 100644 --- a/jenkins/docker32/Dockerfile +++ b/jenkins/docker32/Dockerfile @@ -64,7 +64,7 @@ RUN php -r "unlink('composer-setup.php');" RUN cd /tmp && \ git clone https://github.com/google/protobuf.git && \ cd protobuf/php && \ - git reset 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ + git reset --hard 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ ln -sfn /usr/bin/php5.5 /usr/bin/php && \ ln -sfn /usr/bin/php-config5.5 /usr/bin/php-config && \ ln -sfn /usr/bin/phpize5.5 /usr/bin/phpize && \ -- cgit v1.2.3 From bd74319107523c427c886c9744e7a23242292a5e Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Fri, 31 Mar 2017 15:59:48 -0700 Subject: Update Java conformance failure list. --- conformance/failure_list_java.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/conformance/failure_list_java.txt b/conformance/failure_list_java.txt index a4f0f102..632940ef 100644 --- a/conformance/failure_list_java.txt +++ b/conformance/failure_list_java.txt @@ -32,7 +32,6 @@ Recommended.JsonInput.StringFieldSingleQuoteValue Recommended.JsonInput.StringFieldSurrogateInWrongOrder Recommended.JsonInput.StringFieldUnpairedHighSurrogate Recommended.JsonInput.StringFieldUnpairedLowSurrogate -Recommended.JsonInput.StringFieldUppercaseEscapeLetter Recommended.JsonInput.Uint32MapFieldKeyNotQuoted Recommended.JsonInput.Uint64MapFieldKeyNotQuoted Required.JsonInput.EnumFieldNotQuoted -- cgit v1.2.3 From 80f0c0ac40398858480fcc121b6771f40e5b02bb Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 5 Apr 2017 17:26:46 -0700 Subject: Update version number and changelog for 3.3.0 --- CHANGES.txt | 108 ++++++++++++++++++++++++++++++++ Protobuf.podspec | 2 +- configure.ac | 2 +- csharp/Google.Protobuf.Tools.nuspec | 2 +- csharp/src/Google.Protobuf/project.json | 2 +- js/package.json | 2 +- protoc-artifacts/pom.xml | 2 +- python/google/protobuf/__init__.py | 2 +- ruby/google-protobuf.gemspec | 2 +- src/Makefile.am | 6 +- src/google/protobuf/stubs/common.h | 10 +-- 11 files changed, 124 insertions(+), 16 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 11645836..ccc8ff94 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,111 @@ +2017-04-05 version 3.3.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) + Planned Future Changes + * There are some changes that are not included in this release but are + planned for the near future: + - Preserve unknown fields in proto3: please read this doc: + + https://docs.google.com/document/d/1KMRX-G91Aa-Y2FkEaHeeviLRRNblgIahbsk4wA14gRk/view + + for the timeline and follow up this github issue: + + https://github.com/google/protobuf/issues/272 + + for discussion. + - Make C++ implementation C++11 only: we plan to require C++11 to build + protobuf code starting from 3.4.0 or 3.5.0 release. Please join this + github issue: + + https://github.com/google/protobuf/issues/2780 + + to provide your feedback. + + C++ + * Fixed map fields serialization of DynamicMessage to correctly serialize + both key and value regardless of their presence. + * Parser now rejects field number 0 correctly. + * New API Message::SpaceUsedLong() that’s equivalent to + Message::SpaceUsed() but returns the value in size_t. + * JSON support + - New flag always_print_enums_as_ints in JsonPrintOptions. + - New flag preserve_proto_field_names in JsonPrintOptions. It will instruct + the JSON printer to use the original field name declared in the .proto + file instead of converting them to lowerCamelCase when printing JSON. + - JsonPrintOptions.always_print_primtive_fields now works for oneof message + fields. + - Fixed a bug that doesn’t allow different fields to set the same json_name + value. + - Fixed a performance bug that causes excessive memory copy when printing + large messages. + * Various performance optimizations. + + Java + * Map field setters eagerly validate inputs and throw NullPointerExceptions + as appropriate. + * Added ByteBuffer overloads to the generated parsing methods and the Parser + interface. + * proto3 enum's getNumber() method now throws on UNRECOGNIZED values. + * Output of JsonFormat is now locale independent. + + Python + * Added FindServiceByName() in the pure-Python DescriptorPool. This works only + for descriptors added with DescriptorPool.Add(). Generated descriptor_pool + does not support this yet. + * Added a descriptor_pool parameter for parsing Any in text_format.Parse(). + * descriptor_pool.FindFileContainingSymbol() now is able to find nested + extensions. + * Extending empty [] to repeated field now sets parent message presence. + + PHP + * Added file option php_class_prefix. The prefix will be prepended to all + generated classes defined in the file. + * When encoding, negative int32 values are sign-extended to int64. + * Repeated/Map field setter accepts a regular PHP array. Type checking is + done on the array elements. + * encode/decode are renamed to serializeToString/mergeFromString. + * Added mergeFrom, clear method on Message. + * Fixed a bug that oneof accessor didn’t return the field name that is + actually set. + * C extension now works with php7. + * This is the first GA release of PHP. We guarantee that old generated code + can always work with new runtime and new generated code. + + Objective-C + * Fixed help for GPBTimestamp for dates before the epoch that contain + fractional seconds. + * Added GPBMessageDropUnknownFieldsRecursively() to remove unknowns from a + message and any sub messages. + * Addressed a threading race in extension registration/lookup. + * Increased the max message parsing depth to 100 to match the other languages. + * Removed some use of dispatch_once in favor of atomic compare/set since it + needs to be heap based. + * Fixes for new Xcode 8.3 warnings. + + C# + * Fixed MapField.Values.CopyTo, which would throw an exception unnecessarily + if provided exactly the right size of array to copy to. + * Fixed enum JSON formatting when multiple names mapped to the same numeric + value. + * Added JSON formatting option to format enums as integers. + * Modified RepeatedField to implement IReadOnlyList. + * Introduced the start of custom option handling; it's not as pleasant as it + might be, but the information is at least present. We expect to extend code + generation to improve this in the future. + * Introduced ByteString.FromStream and ByteString.FromStreamAsync to + efficiently create a ByteString from a stream. + * Added whole-message deprecation, which decorates the class with [Obsolete]. + + Ruby + * Fixed Message#to_h for messages with map fields. + * Fixed memcpy() in binary gems to work for old glibc, without breaking the + build for non-glibc libc’s like musl. + + Javascript + * Added compatibility tests for version 3.0.0. + * Added conformance tests. + * Fixed serialization of extensions: we need to emit a value even if it is + falsy (like the number 0). + * Use closurebuilder.py in favor of calcdeps.py for compiling JavaScript. + 2017-01-23 version 3.2.0 (C++/Java/Python/PHP/Ruby/Objective-C/C#/JavaScript/Lite) General * Added protoc version number to protoc plugin protocol. It can be used by diff --git a/Protobuf.podspec b/Protobuf.podspec index 0db70650..649f3ae3 100644 --- a/Protobuf.podspec +++ b/Protobuf.podspec @@ -5,7 +5,7 @@ # dependent projects use the :git notation to refer to the library. Pod::Spec.new do |s| s.name = 'Protobuf' - s.version = '3.2.0' + s.version = '3.3.0' s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.' s.homepage = 'https://github.com/google/protobuf' s.license = '3-Clause BSD License' diff --git a/configure.ac b/configure.ac index 531e25fb..82b221e8 100644 --- a/configure.ac +++ b/configure.ac @@ -17,7 +17,7 @@ AC_PREREQ(2.59) # In the SVN trunk, the version should always be the next anticipated release # version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed # the size of one file name in the dist tarfile over the 99-char limit.) -AC_INIT([Protocol Buffers],[3.2.0],[protobuf@googlegroups.com],[protobuf]) +AC_INIT([Protocol Buffers],[3.3.0],[protobuf@googlegroups.com],[protobuf]) AM_MAINTAINER_MODE([enable]) diff --git a/csharp/Google.Protobuf.Tools.nuspec b/csharp/Google.Protobuf.Tools.nuspec index 0b9cbcf4..182309bf 100644 --- a/csharp/Google.Protobuf.Tools.nuspec +++ b/csharp/Google.Protobuf.Tools.nuspec @@ -5,7 +5,7 @@ Google Protocol Buffers tools Tools for Protocol Buffers - Google's data interchange format. See project site for more info. - 3.2.0 + 3.3.0 Google Inc. protobuf-packages https://github.com/google/protobuf/blob/master/LICENSE diff --git a/csharp/src/Google.Protobuf/project.json b/csharp/src/Google.Protobuf/project.json index 961e037e..f4376238 100644 --- a/csharp/src/Google.Protobuf/project.json +++ b/csharp/src/Google.Protobuf/project.json @@ -1,5 +1,5 @@ { - "version": "3.2.0", + "version": "3.3.0", "title": "Google Protocol Buffers", "description": "See project site for more info.", "authors": [ "Google Inc." ], diff --git a/js/package.json b/js/package.json index dd6373de..14f54b8b 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "google-protobuf", - "version": "3.2.0", + "version": "3.3.0", "description": "Protocol Buffers for JavaScript", "main": "google-protobuf.js", "files": [ diff --git a/protoc-artifacts/pom.xml b/protoc-artifacts/pom.xml index 28a25119..a06c9998 100644 --- a/protoc-artifacts/pom.xml +++ b/protoc-artifacts/pom.xml @@ -10,7 +10,7 @@ com.google.protobuf protoc - 3.2.0 + 3.3.0 pom Protobuf Compiler diff --git a/python/google/protobuf/__init__.py b/python/google/protobuf/__init__.py index 7fd9e5a4..0375d72d 100755 --- a/python/google/protobuf/__init__.py +++ b/python/google/protobuf/__init__.py @@ -30,7 +30,7 @@ # Copyright 2007 Google Inc. All Rights Reserved. -__version__ = '3.2.0' +__version__ = '3.3.0' if __name__ != '__main__': try: diff --git a/ruby/google-protobuf.gemspec b/ruby/google-protobuf.gemspec index 1e30ae4d..836b1dd2 100644 --- a/ruby/google-protobuf.gemspec +++ b/ruby/google-protobuf.gemspec @@ -1,6 +1,6 @@ Gem::Specification.new do |s| s.name = "google-protobuf" - s.version = "3.2.0.1" + s.version = "3.3.0" s.licenses = ["BSD-3-Clause"] s.summary = "Protocol Buffers" s.description = "Protocol Buffers are Google's data interchange format." diff --git a/src/Makefile.am b/src/Makefile.am index 445474a0..bfb875ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -184,7 +184,7 @@ nobase_include_HEADERS = \ lib_LTLIBRARIES = libprotobuf-lite.la libprotobuf.la libprotoc.la libprotobuf_lite_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_lite_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +libprotobuf_lite_la_LDFLAGS = -version-info 13:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotobuf_lite_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf-lite.map EXTRA_libprotobuf_lite_la_DEPENDENCIES = libprotobuf-lite.map @@ -229,7 +229,7 @@ libprotobuf_lite_la_SOURCES = \ google/protobuf/io/zero_copy_stream_impl_lite.cc libprotobuf_la_LIBADD = $(PTHREAD_LIBS) -libprotobuf_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +libprotobuf_la_LDFLAGS = -version-info 13:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotobuf_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotobuf.map EXTRA_libprotobuf_la_DEPENDENCIES = libprotobuf.map @@ -318,7 +318,7 @@ libprotobuf_la_SOURCES = \ nodist_libprotobuf_la_SOURCES = $(nodist_libprotobuf_lite_la_SOURCES) libprotoc_la_LIBADD = $(PTHREAD_LIBS) libprotobuf.la -libprotoc_la_LDFLAGS = -version-info 12:0:0 -export-dynamic -no-undefined +libprotoc_la_LDFLAGS = -version-info 13:0:0 -export-dynamic -no-undefined if HAVE_LD_VERSION_SCRIPT libprotoc_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libprotoc.map EXTRA_libprotoc_la_DEPENDENCIES = libprotoc.map diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index d2611498..35fdf96b 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -96,27 +96,27 @@ namespace internal { // The current version, represented as a single integer to make comparison // easier: major * 10^6 + minor * 10^3 + micro -#define GOOGLE_PROTOBUF_VERSION 3002000 +#define GOOGLE_PROTOBUF_VERSION 3003000 // A suffix string for alpha, beta or rc releases. Empty for stable releases. #define GOOGLE_PROTOBUF_VERSION_SUFFIX "" // The minimum library version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3002000 +#define GOOGLE_PROTOBUF_MIN_LIBRARY_VERSION 3003000 // The minimum header version which works with the current version of // the library. This constant should only be used by protoc's C++ code // generator. -static const int kMinHeaderVersionForLibrary = 3002000; +static const int kMinHeaderVersionForLibrary = 3003000; // The minimum protoc version which works with the current version of the // headers. -#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3002000 +#define GOOGLE_PROTOBUF_MIN_PROTOC_VERSION 3003000 // The minimum header version which works with the current version of // protoc. This constant should only be used in VerifyVersion(). -static const int kMinHeaderVersionForProtoc = 3002000; +static const int kMinHeaderVersionForProtoc = 3003000; // Verifies that the headers and libraries are compatible. Use the macro // below to call this. -- cgit v1.2.3 From 21b0b3ca36dbe0954adce38626e4d36c21135982 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Wed, 5 Apr 2017 17:45:21 -0700 Subject: Update generated code. --- src/google/protobuf/any.pb.h | 4 ++-- src/google/protobuf/api.pb.h | 4 ++-- src/google/protobuf/compiler/plugin.pb.h | 4 ++-- src/google/protobuf/compiler/profile.pb.h | 4 ++-- src/google/protobuf/descriptor.pb.h | 4 ++-- src/google/protobuf/duration.pb.h | 4 ++-- src/google/protobuf/empty.pb.h | 4 ++-- src/google/protobuf/field_mask.pb.h | 4 ++-- src/google/protobuf/source_context.pb.h | 4 ++-- src/google/protobuf/struct.pb.h | 4 ++-- src/google/protobuf/timestamp.pb.h | 4 ++-- src/google/protobuf/type.pb.h | 4 ++-- src/google/protobuf/wrappers.pb.h | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index e5051c79..bc05fb35 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 5ddd78e7..108c63a4 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index c9abc256..4f8befb6 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/compiler/profile.pb.h b/src/google/protobuf/compiler/profile.pb.h index c2ce5efc..d20b87ed 100644 --- a/src/google/protobuf/compiler/profile.pb.h +++ b/src/google/protobuf/compiler/profile.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index b8c97a6d..d1ed2b1f 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/duration.pb.h b/src/google/protobuf/duration.pb.h index 9de33fea..34873d97 100644 --- a/src/google/protobuf/duration.pb.h +++ b/src/google/protobuf/duration.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/empty.pb.h b/src/google/protobuf/empty.pb.h index 2c599554..f28dc19b 100644 --- a/src/google/protobuf/empty.pb.h +++ b/src/google/protobuf/empty.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/field_mask.pb.h b/src/google/protobuf/field_mask.pb.h index ca2cb25b..742c1cf9 100644 --- a/src/google/protobuf/field_mask.pb.h +++ b/src/google/protobuf/field_mask.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/source_context.pb.h b/src/google/protobuf/source_context.pb.h index 5eeef140..23cd7f3e 100644 --- a/src/google/protobuf/source_context.pb.h +++ b/src/google/protobuf/source_context.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/struct.pb.h b/src/google/protobuf/struct.pb.h index 816aa794..a37a5652 100644 --- a/src/google/protobuf/struct.pb.h +++ b/src/google/protobuf/struct.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/timestamp.pb.h b/src/google/protobuf/timestamp.pb.h index f7f669af..98478540 100644 --- a/src/google/protobuf/timestamp.pb.h +++ b/src/google/protobuf/timestamp.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/type.pb.h b/src/google/protobuf/type.pb.h index 56d77a42..c1cd4164 100644 --- a/src/google/protobuf/type.pb.h +++ b/src/google/protobuf/type.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. diff --git a/src/google/protobuf/wrappers.pb.h b/src/google/protobuf/wrappers.pb.h index 78631a19..4202541b 100644 --- a/src/google/protobuf/wrappers.pb.h +++ b/src/google/protobuf/wrappers.pb.h @@ -8,12 +8,12 @@ #include -#if GOOGLE_PROTOBUF_VERSION < 3002000 +#if GOOGLE_PROTOBUF_VERSION < 3003000 #error This file was generated by a newer version of protoc which is #error incompatible with your Protocol Buffer headers. Please update #error your headers. #endif -#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#if 3003000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION #error This file was generated by an older version of protoc which is #error incompatible with your Protocol Buffer headers. Please #error regenerate this file with a newer version of protoc. -- cgit v1.2.3 From ee9c7f17e953243943181bcbc84590118be6b3c6 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 6 Apr 2017 16:47:18 -0700 Subject: Cleanup reflection objects for map entry. --- src/google/protobuf/compiler/cpp/cpp_file.cc | 9 +++++++++ src/google/protobuf/struct.pb.cc | 1 + 2 files changed, 10 insertions(+) diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 83e68c12..e0542ae8 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -751,6 +751,15 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) { message_generators_[i]->GenerateShutdownCode(printer); } + if (HasDescriptorMethods(file_, options_)) { + for (int i = 0; i < message_generators_.size(); i++) { + if (!IsMapEntryMessage(message_generators_[i]->descriptor_)) continue; + printer->Print( + "delete file_level_metadata[$index$].reflection;\n", + "index", SimpleItoa(i)); + } + } + printer->Outdent(); printer->Print( "}\n\n"); diff --git a/src/google/protobuf/struct.pb.cc b/src/google/protobuf/struct.pb.cc index 825810b1..207e9efe 100644 --- a/src/google/protobuf/struct.pb.cc +++ b/src/google/protobuf/struct.pb.cc @@ -133,6 +133,7 @@ void TableStruct::Shutdown() { delete file_level_metadata[2].reflection; _ListValue_default_instance_.Shutdown(); delete file_level_metadata[3].reflection; + delete file_level_metadata[0].reflection; } void TableStruct::InitDefaultsImpl() { -- cgit v1.2.3 From bfeeb9851768bc16c4b13938f7340585993efcb3 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Sat, 8 Apr 2017 00:39:03 +0000 Subject: Add include for INT_MAX --- src/google/protobuf/generated_message_util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/google/protobuf/generated_message_util.h b/src/google/protobuf/generated_message_util.h index 055304a1..44174466 100644 --- a/src/google/protobuf/generated_message_util.h +++ b/src/google/protobuf/generated_message_util.h @@ -39,6 +39,7 @@ #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_UTIL_H__ #include +#include #include #include -- cgit v1.2.3 From 899460c9cb328e51b5da0ffe5d73e03c8f00dd15 Mon Sep 17 00:00:00 2001 From: Jie Luo Date: Mon, 10 Apr 2017 16:37:57 -0700 Subject: cherrypick descriptor_pool.FindFileContainingSymbol by extensions (#2962) * Use PyUnicode_AsEncodedString() instead of PyUnicode_AsEncodedObject() * Cherrypick the fix descriptor_pool.FindFileContainingSymbol by extensions. --- python/google/protobuf/descriptor_pool.py | 36 +++++++++++++++++++--- .../protobuf/internal/descriptor_pool_test.py | 9 ++++++ python/google/protobuf/pyext/message.cc | 2 +- .../protobuf/compiler/python/python_generator.cc | 6 ++-- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index 7844575f..7bd2506b 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -127,6 +127,9 @@ class DescriptorPool(object): self._service_descriptors = {} self._file_descriptors = {} self._toplevel_extensions = {} + # TODO(jieluo): Remove _file_desc_by_toplevel_extension when + # FieldDescriptor.file is added in code gen. + self._file_desc_by_toplevel_extension = {} # We store extensions in two two-level mappings: The first key is the # descriptor of the message being extended, the second key is the extension # full name or its tag number. @@ -170,7 +173,7 @@ class DescriptorPool(object): raise TypeError('Expected instance of descriptor.Descriptor.') self._descriptors[desc.full_name] = desc - self.AddFileDescriptor(desc.file) + self._AddFileDescriptor(desc.file) def AddEnumDescriptor(self, enum_desc): """Adds an EnumDescriptor to the pool. @@ -185,7 +188,7 @@ class DescriptorPool(object): raise TypeError('Expected instance of descriptor.EnumDescriptor.') self._enum_descriptors[enum_desc.full_name] = enum_desc - self.AddFileDescriptor(enum_desc.file) + self._AddFileDescriptor(enum_desc.file) def AddServiceDescriptor(self, service_desc): """Adds a ServiceDescriptor to the pool. @@ -251,6 +254,23 @@ class DescriptorPool(object): file_desc: A FileDescriptor. """ + self._AddFileDescriptor(file_desc) + # TODO(jieluo): This is a temporary solution for FieldDescriptor.file. + # Remove it when FieldDescriptor.file is added in code gen. + for extension in file_desc.extensions_by_name.itervalues(): + self._file_desc_by_toplevel_extension[ + extension.full_name] = file_desc + + def _AddFileDescriptor(self, file_desc): + """Adds a FileDescriptor to the pool, non-recursively. + + If the FileDescriptor contains messages or enums, the caller must explicitly + register them. + + Args: + file_desc: A FileDescriptor. + """ + if not isinstance(file_desc, descriptor.FileDescriptor): raise TypeError('Expected instance of descriptor.FileDescriptor.') self._file_descriptors[file_desc.name] = file_desc @@ -313,12 +333,18 @@ class DescriptorPool(object): except KeyError: pass + try: + return self._file_desc_by_toplevel_extension[symbol] + except KeyError: + pass + # Try nested extensions inside a message. message_name, _, extension_name = symbol.rpartition('.') try: - scope = self.FindMessageTypeByName(message_name) - assert scope.extensions_by_name[extension_name] - return scope.file + message = self.FindMessageTypeByName(message_name) + assert message.extensions_by_name[extension_name] + return message.file + except KeyError: raise KeyError('Cannot find a file containing %s' % symbol) diff --git a/python/google/protobuf/internal/descriptor_pool_test.py b/python/google/protobuf/internal/descriptor_pool_test.py index 2ba1d285..c1733a48 100644 --- a/python/google/protobuf/internal/descriptor_pool_test.py +++ b/python/google/protobuf/internal/descriptor_pool_test.py @@ -63,6 +63,9 @@ from google.protobuf import symbol_database class DescriptorPoolTest(unittest.TestCase): def setUp(self): + # TODO(jieluo): Should make the pool which is created by + # serialized_pb same with generated pool. + # TODO(jieluo): More test coverage for the generated pool. self.pool = descriptor_pool.DescriptorPool() self.factory_test1_fd = descriptor_pb2.FileDescriptorProto.FromString( factory_test1_pb2.DESCRIPTOR.serialized_pb) @@ -128,6 +131,12 @@ class DescriptorPoolTest(unittest.TestCase): self.assertEqual('google/protobuf/internal/factory_test2.proto', file_desc4.name) + # Tests the generated pool. + assert descriptor_pool.Default().FindFileContainingSymbol( + 'google.protobuf.python.internal.Factory2Message.one_more_field') + assert descriptor_pool.Default().FindFileContainingSymbol( + 'google.protobuf.python.internal.another_field') + def testFindFileContainingSymbolFailure(self): with self.assertRaises(KeyError): self.pool.FindFileContainingSymbol('Does not exist') diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index c810b788..85aaa46f 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -779,7 +779,7 @@ PyObject* CheckString(PyObject* arg, const FieldDescriptor* descriptor) { encoded_string = arg; // Already encoded. Py_INCREF(encoded_string); } else { - encoded_string = PyUnicode_AsEncodedObject(arg, "utf-8", NULL); + encoded_string = PyUnicode_AsEncodedString(arg, "utf-8", NULL); } } else { // In this case field type is "bytes". diff --git a/src/google/protobuf/compiler/python/python_generator.cc b/src/google/protobuf/compiler/python/python_generator.cc index f83f155a..21a7e158 100644 --- a/src/google/protobuf/compiler/python/python_generator.cc +++ b/src/google/protobuf/compiler/python/python_generator.cc @@ -445,8 +445,6 @@ void Generator::PrintFileDescriptor() const { printer_->Outdent(); printer_->Print(")\n"); - printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name", - kDescriptorKey); printer_->Print("\n"); } @@ -999,6 +997,10 @@ void Generator::FixForeignFieldsInDescriptors() const { for (int i = 0; i < file_->extension_count(); ++i) { AddExtensionToFileDescriptor(*file_->extension(i)); } + // TODO(jieluo): Move this register to PrintFileDescriptor() when + // FieldDescriptor.file is added in generated file. + printer_->Print("_sym_db.RegisterFileDescriptor($name$)\n", "name", + kDescriptorKey); printer_->Print("\n"); } -- cgit v1.2.3 From cad0258d1758a0ca9f1b9725103bcdbae26697e1 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Tue, 11 Apr 2017 16:08:16 -0700 Subject: Cherry-pick cl/151775298 --- src/google/protobuf/map_test.cc | 27 +++++++++++++++++++++++++++ src/google/protobuf/wire_format.cc | 31 +++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index 3fe44512..e10a4278 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -2811,6 +2811,33 @@ TEST(WireFormatForMapFieldTest, SerializeMap) { EXPECT_TRUE(dynamic_data == generated_data); } +TEST(WireFormatForMapFieldTest, SerializeMapDynamicMessage) { + DynamicMessageFactory factory; + google::protobuf::scoped_ptr dynamic_message; + dynamic_message.reset( + factory.GetPrototype(unittest::TestMap::descriptor())->New()); + MapReflectionTester reflection_tester( + unittest::TestMap::descriptor()); + reflection_tester.SetMapFieldsViaReflection(dynamic_message.get()); + reflection_tester.ExpectMapFieldsSetViaReflection(*dynamic_message); + + unittest::TestMap generated_message; + MapTestUtil::SetMapFields(&generated_message); + MapTestUtil::ExpectMapFieldsSet(generated_message); + + string generated_data; + string dynamic_data; + + // Serialize. + generated_message.SerializeToString(&generated_data); + dynamic_message->SerializeToString(&dynamic_data); + + // Because map serialization doesn't guarantee order, we just compare + // serialized size here. This is enough to tell dynamic message doesn't miss + // anything in serialization. + EXPECT_TRUE(dynamic_data.size() == generated_data.size()); +} + TEST(WireFormatForMapFieldTest, MapParseHelpers) { string data; diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index d3d21c09..7778ecd1 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -797,7 +797,16 @@ void WireFormat::SerializeWithCachedSizes( int expected_endpoint = output->ByteCount() + size; std::vector fields; - message_reflection->ListFields(message, &fields); + + // Fields of map entry should always be serialized. + if (descriptor->options().map_entry()) { + for (int i = 0; i < descriptor->field_count(); i++) { + fields.push_back(descriptor->field(i)); + } + } else { + message_reflection->ListFields(message, &fields); + } + for (int i = 0; i < fields.size(); i++) { SerializeFieldWithCachedSizes(fields[i], message, output); } @@ -834,6 +843,9 @@ void WireFormat::SerializeFieldWithCachedSizes( if (field->is_repeated()) { count = message_reflection->FieldSize(message, field); + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; } else if (message_reflection->HasField(message, field)) { count = 1; } @@ -984,7 +996,16 @@ size_t WireFormat::ByteSize(const Message& message) { size_t our_size = 0; std::vector fields; - message_reflection->ListFields(message, &fields); + + // Fields of map entry should always be serialized. + if (descriptor->options().map_entry()) { + for (int i = 0; i < descriptor->field_count(); i++) { + fields.push_back(descriptor->field(i)); + } + } else { + message_reflection->ListFields(message, &fields); + } + for (int i = 0; i < fields.size(); i++) { our_size += FieldByteSize(fields[i], message); } @@ -1015,6 +1036,9 @@ size_t WireFormat::FieldByteSize( size_t count = 0; if (field->is_repeated()) { count = FromIntSize(message_reflection->FieldSize(message, field)); + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; } else if (message_reflection->HasField(message, field)) { count = 1; } @@ -1044,6 +1068,9 @@ size_t WireFormat::FieldDataOnlyByteSize( if (field->is_repeated()) { count = internal::FromIntSize(message_reflection->FieldSize(message, field)); + } else if (field->containing_type()->options().map_entry()) { + // Map entry fields always need to be serialized. + count = 1; } else if (message_reflection->HasField(message, field)) { count = 1; } -- cgit v1.2.3 From 57772592738cf9ec1464fe2232f4db195875e95d Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Tue, 11 Apr 2017 16:08:48 -0700 Subject: Cherry-pick cl/152450543 --- src/google/protobuf/map_field.cc | 14 ++ src/google/protobuf/map_field.h | 2 + src/google/protobuf/map_test.cc | 128 +++++++++++++++- src/google/protobuf/map_test_util.cc | 16 ++ src/google/protobuf/map_test_util.h | 5 + src/google/protobuf/message.h | 11 ++ src/google/protobuf/reflection_ops.cc | 22 +++ src/google/protobuf/wire_format.cc | 276 +++++++++++++++++++++++++++++++++- 8 files changed, 472 insertions(+), 2 deletions(-) diff --git a/src/google/protobuf/map_field.cc b/src/google/protobuf/map_field.cc index 4cde0aaa..64dcc990 100644 --- a/src/google/protobuf/map_field.cc +++ b/src/google/protobuf/map_field.cc @@ -67,6 +67,13 @@ size_t MapFieldBase::SpaceUsedExcludingSelfNoLock() const { } } +bool MapFieldBase::IsMapValid() const { + // "Acquire" insures the operation after SyncRepeatedFieldWithMap won't get + // executed before state_ is checked. + Atomic32 state = google::protobuf::internal::Acquire_Load(&state_); + return state != STATE_MODIFIED_REPEATED; +} + void MapFieldBase::SetMapDirty() { state_ = STATE_MODIFIED_MAP; } void MapFieldBase::SetRepeatedDirty() { state_ = STATE_MODIFIED_REPEATED; } @@ -359,6 +366,13 @@ void DynamicMapField::SyncMapWithRepeatedFieldNoLock() const { GOOGLE_LOG(FATAL) << "Can't get here."; break; } + + // Remove existing map value with same key. + Map::iterator iter = map->find(map_key); + if (iter != map->end()) { + iter->second.DeleteData(); + } + MapValueRef& map_val = (*map)[map_key]; map_val.SetType(val_des->cpp_type()); switch (val_des->cpp_type()) { diff --git a/src/google/protobuf/map_field.h b/src/google/protobuf/map_field.h index 6d904076..9d5a328e 100644 --- a/src/google/protobuf/map_field.h +++ b/src/google/protobuf/map_field.h @@ -86,6 +86,8 @@ class LIBPROTOBUF_EXPORT MapFieldBase { virtual bool ContainsMapKey(const MapKey& map_key) const = 0; virtual bool InsertOrLookupMapValue( const MapKey& map_key, MapValueRef* val) = 0; + // Insures operations after won't get executed before calling this. + bool IsMapValid() const; virtual bool DeleteMapValue(const MapKey& map_key) = 0; virtual bool EqualIterator(const MapIterator& a, const MapIterator& b) const = 0; diff --git a/src/google/protobuf/map_test.cc b/src/google/protobuf/map_test.cc index e10a4278..a06b432a 100644 --- a/src/google/protobuf/map_test.cc +++ b/src/google/protobuf/map_test.cc @@ -975,6 +975,11 @@ static int Int(const string& value) { class MapFieldReflectionTest : public testing::Test { protected: typedef FieldDescriptor FD; + + int MapSize(const Reflection* reflection, const FieldDescriptor* field, + const Message& message) { + return reflection->MapSize(message, field); + } }; TEST_F(MapFieldReflectionTest, RegularFields) { @@ -1782,6 +1787,50 @@ TEST_F(MapFieldReflectionTest, RepeatedFieldRefMergeFromAndSwap) { // TODO(teboring): add test for duplicated key } +TEST_F(MapFieldReflectionTest, MapSizeWithDuplicatedKey) { + // Dynamic Message + { + DynamicMessageFactory factory; + google::protobuf::scoped_ptr message( + factory.GetPrototype(unittest::TestMap::descriptor())->New()); + const Reflection* reflection = message->GetReflection(); + const FieldDescriptor* field = + unittest::TestMap::descriptor()->FindFieldByName("map_int32_int32"); + + Message* entry1 = reflection->AddMessage(message.get(), field); + Message* entry2 = reflection->AddMessage(message.get(), field); + + const Reflection* entry_reflection = entry1->GetReflection(); + const FieldDescriptor* key_field = + entry1->GetDescriptor()->FindFieldByName("key"); + entry_reflection->SetInt32(entry1, key_field, 1); + entry_reflection->SetInt32(entry2, key_field, 1); + + EXPECT_EQ(2, reflection->FieldSize(*message, field)); + EXPECT_EQ(1, MapSize(reflection, field, *message)); + } + + // Generated Message + { + unittest::TestMap message; + const Reflection* reflection = message.GetReflection(); + const FieldDescriptor* field = + message.GetDescriptor()->FindFieldByName("map_int32_int32"); + + Message* entry1 = reflection->AddMessage(&message, field); + Message* entry2 = reflection->AddMessage(&message, field); + + const Reflection* entry_reflection = entry1->GetReflection(); + const FieldDescriptor* key_field = + entry1->GetDescriptor()->FindFieldByName("key"); + entry_reflection->SetInt32(entry1, key_field, 1); + entry_reflection->SetInt32(entry2, key_field, 1); + + EXPECT_EQ(2, reflection->FieldSize(message, field)); + EXPECT_EQ(1, MapSize(reflection, field, message)); + } +} + // Generated Message Test =========================================== TEST(GeneratedMapFieldTest, Accessors) { @@ -2689,6 +2738,69 @@ TEST_F(MapFieldInDynamicMessageTest, RecursiveMap) { ASSERT_TRUE(to->ParseFromString(data)); } +TEST_F(MapFieldInDynamicMessageTest, MapValueReferernceValidAfterSerialize) { + google::protobuf::scoped_ptr message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + reflection_tester.SetMapFieldsViaMapReflection(message.get()); + + // Get value reference before serialization, so that we know the value is from + // map. + MapKey map_key; + MapValueRef map_val; + map_key.SetInt32Value(0); + reflection_tester.GetMapValueViaMapReflection( + message.get(), "map_int32_foreign_message", map_key, &map_val); + Message* submsg = map_val.MutableMessageValue(); + + // In previous implementation, calling SerializeToString will cause syncing + // from map to repeated field, which will invalidate the submsg we previously + // got. + string data; + message->SerializeToString(&data); + + const Reflection* submsg_reflection = submsg->GetReflection(); + const Descriptor* submsg_desc = submsg->GetDescriptor(); + const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); + submsg_reflection->SetInt32(submsg, submsg_field, 128); + + message->SerializeToString(&data); + TestMap to; + to.ParseFromString(data); + EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); +} + +TEST_F(MapFieldInDynamicMessageTest, MapEntryReferernceValidAfterSerialize) { + google::protobuf::scoped_ptr message(map_prototype_->New()); + MapReflectionTester reflection_tester(map_descriptor_); + reflection_tester.SetMapFieldsViaReflection(message.get()); + + // Get map entry before serialization, so that we know the it is from + // repeated field. + Message* map_entry = reflection_tester.GetMapEntryViaReflection( + message.get(), "map_int32_foreign_message", 0); + const Reflection* map_entry_reflection = map_entry->GetReflection(); + const Descriptor* map_entry_desc = map_entry->GetDescriptor(); + const FieldDescriptor* value_field = map_entry_desc->FindFieldByName("value"); + Message* submsg = + map_entry_reflection->MutableMessage(map_entry, value_field); + + // In previous implementation, calling SerializeToString will cause syncing + // from repeated field to map, which will invalidate the map_entry we + // previously got. + string data; + message->SerializeToString(&data); + + const Reflection* submsg_reflection = submsg->GetReflection(); + const Descriptor* submsg_desc = submsg->GetDescriptor(); + const FieldDescriptor* submsg_field = submsg_desc->FindFieldByName("c"); + submsg_reflection->SetInt32(submsg, submsg_field, 128); + + message->SerializeToString(&data); + TestMap to; + to.ParseFromString(data); + EXPECT_EQ(128, to.map_int32_foreign_message().at(0).c()); +} + // ReflectionOps Test =============================================== TEST(ReflectionOpsForMapFieldTest, MapSanityCheck) { @@ -2751,6 +2863,20 @@ TEST(ReflectionOpsForMapFieldTest, MapDiscardUnknownFields) { GetUnknownFields(message).field_count()); } +TEST(ReflectionOpsForMapFieldTest, IsInitialized) { + unittest::TestRequiredMessageMap map_message; + + // Add an uninitialized message. + (*map_message.mutable_map_field())[0]; + EXPECT_FALSE(ReflectionOps::IsInitialized(map_message)); + + // Initialize uninitialized message + (*map_message.mutable_map_field())[0].set_a(0); + (*map_message.mutable_map_field())[0].set_b(0); + (*map_message.mutable_map_field())[0].set_c(0); + EXPECT_TRUE(ReflectionOps::IsInitialized(map_message)); +} + // Wire Format Test ================================================= TEST(WireFormatForMapFieldTest, ParseMap) { @@ -3089,7 +3215,7 @@ TEST(ArenaTest, ParsingAndSerializingNoHeapAllocation) { } // Use text format parsing and serializing to test reflection api. -TEST(ArenaTest, RelfectionInTextFormat) { +TEST(ArenaTest, ReflectionInTextFormat) { Arena arena; string data; diff --git a/src/google/protobuf/map_test_util.cc b/src/google/protobuf/map_test_util.cc index 3dd6aae5..4d3ad609 100644 --- a/src/google/protobuf/map_test_util.cc +++ b/src/google/protobuf/map_test_util.cc @@ -744,6 +744,22 @@ void MapReflectionTester::SetMapFieldsViaMapReflection( sub_foreign_message, foreign_c_, 1); } +void MapReflectionTester::GetMapValueViaMapReflection(Message* message, + const string& field_name, + const MapKey& map_key, + MapValueRef* map_val) { + const Reflection* reflection = message->GetReflection(); + EXPECT_FALSE(reflection->InsertOrLookupMapValue(message, F(field_name), + map_key, map_val)); +} + +Message* MapReflectionTester::GetMapEntryViaReflection(Message* message, + const string& field_name, + int index) { + const Reflection* reflection = message->GetReflection(); + return reflection->MutableRepeatedMessage(message, F(field_name), index); +} + void MapReflectionTester::ClearMapFieldsViaReflection( Message* message) { const Reflection* reflection = message->GetReflection(); diff --git a/src/google/protobuf/map_test_util.h b/src/google/protobuf/map_test_util.h index deaf0f4f..15c6c289 100644 --- a/src/google/protobuf/map_test_util.h +++ b/src/google/protobuf/map_test_util.h @@ -106,6 +106,11 @@ class MapReflectionTester { void ExpectClearViaReflection(const Message& message); void ExpectClearViaReflectionIterator(Message* message); void ExpectMapEntryClearViaReflection(Message* message); + void GetMapValueViaMapReflection(Message* message, + const string& field_name, + const MapKey& map_key, MapValueRef* map_val); + Message* GetMapEntryViaReflection(Message* message, const string& field_name, + int index); private: const FieldDescriptor* F(const string& name); diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 7d9bb8a9..68acb5b1 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -154,6 +154,13 @@ class MapReflectionFriend; // scalar_map_container.h } +namespace internal { +class ReflectionOps; // reflection_ops.h +class MapKeySorter; // wire_format.cc +class WireFormat; // wire_format.h +class MapFieldReflectionTest; // map_test.cc +} + template class RepeatedField; // repeated_field.h @@ -936,6 +943,10 @@ class LIBPROTOBUF_EXPORT Reflection { template friend class MutableRepeatedFieldRef; friend class ::google::protobuf::python::MapReflectionFriend; + friend class internal::MapFieldReflectionTest; + friend class internal::MapKeySorter; + friend class internal::WireFormat; + friend class internal::ReflectionOps; // Special version for specialized implementations of string. We can't call // MutableRawRepeatedField directly here because we don't have access to diff --git a/src/google/protobuf/reflection_ops.cc b/src/google/protobuf/reflection_ops.cc index bb9c7f8b..d1867311 100644 --- a/src/google/protobuf/reflection_ops.cc +++ b/src/google/protobuf/reflection_ops.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #include @@ -158,6 +159,27 @@ bool ReflectionOps::IsInitialized(const Message& message) { const FieldDescriptor* field = fields[i]; if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + if (field->is_map()) { + const FieldDescriptor* value_field = field->message_type()->field(1); + if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { + MapFieldBase* map_field = + reflection->MapData(const_cast(&message), field); + if (map_field->IsMapValid()) { + MapIterator iter(const_cast(&message), field); + MapIterator end(const_cast(&message), field); + for (map_field->MapBegin(&iter), map_field->MapEnd(&end); + iter != end; ++iter) { + if (!iter.GetValueRef().GetMessageValue().IsInitialized()) { + return false; + } + } + continue; + } + } else { + continue; + } + } + if (field->is_repeated()) { int size = reflection->FieldSize(message, field); diff --git a/src/google/protobuf/wire_format.cc b/src/google/protobuf/wire_format.cc index 7778ecd1..01704c94 100644 --- a/src/google/protobuf/wire_format.cc +++ b/src/google/protobuf/wire_format.cc @@ -54,9 +54,17 @@ namespace google { +const size_t kMapEntryTagByteSize = 2; + namespace protobuf { namespace internal { +// Forward declare static functions +static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, + const MapKey& value); +static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, + const MapValueRef& value); + // =================================================================== bool UnknownFieldSetFieldSkipper::SkipField( @@ -825,6 +833,129 @@ void WireFormat::SerializeWithCachedSizes( "during serialization?"; } +static void SerializeMapKeyWithCachedSizes(const FieldDescriptor* field, + const MapKey& value, + io::CodedOutputStream* output) { + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + GOOGLE_LOG(FATAL) << "Unsupported"; + break; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + WireFormatLite::Write##CamelFieldType(1, value.Get##CamelCppType##Value(), \ + output); \ + break; + CASE_TYPE(INT64, Int64, Int64) + CASE_TYPE(UINT64, UInt64, UInt64) + CASE_TYPE(INT32, Int32, Int32) + CASE_TYPE(FIXED64, Fixed64, UInt64) + CASE_TYPE(FIXED32, Fixed32, UInt32) + CASE_TYPE(BOOL, Bool, Bool) + CASE_TYPE(UINT32, UInt32, UInt32) + CASE_TYPE(SFIXED32, SFixed32, Int32) + CASE_TYPE(SFIXED64, SFixed64, Int64) + CASE_TYPE(SINT32, SInt32, Int32) + CASE_TYPE(SINT64, SInt64, Int64) + CASE_TYPE(STRING, String, String) +#undef CASE_TYPE + } +} + +static void SerializeMapValueRefWithCachedSizes(const FieldDescriptor* field, + const MapValueRef& value, + io::CodedOutputStream* output) { + switch (field->type()) { +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + WireFormatLite::Write##CamelFieldType(2, value.Get##CamelCppType##Value(), \ + output); \ + break; + CASE_TYPE(INT64, Int64, Int64) + CASE_TYPE(UINT64, UInt64, UInt64) + CASE_TYPE(INT32, Int32, Int32) + CASE_TYPE(FIXED64, Fixed64, UInt64) + CASE_TYPE(FIXED32, Fixed32, UInt32) + CASE_TYPE(BOOL, Bool, Bool) + CASE_TYPE(UINT32, UInt32, UInt32) + CASE_TYPE(SFIXED32, SFixed32, Int32) + CASE_TYPE(SFIXED64, SFixed64, Int64) + CASE_TYPE(SINT32, SInt32, Int32) + CASE_TYPE(SINT64, SInt64, Int64) + CASE_TYPE(ENUM, Enum, Enum) + CASE_TYPE(DOUBLE, Double, Double) + CASE_TYPE(FLOAT, Float, Float) + CASE_TYPE(STRING, String, String) + CASE_TYPE(BYTES, Bytes, String) + CASE_TYPE(MESSAGE, Message, Message) + CASE_TYPE(GROUP, Group, Message) +#undef CASE_TYPE + } +} + +class MapKeySorter { + public: + static std::vector SortKey(const Message& message, + const Reflection* reflection, + const FieldDescriptor* field) { + std::vector sorted_key_list; + for (MapIterator it = + reflection->MapBegin(const_cast(&message), field); + it != reflection->MapEnd(const_cast(&message), field); + ++it) { + sorted_key_list.push_back(it.GetKey()); + } + MapKeyComparator comparator; + std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator); + return sorted_key_list; + } + + private: + class MapKeyComparator { + public: + bool operator()(const MapKey& a, const MapKey& b) const { + GOOGLE_DCHECK(a.type() == b.type()); + switch (a.type()) { +#define CASE_TYPE(CppType, CamelCppType) \ + case FieldDescriptor::CPPTYPE_##CppType: { \ + return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \ + } + CASE_TYPE(STRING, String) + CASE_TYPE(INT64, Int64) + CASE_TYPE(INT32, Int32) + CASE_TYPE(UINT64, UInt64) + CASE_TYPE(UINT32, UInt32) + CASE_TYPE(BOOL, Bool) +#undef CASE_TYPE + + default: + GOOGLE_LOG(DFATAL) << "Invalid key for map field."; + return true; + } + } + }; +}; + +static void SerializeMapEntry(const FieldDescriptor* field, const MapKey& key, + const MapValueRef& value, + io::CodedOutputStream* output) { + const FieldDescriptor* key_field = field->message_type()->field(0); + const FieldDescriptor* value_field = field->message_type()->field(1); + + WireFormatLite::WriteTag(field->number(), + WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output); + size_t size = kMapEntryTagByteSize; + size += MapKeyDataOnlyByteSize(key_field, key); + size += MapValueRefDataOnlyByteSize(value_field, value); + output->WriteVarint32(size); + SerializeMapKeyWithCachedSizes(key_field, key, output); + SerializeMapValueRefWithCachedSizes(value_field, value, output); +} + void WireFormat::SerializeFieldWithCachedSizes( const FieldDescriptor* field, const Message& message, @@ -839,6 +970,48 @@ void WireFormat::SerializeFieldWithCachedSizes( return; } + // For map fields, we can use either repeated field reflection or map + // reflection. Our choice has some subtle effects. If we use repeated field + // reflection here, then the repeated field representation becomes + // authoritative for this field: any existing references that came from map + // reflection remain valid for reading, but mutations to them are lost and + // will be overwritten next time we call map reflection! + // + // So far this mainly affects Python, which keeps long-term references to map + // values around, and always uses map reflection. See: b/35918691 + // + // Here we choose to use map reflection API as long as the internal + // map is valid. In this way, the serialization doesn't change map field's + // internal state and existing references that came from map reflection remain + // valid for both reading and writing. + if (field->is_map()) { + MapFieldBase* map_field = + message_reflection->MapData(const_cast(&message), field); + if (map_field->IsMapValid()) { + if (output->IsSerializationDeterministic()) { + std::vector sorted_key_list = + MapKeySorter::SortKey(message, message_reflection, field); + for (std::vector::iterator it = sorted_key_list.begin(); + it != sorted_key_list.end(); ++it) { + MapValueRef map_value; + message_reflection->InsertOrLookupMapValue( + const_cast(&message), field, *it, &map_value); + SerializeMapEntry(field, *it, map_value, output); + } + } else { + for (MapIterator it = message_reflection->MapBegin( + const_cast(&message), field); + it != + message_reflection->MapEnd(const_cast(&message), field); + ++it) { + SerializeMapEntry(field, it.GetKey(), it.GetValueRef(), output); + } + } + + return; + } + } + int count = 0; if (field->is_repeated()) { @@ -1059,11 +1232,113 @@ size_t WireFormat::FieldByteSize( return our_size; } +static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field, + const MapKey& value) { + GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type()); + switch (field->type()) { + case FieldDescriptor::TYPE_DOUBLE: + case FieldDescriptor::TYPE_FLOAT: + case FieldDescriptor::TYPE_GROUP: + case FieldDescriptor::TYPE_MESSAGE: + case FieldDescriptor::TYPE_BYTES: + case FieldDescriptor::TYPE_ENUM: + GOOGLE_LOG(FATAL) << "Unsupported"; + return 0; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::CamelFieldType##Size( \ + value.Get##CamelCppType##Value()); + +#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::k##CamelFieldType##Size; + + CASE_TYPE(INT32, Int32, Int32); + CASE_TYPE(INT64, Int64, Int64); + CASE_TYPE(UINT32, UInt32, UInt32); + CASE_TYPE(UINT64, UInt64, UInt64); + CASE_TYPE(SINT32, SInt32, Int32); + CASE_TYPE(SINT64, SInt64, Int64); + CASE_TYPE(STRING, String, String); + FIXED_CASE_TYPE(FIXED32, Fixed32); + FIXED_CASE_TYPE(FIXED64, Fixed64); + FIXED_CASE_TYPE(SFIXED32, SFixed32); + FIXED_CASE_TYPE(SFIXED64, SFixed64); + FIXED_CASE_TYPE(BOOL, Bool); + +#undef CASE_TYPE +#undef FIXED_CASE_TYPE + } + GOOGLE_LOG(FATAL) << "Cannot get here"; + return 0; +} + +static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field, + const MapValueRef& value) { + switch (field->type()) { + case FieldDescriptor::TYPE_GROUP: + GOOGLE_LOG(FATAL) << "Unsupported"; + return 0; +#define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::CamelFieldType##Size( \ + value.Get##CamelCppType##Value()); + +#define FIXED_CASE_TYPE(FieldType, CamelFieldType) \ + case FieldDescriptor::TYPE_##FieldType: \ + return WireFormatLite::k##CamelFieldType##Size; + + CASE_TYPE(INT32, Int32, Int32); + CASE_TYPE(INT64, Int64, Int64); + CASE_TYPE(UINT32, UInt32, UInt32); + CASE_TYPE(UINT64, UInt64, UInt64); + CASE_TYPE(SINT32, SInt32, Int32); + CASE_TYPE(SINT64, SInt64, Int64); + CASE_TYPE(STRING, String, String); + CASE_TYPE(BYTES, Bytes, String); + CASE_TYPE(ENUM, Enum, Enum); + CASE_TYPE(MESSAGE, Message, Message); + FIXED_CASE_TYPE(FIXED32, Fixed32); + FIXED_CASE_TYPE(FIXED64, Fixed64); + FIXED_CASE_TYPE(SFIXED32, SFixed32); + FIXED_CASE_TYPE(SFIXED64, SFixed64); + FIXED_CASE_TYPE(DOUBLE, Double); + FIXED_CASE_TYPE(FLOAT, Float); + FIXED_CASE_TYPE(BOOL, Bool); + +#undef CASE_TYPE +#undef FIXED_CASE_TYPE + } + GOOGLE_LOG(FATAL) << "Cannot get here"; + return 0; +} + size_t WireFormat::FieldDataOnlyByteSize( const FieldDescriptor* field, const Message& message) { const Reflection* message_reflection = message.GetReflection(); + size_t data_size = 0; + + if (field->is_map()) { + MapFieldBase* map_field = + message_reflection->MapData(const_cast(&message), field); + if (map_field->IsMapValid()) { + MapIterator iter(const_cast(&message), field); + MapIterator end(const_cast(&message), field); + const FieldDescriptor* key_field = field->message_type()->field(0); + const FieldDescriptor* value_field = field->message_type()->field(1); + for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end; + ++iter) { + size_t size = kMapEntryTagByteSize; + size += MapKeyDataOnlyByteSize(key_field, iter.GetKey()); + size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef()); + data_size += WireFormatLite::LengthDelimitedSize(size); + } + return data_size; + } + } + size_t count = 0; if (field->is_repeated()) { count = @@ -1075,7 +1350,6 @@ size_t WireFormat::FieldDataOnlyByteSize( count = 1; } - size_t data_size = 0; switch (field->type()) { #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD) \ case FieldDescriptor::TYPE_##TYPE: \ -- cgit v1.2.3 From 190b5270c8717ca343db42da489e5e7d6d9efb2c Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 19 Apr 2017 16:23:51 -0700 Subject: Make PHP c extension work with PHP7 (#2951) --- .gitignore | 3 + .travis.yml | 1 + conformance/failure_list_php_c.txt | 28 +- jenkins/buildcmds/pull_request_32.sh | 2 +- jenkins/docker/Dockerfile | 31 +- jenkins/docker32/Dockerfile | 19 +- php/ext/google/protobuf/array.c | 313 +++++------ php/ext/google/protobuf/def.c | 329 ++++++------ php/ext/google/protobuf/encode_decode.c | 529 ++++++++++++------- php/ext/google/protobuf/map.c | 195 ++++--- php/ext/google/protobuf/message.c | 224 ++++---- php/ext/google/protobuf/protobuf.c | 57 +- php/ext/google/protobuf/protobuf.h | 476 ++++++++++++++--- php/ext/google/protobuf/storage.c | 578 +++++++++++++-------- php/ext/google/protobuf/type_check.c | 85 ++- php/src/Google/Protobuf/Internal/MapField.php | 3 + php/src/Google/Protobuf/Internal/RepeatedField.php | 4 + php/tests/array_test.php | 39 +- php/tests/gdb_test.sh | 8 +- php/tests/map_field_test.php | 17 +- php/tests/memory_leak_test.php | 9 +- php/tests/test_util.php | 3 +- tests.sh | 125 ++--- 23 files changed, 1891 insertions(+), 1187 deletions(-) diff --git a/.gitignore b/.gitignore index 43965a1e..0565b5e7 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,9 @@ src/js_embed src/protoc src/unittest_proto_middleman +# vim generated +*.swp + # Generated test scaffolding src/no_warning_test.cc src/no-warning-test diff --git a/.travis.yml b/.travis.yml index 77662993..8f6f90de 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ env: - CONFIG=ruby22 - CONFIG=jruby - CONFIG=php5.6_mac + - CONFIG=php7.0_mac matrix: exclude: # It's nontrivial to programmatically install a new JDK from the command diff --git a/conformance/failure_list_php_c.txt b/conformance/failure_list_php_c.txt index 05cb218a..f53449f7 100644 --- a/conformance/failure_list_php_c.txt +++ b/conformance/failure_list_php_c.txt @@ -8,6 +8,7 @@ Recommended.JsonInput.DurationHas6FractionalDigits.Validator Recommended.JsonInput.DurationHas9FractionalDigits.Validator Recommended.JsonInput.DurationHasZeroFractionalDigit.Validator Recommended.JsonInput.Int64FieldBeString.Validator +Recommended.JsonInput.MapFieldValueIsNull Recommended.JsonInput.OneofZeroBool.JsonOutput Recommended.JsonInput.OneofZeroBool.ProtobufOutput Recommended.JsonInput.OneofZeroBytes.JsonOutput @@ -24,6 +25,8 @@ Recommended.JsonInput.OneofZeroUint32.JsonOutput Recommended.JsonInput.OneofZeroUint32.ProtobufOutput Recommended.JsonInput.OneofZeroUint64.JsonOutput Recommended.JsonInput.OneofZeroUint64.ProtobufOutput +Recommended.JsonInput.RepeatedFieldMessageElementIsNull +Recommended.JsonInput.RepeatedFieldPrimitiveElementIsNull Recommended.JsonInput.StringEndsWithEscapeChar Recommended.JsonInput.StringFieldSurrogateInWrongOrder Recommended.JsonInput.StringFieldUnpairedHighSurrogate @@ -127,24 +130,12 @@ Required.JsonInput.Int32FieldStringValue.JsonOutput Required.JsonInput.Int32FieldStringValue.ProtobufOutput Required.JsonInput.Int32FieldStringValueEscaped.JsonOutput Required.JsonInput.Int32FieldStringValueEscaped.ProtobufOutput -Required.JsonInput.Int32MapEscapedKey.JsonOutput -Required.JsonInput.Int32MapEscapedKey.ProtobufOutput -Required.JsonInput.Int32MapField.JsonOutput -Required.JsonInput.Int32MapField.ProtobufOutput Required.JsonInput.Int64FieldMaxValue.JsonOutput Required.JsonInput.Int64FieldMaxValue.ProtobufOutput Required.JsonInput.Int64FieldMinValue.JsonOutput Required.JsonInput.Int64FieldMinValue.ProtobufOutput -Required.JsonInput.Int64MapEscapedKey.JsonOutput -Required.JsonInput.Int64MapEscapedKey.ProtobufOutput -Required.JsonInput.Int64MapField.JsonOutput -Required.JsonInput.Int64MapField.ProtobufOutput Required.JsonInput.MessageField.JsonOutput Required.JsonInput.MessageField.ProtobufOutput -Required.JsonInput.MessageMapField.JsonOutput -Required.JsonInput.MessageMapField.ProtobufOutput -Required.JsonInput.MessageRepeatedField.JsonOutput -Required.JsonInput.MessageRepeatedField.ProtobufOutput Required.JsonInput.OptionalBoolWrapper.JsonOutput Required.JsonInput.OptionalBoolWrapper.ProtobufOutput Required.JsonInput.OptionalBytesWrapper.JsonOutput @@ -165,14 +156,13 @@ Required.JsonInput.OptionalUint64Wrapper.JsonOutput Required.JsonInput.OptionalUint64Wrapper.ProtobufOutput Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.JsonOutput Required.JsonInput.OptionalWrapperTypesWithNonDefaultValue.ProtobufOutput -Required.JsonInput.PrimitiveRepeatedField.JsonOutput -Required.JsonInput.PrimitiveRepeatedField.ProtobufOutput Required.JsonInput.RepeatedBoolWrapper.JsonOutput Required.JsonInput.RepeatedBoolWrapper.ProtobufOutput Required.JsonInput.RepeatedBytesWrapper.JsonOutput Required.JsonInput.RepeatedBytesWrapper.ProtobufOutput Required.JsonInput.RepeatedDoubleWrapper.JsonOutput Required.JsonInput.RepeatedDoubleWrapper.ProtobufOutput +Required.JsonInput.RepeatedFieldWrongElementTypeExpectingMessagesGotInt Required.JsonInput.RepeatedFieldWrongElementTypeExpectingStringsGotInt Required.JsonInput.RepeatedFloatWrapper.JsonOutput Required.JsonInput.RepeatedFloatWrapper.ProtobufOutput @@ -186,9 +176,15 @@ Required.JsonInput.RepeatedUint32Wrapper.JsonOutput Required.JsonInput.RepeatedUint32Wrapper.ProtobufOutput Required.JsonInput.RepeatedUint64Wrapper.JsonOutput Required.JsonInput.RepeatedUint64Wrapper.ProtobufOutput +Required.JsonInput.StringFieldEscape.JsonOutput +Required.JsonInput.StringFieldEscape.ProtobufOutput Required.JsonInput.StringFieldNotAString Required.JsonInput.StringFieldSurrogatePair.JsonOutput Required.JsonInput.StringFieldSurrogatePair.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscape.JsonOutput +Required.JsonInput.StringFieldUnicodeEscape.ProtobufOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.JsonOutput +Required.JsonInput.StringFieldUnicodeEscapeWithLowercaseHexLetters.ProtobufOutput Required.JsonInput.Struct.JsonOutput Required.JsonInput.Struct.ProtobufOutput Required.JsonInput.TimestampMaxValue.JsonOutput @@ -203,12 +199,8 @@ Required.JsonInput.TimestampWithPositiveOffset.JsonOutput Required.JsonInput.TimestampWithPositiveOffset.ProtobufOutput Required.JsonInput.Uint32FieldMaxFloatValue.JsonOutput Required.JsonInput.Uint32FieldMaxFloatValue.ProtobufOutput -Required.JsonInput.Uint32MapField.JsonOutput -Required.JsonInput.Uint32MapField.ProtobufOutput Required.JsonInput.Uint64FieldMaxValue.JsonOutput Required.JsonInput.Uint64FieldMaxValue.ProtobufOutput -Required.JsonInput.Uint64MapField.JsonOutput -Required.JsonInput.Uint64MapField.ProtobufOutput Required.JsonInput.ValueAcceptBool.JsonOutput Required.JsonInput.ValueAcceptBool.ProtobufOutput Required.JsonInput.ValueAcceptFloat.JsonOutput diff --git a/jenkins/buildcmds/pull_request_32.sh b/jenkins/buildcmds/pull_request_32.sh index bf0fb7ff..99df2971 100755 --- a/jenkins/buildcmds/pull_request_32.sh +++ b/jenkins/buildcmds/pull_request_32.sh @@ -12,5 +12,5 @@ export DOCKERFILE_DIR=jenkins/docker32 export DOCKER_RUN_SCRIPT=jenkins/pull_request_in_docker.sh export OUTPUT_DIR=testoutput -export TEST_SET="php_all_32" +export TEST_SET="php_all" ./jenkins/build_and_run_docker.sh diff --git a/jenkins/docker/Dockerfile b/jenkins/docker/Dockerfile index 685c05d6..9c9ee56b 100644 --- a/jenkins/docker/Dockerfile +++ b/jenkins/docker/Dockerfile @@ -147,6 +147,23 @@ RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php make && make install && cd .. RUN cd php-5.5.38 && make clean && ./configure --prefix=/usr/local/php-5.5 && \ make && make install && cd .. + +RUN wget http://am1.php.net/get/php-5.6.30.tar.bz2/from/this/mirror +RUN mv mirror php-5.6.30.tar.bz2 +RUN tar -xvf php-5.6.30.tar.bz2 +RUN cd php-5.6.30 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.6-zts && \ + make && make install && cd .. +RUN cd php-5.6.30 && make clean && ./configure --prefix=/usr/local/php-5.6 && \ + make && make install && cd .. + +RUN wget http://am1.php.net/get/php-7.0.18.tar.bz2/from/this/mirror +RUN mv mirror php-7.0.18.tar.bz2 +RUN tar -xvf php-7.0.18.tar.bz2 +RUN cd php-7.0.18 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-7.0-zts && \ + make && make install && cd .. +RUN cd php-7.0.18 && make clean && ./configure --prefix=/usr/local/php-7.0 && \ + make && make install && cd .. + RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" RUN php composer-setup.php RUN mv composer.phar /usr/bin/composer @@ -157,21 +174,21 @@ RUN cd /tmp && \ rm -rf protobuf && \ git clone https://github.com/google/protobuf.git && \ cd protobuf && \ - git reset --hard 46ae90dc5e145b12fffa7e053a908a9f3e066286 && \ + git reset --hard 6b27c1f981a9a93918e4039f236ead27165a8e91 && \ cd php && \ ln -sfn /usr/local/php-5.5/bin/php /usr/bin/php && \ ln -sfn /usr/local/php-5.5/bin/php-config /usr/bin/php-config && \ ln -sfn /usr/local/php-5.5/bin/phpize /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-5.5 && \ - ln -sfn /usr/bin/php5.6 /usr/bin/php && \ - ln -sfn /usr/bin/php-config5.6 /usr/bin/php-config && \ - ln -sfn /usr/bin/phpize5.6 /usr/bin/phpize && \ + ln -sfn /usr/local/php-5.6/bin/php /usr/bin/php && \ + ln -sfn /usr/local/php-5.6/bin/php-config /usr/bin/php-config && \ + ln -sfn /usr/local/php-5.6/bin/phpize /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-5.6 && \ - ln -sfn /usr/bin/php7.0 /usr/bin/php && \ - ln -sfn /usr/bin/php-config7.0 /usr/bin/php-config && \ - ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \ + ln -sfn /usr/local/php-7.0/bin/php /usr/bin/php && \ + ln -sfn /usr/local/php-7.0/bin/php-config /usr/bin/php-config && \ + ln -sfn /usr/local/php-7.0/bin/phpize /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-7.0 diff --git a/jenkins/docker32/Dockerfile b/jenkins/docker32/Dockerfile index 2d83735d..ab3fd957 100644 --- a/jenkins/docker32/Dockerfile +++ b/jenkins/docker32/Dockerfile @@ -80,14 +80,31 @@ RUN cd /tmp && \ ln -sfn /usr/bin/phpize7.0 /usr/bin/phpize && \ composer install && \ mv vendor /usr/local/vendor-7.0 + RUN wget http://am1.php.net/get/php-5.5.38.tar.bz2/from/this/mirror RUN mv mirror php-5.5.38.tar.bz2 RUN tar -xvf php-5.5.38.tar.bz2 RUN cd php-5.5.38 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.5-zts && \ make && make install && make clean && cd .. -RUN cd php-5.5.38 && ./configure --enable-bcmath --prefix=/usr/local/php-5.5-bc && \ +RUN cd php-5.5.38 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.5 && \ make && make install && make clean && cd .. +RUN wget http://am1.php.net/get/php-5.6.30.tar.bz2/from/this/mirror +RUN mv mirror php-5.6.30.tar.bz2 +RUN tar -xvf php-5.6.30.tar.bz2 +RUN cd php-5.6.30 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-5.6-zts && \ + make && make install && cd .. +RUN cd php-5.6.30 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-5.6 && \ + make && make install && cd .. + +RUN wget http://am1.php.net/get/php-7.0.18.tar.bz2/from/this/mirror +RUN mv mirror php-7.0.18.tar.bz2 +RUN tar -xvf php-7.0.18.tar.bz2 +RUN cd php-7.0.18 && ./configure --enable-maintainer-zts --prefix=/usr/local/php-7.0-zts && \ + make && make install && cd .. +RUN cd php-7.0.18 && make clean && ./configure --enable-bcmath --prefix=/usr/local/php-7.0 && \ + make && make install && cd .. + ################## # Python dependencies diff --git a/php/ext/google/protobuf/array.c b/php/ext/google/protobuf/array.c index 2186ab1f..e9f5f156 100644 --- a/php/ext/google/protobuf/array.c +++ b/php/ext/google/protobuf/array.c @@ -69,19 +69,20 @@ static zend_function_entry repeated_field_iter_methods[] = { // Forward declare static functions. -static zend_object_value repeated_field_create(zend_class_entry *ce TSRMLS_DC); -static void repeated_field_free(void *object TSRMLS_DC); static int repeated_field_array_init(zval *array, upb_fieldtype_t type, uint size ZEND_FILE_LINE_DC); -static void repeated_field_free_element(void *object); static void repeated_field_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC); static int repeated_field_has_dimension(zval *object, zval *offset TSRMLS_DC); -static HashTable *repeated_field_get_gc(zval *object, zval ***table, +static HashTable *repeated_field_get_gc(zval *object, CACHED_VALUE **table, int *n TSRMLS_DC); - +#if PHP_MAJOR_VERSION < 7 +static zend_object_value repeated_field_create(zend_class_entry *ce TSRMLS_DC); static zend_object_value repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC); -static void repeated_field_iter_free(void *object TSRMLS_DC); +#else +static zend_object *repeated_field_create(zend_class_entry *ce TSRMLS_DC); +static zend_object *repeated_field_iter_create(zend_class_entry *ce TSRMLS_DC); +#endif // ----------------------------------------------------------------------------- // RepeatedField creation/desctruction @@ -90,76 +91,91 @@ static void repeated_field_iter_free(void *object TSRMLS_DC); zend_class_entry* repeated_field_type; zend_class_entry* repeated_field_iter_type; zend_object_handlers* repeated_field_handlers; - -void repeated_field_init(TSRMLS_D) { - zend_class_entry class_type; - const char* class_name = "Google\\Protobuf\\Internal\\RepeatedField"; - INIT_CLASS_ENTRY_EX(class_type, class_name, strlen(class_name), - repeated_field_methods); - - repeated_field_type = zend_register_internal_class(&class_type TSRMLS_CC); - repeated_field_type->create_object = repeated_field_create; - - zend_class_implements(repeated_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess, - zend_ce_aggregate, spl_ce_Countable); - - repeated_field_handlers = PEMALLOC(zend_object_handlers); - memcpy(repeated_field_handlers, zend_get_std_object_handlers(), - sizeof(zend_object_handlers)); - repeated_field_handlers->write_dimension = repeated_field_write_dimension; - repeated_field_handlers->get_gc = repeated_field_get_gc; +zend_object_handlers* repeated_field_iter_handlers; + +// Define object free method. +PHP_PROTO_OBJECT_FREE_START(RepeatedField, repeated_field) +#if PHP_MAJOR_VERSION < 7 +php_proto_zval_ptr_dtor(intern->array); +#else +php_proto_zval_ptr_dtor(&intern->array); +#endif +PHP_PROTO_OBJECT_FREE_END + +PHP_PROTO_OBJECT_DTOR_START(RepeatedField, repeated_field) +PHP_PROTO_OBJECT_DTOR_END + +// Define object create method. +PHP_PROTO_OBJECT_CREATE_START(RepeatedField, repeated_field) +#if PHP_MAJOR_VERSION < 7 +intern->array = NULL; +#endif +intern->type = 0; +intern->msg_ce = NULL; +PHP_PROTO_OBJECT_CREATE_END(RepeatedField, repeated_field) + +// Init class entry. +PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\RepeatedField", + RepeatedField, repeated_field) +zend_class_implements(repeated_field_type TSRMLS_CC, 3, spl_ce_ArrayAccess, + zend_ce_aggregate, spl_ce_Countable); +repeated_field_handlers->write_dimension = repeated_field_write_dimension; +repeated_field_handlers->get_gc = repeated_field_get_gc; +PHP_PROTO_INIT_CLASS_END + +// Define array element free function. +#if PHP_MAJOR_VERSION < 7 +static inline void php_proto_array_string_release(void *value) { + zval_ptr_dtor(value); } -static zend_object_value repeated_field_create(zend_class_entry *ce TSRMLS_DC) { - zend_object_value retval = {0}; - RepeatedField *intern; - - intern = emalloc(sizeof(RepeatedField)); - memset(intern, 0, sizeof(RepeatedField)); - - zend_object_std_init(&intern->std, ce TSRMLS_CC); - object_properties_init(&intern->std, ce); - - intern->array = NULL; - intern->type = 0; - intern->msg_ce = NULL; - - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - (zend_objects_free_object_storage_t)repeated_field_free, NULL TSRMLS_CC); - retval.handlers = repeated_field_handlers; - - return retval; +static inline void php_proto_array_object_release(void *value) { + zval_ptr_dtor(value); } - -static void repeated_field_free(void *object TSRMLS_DC) { - RepeatedField *intern = object; - zend_object_std_dtor(&intern->std TSRMLS_CC); - zval_ptr_dtor(&intern->array); - efree(object); +static inline void php_proto_array_default_release(void *value) { +} +#else +static inline void php_proto_array_string_release(zval *value) { + void* ptr = Z_PTR_P(value); + zend_string* object = *(zend_string**)ptr; + zend_string_release(object); + efree(ptr); +} +static inline void php_proto_array_object_release(zval *value) { + void* ptr = Z_PTR_P(value); + zend_object* object = *(zend_object**)ptr; + if(--GC_REFCOUNT(object) == 0) { + zend_objects_store_del(object); + } + efree(ptr); } +static void php_proto_array_default_release(zval* value) { + void* ptr = Z_PTR_P(value); + efree(ptr); +} +#endif static int repeated_field_array_init(zval *array, upb_fieldtype_t type, uint size ZEND_FILE_LINE_DC) { - ALLOC_HASHTABLE(Z_ARRVAL_P(array)); + PHP_PROTO_ALLOC_ARRAY(array); switch (type) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: + zend_hash_init(Z_ARRVAL_P(array), size, NULL, + php_proto_array_string_release, 0); + break; case UPB_TYPE_MESSAGE: - zend_hash_init(Z_ARRVAL_P(array), size, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(Z_ARRVAL_P(array), size, NULL, + php_proto_array_object_release, 0); break; default: - zend_hash_init(Z_ARRVAL_P(array), size, NULL, repeated_field_free_element, - 0); + zend_hash_init(Z_ARRVAL_P(array), size, NULL, + php_proto_array_default_release, 0); } - Z_TYPE_P(array) = IS_ARRAY; return SUCCESS; } -static void repeated_field_free_element(void *object) { -} - // ----------------------------------------------------------------------------- // RepeatedField Handlers // ----------------------------------------------------------------------------- @@ -168,23 +184,25 @@ static void repeated_field_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) { uint64_t index; - RepeatedField *intern = zend_object_store_get_object(object TSRMLS_CC); - HashTable *ht = HASH_OF(intern->array); + RepeatedField *intern = UNBOX(RepeatedField, object); + HashTable *ht = PHP_PROTO_HASH_OF(intern->array); int size = native_slot_size(intern->type); unsigned char memory[NATIVE_SLOT_MAX_SIZE]; memset(memory, 0, NATIVE_SLOT_MAX_SIZE); - if (!native_slot_set(intern->type, intern->msg_ce, memory, value TSRMLS_CC)) { + if (!native_slot_set_by_array(intern->type, intern->msg_ce, memory, + value TSRMLS_CC)) { return; } if (!offset || Z_TYPE_P(offset) == IS_NULL) { - index = zend_hash_num_elements(HASH_OF(intern->array)); + index = zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array)); } else { if (protobuf_convert_to_uint64(offset, &index)) { if (!zend_hash_index_exists(ht, index)) { - zend_error(E_USER_ERROR, "Element at %llu doesn't exist.\n", index); + zend_error(E_USER_ERROR, "Element at %llu doesn't exist.\n", + (long long unsigned int)index); return; } } else { @@ -192,15 +210,19 @@ static void repeated_field_write_dimension(zval *object, zval *offset, } } - zend_hash_index_update(ht, index, memory, size, NULL); + php_proto_zend_hash_index_update(ht, index, memory, size, NULL); } +#if PHP_MAJOR_VERSION < 7 static HashTable *repeated_field_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) { +#else +static HashTable *repeated_field_get_gc(zval *object, zval **table, int *n) { +#endif *table = NULL; *n = 0; - RepeatedField *intern = zend_object_store_get_object(object TSRMLS_CC); - return HASH_OF(intern->array); + RepeatedField *intern = UNBOX(RepeatedField, object); + return PHP_PROTO_HASH_OF(intern->array); } // ----------------------------------------------------------------------------- @@ -208,10 +230,10 @@ static HashTable *repeated_field_get_gc(zval *object, zval ***table, // ----------------------------------------------------------------------------- void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC) { - HashTable *ht = HASH_OF(intern->array); + HashTable *ht = PHP_PROTO_HASH_OF(intern->array); void *value; - if (zend_hash_index_find(ht, index, (void **)&value) == FAILURE) { + if (php_proto_zend_hash_index_find(ht, index, (void **)&value) == FAILURE) { zend_error(E_USER_ERROR, "Element at %d doesn't exist.\n", index); return NULL; } @@ -219,35 +241,37 @@ void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC) { return value; } -void repeated_field_push_native(RepeatedField *intern, void *value TSRMLS_DC) { - HashTable *ht = HASH_OF(intern->array); +void repeated_field_push_native(RepeatedField *intern, void *value) { + HashTable *ht = PHP_PROTO_HASH_OF(intern->array); int size = native_slot_size(intern->type); - zend_hash_next_index_insert(ht, (void **)value, size, NULL); + php_proto_zend_hash_next_index_insert(ht, (void **)value, size, NULL); } -void repeated_field_create_with_field(zend_class_entry *ce, - const upb_fielddef *field, - zval **repeated_field TSRMLS_DC) { +void repeated_field_create_with_field( + zend_class_entry *ce, const upb_fielddef *field, + CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) { upb_fieldtype_t type = upb_fielddef_type(field); - const zend_class_entry *msg_ce = field_type_class(field TSRMLS_CC); - repeated_field_create_with_type(ce, type, msg_ce, repeated_field TSRMLS_CC); + const zend_class_entry *msg_ce = field_type_class(field PHP_PROTO_TSRMLS_CC); + repeated_field_create_with_type(ce, type, msg_ce, + repeated_field PHP_PROTO_TSRMLS_CC); } -void repeated_field_create_with_type(zend_class_entry *ce, - upb_fieldtype_t type, - const zend_class_entry* msg_ce, - zval **repeated_field TSRMLS_DC) { - MAKE_STD_ZVAL(*repeated_field); - Z_TYPE_PP(repeated_field) = IS_OBJECT; - Z_OBJVAL_PP(repeated_field) = - repeated_field_type->create_object(repeated_field_type TSRMLS_CC); +void repeated_field_create_with_type( + zend_class_entry *ce, upb_fieldtype_t type, const zend_class_entry *msg_ce, + CACHED_VALUE *repeated_field PHP_PROTO_TSRMLS_DC) { + CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(CACHED_PTR_TO_ZVAL_PTR(repeated_field), + repeated_field_type); RepeatedField *intern = - zend_object_store_get_object(*repeated_field TSRMLS_CC); + UNBOX(RepeatedField, CACHED_TO_ZVAL_PTR(*repeated_field)); intern->type = type; intern->msg_ce = msg_ce; +#if PHP_MAJOR_VERSION < 7 MAKE_STD_ZVAL(intern->array); repeated_field_array_init(intern->array, intern->type, 0 ZEND_FILE_LINE_CC); +#else + repeated_field_array_init(&intern->array, intern->type, 0 ZEND_FILE_LINE_CC); +#endif // TODO(teboring): Link class entry for message and enum } @@ -271,12 +295,16 @@ PHP_METHOD(RepeatedField, __construct) { return; } - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedField *intern = UNBOX(RepeatedField, getThis()); intern->type = to_fieldtype(type); intern->msg_ce = klass; +#if PHP_MAJOR_VERSION < 7 MAKE_STD_ZVAL(intern->array); repeated_field_array_init(intern->array, intern->type, 0 ZEND_FILE_LINE_CC); +#else + repeated_field_array_init(&intern->array, intern->type, 0 ZEND_FILE_LINE_CC); +#endif if (intern->type == UPB_TYPE_MESSAGE && klass == NULL) { zend_error(E_USER_ERROR, "Message type must have concrete class."); @@ -313,10 +341,10 @@ PHP_METHOD(RepeatedField, offsetExists) { return; } - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedField *intern = UNBOX(RepeatedField, getThis()); RETURN_BOOL(index >= 0 && - index < zend_hash_num_elements(HASH_OF(intern->array))); + index < zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array))); } /** @@ -336,15 +364,16 @@ PHP_METHOD(RepeatedField, offsetGet) { return; } - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); - HashTable *table = HASH_OF(intern->array); + RepeatedField *intern = UNBOX(RepeatedField, getThis()); + HashTable *table = PHP_PROTO_HASH_OF(intern->array); - if (zend_hash_index_find(table, index, (void **)&memory) == FAILURE) { + if (php_proto_zend_hash_index_find(table, index, (void **)&memory) == FAILURE) { zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); return; } - native_slot_get(intern->type, memory, return_value_ptr TSRMLS_CC); + native_slot_get_by_array(intern->type, memory, + ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); } /** @@ -379,16 +408,16 @@ PHP_METHOD(RepeatedField, offsetUnset) { return; } - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedField *intern = UNBOX(RepeatedField, getThis()); // Only the element at the end of the array can be removed. if (index == -1 || - index != (zend_hash_num_elements(HASH_OF(intern->array)) - 1)) { + index != (zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array)) - 1)) { zend_error(E_USER_ERROR, "Cannot remove element at %ld.\n", index); return; } - zend_hash_index_del(HASH_OF(intern->array), index); + zend_hash_index_del(PHP_PROTO_HASH_OF(intern->array), index); } /** @@ -397,13 +426,13 @@ PHP_METHOD(RepeatedField, offsetUnset) { * @return long The number of stored elements. */ PHP_METHOD(RepeatedField, count) { - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedField *intern = UNBOX(RepeatedField, getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } - RETURN_LONG(zend_hash_num_elements(HASH_OF(intern->array))); + RETURN_LONG(zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array))); } /** @@ -412,105 +441,77 @@ PHP_METHOD(RepeatedField, count) { * @return object Beginning iterator. */ PHP_METHOD(RepeatedField, getIterator) { - zval *iter_php = NULL; - MAKE_STD_ZVAL(iter_php); - Z_TYPE_P(iter_php) = IS_OBJECT; - Z_OBJVAL_P(iter_php) = repeated_field_iter_type->create_object( - repeated_field_iter_type TSRMLS_CC); - - RepeatedField *intern = zend_object_store_get_object(getThis() TSRMLS_CC); - RepeatedFieldIter *iter = zend_object_store_get_object(iter_php TSRMLS_CC); + CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(return_value, + repeated_field_iter_type); + + RepeatedField *intern = UNBOX(RepeatedField, getThis()); + RepeatedFieldIter *iter = UNBOX(RepeatedFieldIter, return_value); iter->repeated_field = intern; iter->position = 0; - - RETURN_ZVAL(iter_php, 1, 1); } // ----------------------------------------------------------------------------- // RepeatedFieldIter creation/desctruction // ----------------------------------------------------------------------------- -void repeated_field_iter_init(TSRMLS_D) { - zend_class_entry class_type; - const char* class_name = "Google\\Protobuf\\Internal\\RepeatedFieldIter"; - INIT_CLASS_ENTRY_EX(class_type, class_name, strlen(class_name), - repeated_field_iter_methods); - - repeated_field_iter_type = - zend_register_internal_class(&class_type TSRMLS_CC); - repeated_field_iter_type->create_object = repeated_field_iter_create; - - zend_class_implements(repeated_field_iter_type TSRMLS_CC, 1, - zend_ce_iterator); -} - -static zend_object_value repeated_field_iter_create( - zend_class_entry *ce TSRMLS_DC) { - zend_object_value retval = {0}; - RepeatedFieldIter *intern; - - intern = emalloc(sizeof(RepeatedFieldIter)); - memset(intern, 0, sizeof(RepeatedFieldIter)); - - zend_object_std_init(&intern->std, ce TSRMLS_CC); - object_properties_init(&intern->std, ce); +// Define object free method. +PHP_PROTO_OBJECT_FREE_START(RepeatedFieldIter, repeated_field_iter) +PHP_PROTO_OBJECT_FREE_END - intern->repeated_field = NULL; - intern->position = 0; - - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - (zend_objects_free_object_storage_t)repeated_field_iter_free, - NULL TSRMLS_CC); - retval.handlers = zend_get_std_object_handlers(); +PHP_PROTO_OBJECT_DTOR_START(RepeatedFieldIter, repeated_field_iter) +PHP_PROTO_OBJECT_DTOR_END - return retval; -} +// Define object create method. +PHP_PROTO_OBJECT_CREATE_START(RepeatedFieldIter, repeated_field_iter) +intern->repeated_field = NULL; +intern->position = 0; +PHP_PROTO_OBJECT_CREATE_END(RepeatedFieldIter, repeated_field_iter) -static void repeated_field_iter_free(void *object TSRMLS_DC) { - RepeatedFieldIter *intern = object; - zend_object_std_dtor(&intern->std TSRMLS_CC); - efree(object); -} +// Init class entry. +PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\RepeatedFieldIter", + RepeatedFieldIter, repeated_field_iter) +zend_class_implements(repeated_field_iter_type TSRMLS_CC, 1, zend_ce_iterator); +PHP_PROTO_INIT_CLASS_END // ----------------------------------------------------------------------------- // PHP RepeatedFieldIter Methods // ----------------------------------------------------------------------------- PHP_METHOD(RepeatedFieldIter, rewind) { - RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); intern->position = 0; } PHP_METHOD(RepeatedFieldIter, current) { - RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); RepeatedField *repeated_field = intern->repeated_field; long index; void *memory; - HashTable *table = HASH_OF(repeated_field->array); + HashTable *table = PHP_PROTO_HASH_OF(repeated_field->array); - if (zend_hash_index_find(table, intern->position, (void **)&memory) == + if (php_proto_zend_hash_index_find(table, intern->position, (void **)&memory) == FAILURE) { zend_error(E_USER_ERROR, "Element at %ld doesn't exist.\n", index); return; } - native_slot_get(repeated_field->type, memory, return_value_ptr TSRMLS_CC); + native_slot_get_by_array(repeated_field->type, memory, + ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); } PHP_METHOD(RepeatedFieldIter, key) { - RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); RETURN_LONG(intern->position); } PHP_METHOD(RepeatedFieldIter, next) { - RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); + RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); ++intern->position; } PHP_METHOD(RepeatedFieldIter, valid) { - RepeatedFieldIter *intern = zend_object_store_get_object(getThis() TSRMLS_CC); - RETURN_BOOL(zend_hash_num_elements(HASH_OF(intern->repeated_field->array)) > - intern->position); + RepeatedFieldIter *intern = UNBOX(RepeatedFieldIter, getThis()); + RETURN_BOOL(zend_hash_num_elements(PHP_PROTO_HASH_OF( + intern->repeated_field->array)) > intern->position); } diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 52b9e885..50c0350e 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -31,19 +31,13 @@ #include "protobuf.h" // Forward declare. -static zend_object_value descriptor_create(zend_class_entry *ce TSRMLS_DC); static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC); static void descriptor_free_c(Descriptor* object TSRMLS_DC); -static void descriptor_free(void* object TSRMLS_DC); -static zend_object_value enum_descriptor_create(zend_class_entry *ce TSRMLS_DC); static void enum_descriptor_init_c_instance(EnumDescriptor* intern TSRMLS_DC); static void enum_descriptor_free_c(EnumDescriptor* object TSRMLS_DC); -static void enum_descriptor_free(void* object TSRMLS_DC); -static zend_object_value descriptor_pool_create(zend_class_entry *ce TSRMLS_DC); static void descriptor_pool_free_c(DescriptorPool* object TSRMLS_DC); -static void descriptor_pool_free(void* object TSRMLS_DC); static void descriptor_pool_init_c_instance(DescriptorPool* pool TSRMLS_DC); // ----------------------------------------------------------------------------- @@ -104,40 +98,31 @@ static void append_map_entry_name(char *result, const char *field_name, } while (0) // Define PHP class -#define DEFINE_PROTOBUF_INIT_CLASS(name_lower, string_name) \ - void name_lower##_init(TSRMLS_D) { \ - zend_class_entry class_type; \ - INIT_CLASS_ENTRY(class_type, string_name, name_lower##_methods); \ - name_lower##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ - name_lower##_type->create_object = name_lower##_create; \ - } - -#define DEFINE_PROTOBUF_CREATE(name, name_lower) \ - static zend_object_value name_lower##_create( \ - zend_class_entry* ce TSRMLS_DC) { \ - zend_object_value return_value; \ - name* intern = (name*)emalloc(sizeof(name)); \ - memset(intern, 0, sizeof(name)); \ - name_lower##_init_c_instance(intern TSRMLS_CC); \ - return_value.handle = zend_objects_store_put( \ - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ - name_lower##_free, NULL TSRMLS_CC); \ - return_value.handlers = zend_get_std_object_handlers(); \ - return return_value; \ - } - -#define DEFINE_PROTOBUF_FREE(name, name_lower) \ - static void name_lower##_free(void* object TSRMLS_DC) { \ - name* intern = (name*)object; \ - name_lower##_free_c(intern TSRMLS_CC); \ - efree(object); \ - } - -#define DEFINE_CLASS(name, name_lower, string_name) \ - zend_class_entry* name_lower##_type; \ - DEFINE_PROTOBUF_FREE(name, name_lower) \ - DEFINE_PROTOBUF_CREATE(name, name_lower) \ - DEFINE_PROTOBUF_INIT_CLASS(name_lower, string_name) +#define DEFINE_PROTOBUF_INIT_CLASS(CLASSNAME, CAMELNAME, LOWERNAME) \ + PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWERNAME) \ + PHP_PROTO_INIT_CLASS_END + +#define DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \ + PHP_PROTO_OBJECT_CREATE_START(NAME, LOWERNAME) \ + LOWERNAME##_init_c_instance(intern TSRMLS_CC); \ + PHP_PROTO_OBJECT_CREATE_END(NAME, LOWERNAME) + +#define DEFINE_PROTOBUF_FREE(CAMELNAME, LOWERNAME) \ + PHP_PROTO_OBJECT_FREE_START(CAMELNAME, LOWERNAME) \ + LOWERNAME##_free_c(intern TSRMLS_CC); \ + PHP_PROTO_OBJECT_FREE_END + +#define DEFINE_PROTOBUF_DTOR(CAMELNAME, LOWERNAME) \ + PHP_PROTO_OBJECT_DTOR_START(CAMELNAME, LOWERNAME) \ + PHP_PROTO_OBJECT_DTOR_END + +#define DEFINE_CLASS(NAME, LOWERNAME, string_name) \ + zend_class_entry *LOWERNAME##_type; \ + zend_object_handlers *LOWERNAME##_handlers; \ + DEFINE_PROTOBUF_FREE(NAME, LOWERNAME) \ + DEFINE_PROTOBUF_DTOR(NAME, LOWERNAME) \ + DEFINE_PROTOBUF_CREATE(NAME, LOWERNAME) \ + DEFINE_PROTOBUF_INIT_CLASS(string_name, NAME, LOWERNAME) // ----------------------------------------------------------------------------- // GPBType @@ -176,6 +161,114 @@ void gpb_type_init(TSRMLS_D) { zend_declare_class_constant_long(gpb_type_type, STR("SINT64"), 18 TSRMLS_CC); } +// ----------------------------------------------------------------------------- +// Descriptor +// ----------------------------------------------------------------------------- + +static zend_function_entry descriptor_methods[] = { + ZEND_FE_END +}; + +DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Internal\\Descriptor"); + +static void descriptor_free_c(Descriptor *self TSRMLS_DC) { + if (self->layout) { + free_layout(self->layout); + } + if (self->fill_handlers) { + upb_handlers_unref(self->fill_handlers, &self->fill_handlers); + } + if (self->fill_method) { + upb_pbdecodermethod_unref(self->fill_method, &self->fill_method); + } + if (self->json_fill_method) { + upb_json_parsermethod_unref(self->json_fill_method, + &self->json_fill_method); + } + if (self->pb_serialize_handlers) { + upb_handlers_unref(self->pb_serialize_handlers, + &self->pb_serialize_handlers); + } + if (self->json_serialize_handlers) { + upb_handlers_unref(self->json_serialize_handlers, + &self->json_serialize_handlers); + } + if (self->json_serialize_handlers_preserve) { + upb_handlers_unref(self->json_serialize_handlers_preserve, + &self->json_serialize_handlers_preserve); + } +} + +static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) { + // zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC); + desc->msgdef = NULL; + desc->layout = NULL; + desc->klass = NULL; + desc->fill_handlers = NULL; + desc->fill_method = NULL; + desc->json_fill_method = NULL; + desc->pb_serialize_handlers = NULL; + desc->json_serialize_handlers = NULL; + desc->json_serialize_handlers_preserve = NULL; +} + +// ----------------------------------------------------------------------------- +// EnumDescriptor +// ----------------------------------------------------------------------------- + +static zend_function_entry enum_descriptor_methods[] = { + ZEND_FE_END +}; + +DEFINE_CLASS(EnumDescriptor, enum_descriptor, + "Google\\Protobuf\\Internal\\EnumDescriptor"); + +static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) { +} + +static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) { + // zend_object_std_init(&self->std, enum_descriptor_type TSRMLS_CC); + self->enumdef = NULL; + self->klass = NULL; +} + +// ----------------------------------------------------------------------------- +// FieldDescriptor +// ----------------------------------------------------------------------------- + +upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { + switch (type) { +#define CASE(descriptor_type, type) \ + case UPB_DESCRIPTOR_TYPE_##descriptor_type: \ + return UPB_TYPE_##type; + + CASE(FLOAT, FLOAT); + CASE(DOUBLE, DOUBLE); + CASE(BOOL, BOOL); + CASE(STRING, STRING); + CASE(BYTES, BYTES); + CASE(MESSAGE, MESSAGE); + CASE(GROUP, MESSAGE); + CASE(ENUM, ENUM); + CASE(INT32, INT32); + CASE(INT64, INT64); + CASE(UINT32, UINT32); + CASE(UINT64, UINT64); + CASE(SINT32, INT32); + CASE(SINT64, INT64); + CASE(FIXED32, UINT32); + CASE(FIXED64, UINT64); + CASE(SFIXED32, INT32); + CASE(SFIXED64, INT64); + +#undef CONVERT + + } + + zend_error(E_ERROR, "Unknown field type."); + return 0; +} + // ----------------------------------------------------------------------------- // DescriptorPool // ----------------------------------------------------------------------------- @@ -190,25 +283,32 @@ static zend_function_entry descriptor_pool_methods[] = { DEFINE_CLASS(DescriptorPool, descriptor_pool, "Google\\Protobuf\\Internal\\DescriptorPool"); -zval* generated_pool_php; // wrapper of generated pool +// wrapper of generated pool +#if PHP_MAJOR_VERSION < 7 +zval* generated_pool_php; +#else +zend_object *generated_pool_php; +#endif DescriptorPool *generated_pool; // The actual generated pool static void init_generated_pool_once(TSRMLS_D) { if (generated_pool_php == NULL) { +#if PHP_MAJOR_VERSION < 7 MAKE_STD_ZVAL(generated_pool_php); - Z_TYPE_P(generated_pool_php) = IS_OBJECT; - generated_pool = ALLOC(DescriptorPool); - descriptor_pool_init_c_instance(generated_pool TSRMLS_CC); - Z_OBJ_HANDLE_P(generated_pool_php) = zend_objects_store_put( - generated_pool, NULL, - (zend_objects_free_object_storage_t)descriptor_pool_free, - NULL TSRMLS_CC); - Z_OBJ_HT_P(generated_pool_php) = zend_get_std_object_handlers(); + ZVAL_OBJ(generated_pool_php, descriptor_pool_type->create_object( + descriptor_pool_type TSRMLS_CC)); + generated_pool = UNBOX(DescriptorPool, generated_pool_php); +#else + generated_pool_php = + descriptor_pool_type->create_object(descriptor_pool_type TSRMLS_CC); + generated_pool = (DescriptorPool *)((char *)generated_pool_php - + XtOffsetOf(DescriptorPool, std)); +#endif } } static void descriptor_pool_init_c_instance(DescriptorPool *pool TSRMLS_DC) { - zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC); + // zend_object_std_init(&pool->std, descriptor_pool_type TSRMLS_CC); pool->symtab = upb_symtab_new(); ALLOC_HASHTABLE(pool->pending_list); @@ -247,7 +347,12 @@ static void validate_msgdef(const upb_msgdef* msgdef) { PHP_METHOD(DescriptorPool, getGeneratedPool) { init_generated_pool_once(TSRMLS_C); +#if PHP_MAJOR_VERSION < 7 RETURN_ZVAL(generated_pool_php, 1, 0); +#else + ++GC_REFCOUNT(generated_pool_php); + RETURN_OBJ(generated_pool_php); +#endif } static void convert_to_class_name_inplace(char *class_name, @@ -306,7 +411,7 @@ static void convert_to_class_name_inplace(char *class_name, PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { char *data = NULL; - int data_len; + PHP_PROTO_SIZE data_len; upb_filedef **files; size_t i; @@ -335,11 +440,7 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { switch (upb_def_type(def)) { #define CASE_TYPE(def_type, def_type_lower, desc_type, desc_type_lower) \ case UPB_DEF_##def_type: { \ - desc_type *desc; \ - zval *desc_php; \ - CREATE(desc_type, desc, desc_type_lower##_init_c_instance); \ - BOX(desc_type, desc_php, desc, desc_type_lower##_free); \ - Z_DELREF_P(desc_php); \ + CREATE_HASHTABLE_VALUE(desc, desc_php, desc_type, desc_type_lower##_type); \ const upb_##def_type_lower *def_type_lower = \ upb_downcast_##def_type_lower(def); \ desc->def_type_lower = def_type_lower; \ @@ -362,14 +463,14 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { char *klass_name = ecalloc(sizeof(char), klass_name_len); \ convert_to_class_name_inplace(klass_name, fullname, prefix, \ upb_filedef_package(files[0])); \ - zend_class_entry **pce; \ - if (zend_lookup_class(klass_name, strlen(klass_name), &pce TSRMLS_CC) == \ + PHP_PROTO_CE_DECLARE pce; \ + if (php_proto_zend_lookup_class(klass_name, strlen(klass_name), &pce) == \ FAILURE) { \ zend_error(E_ERROR, "Generated message class %s hasn't been defined", \ klass_name); \ return; \ } else { \ - desc->klass = *pce; \ + desc->klass = PHP_PROTO_CE_UNREF(pce); \ } \ add_ce_obj(desc->klass, desc_php); \ efree(klass_name); \ @@ -389,7 +490,7 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { const upb_def *def = upb_filedef_def(files[0], i); if (upb_def_type(def) == UPB_DEF_MSG) { const upb_msgdef *msgdef = upb_downcast_msgdef(def); - zval *desc_php = get_def_obj(msgdef); + PHP_PROTO_HASHTABLE_VALUE desc_php = get_def_obj(msgdef); build_class_from_descriptor(desc_php TSRMLS_CC); } } @@ -397,111 +498,3 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { upb_filedef_unref(files[0], &pool); upb_gfree(files); } - -// ----------------------------------------------------------------------------- -// Descriptor -// ----------------------------------------------------------------------------- - -static zend_function_entry descriptor_methods[] = { - ZEND_FE_END -}; - -DEFINE_CLASS(Descriptor, descriptor, "Google\\Protobuf\\Internal\\Descriptor"); - -static void descriptor_free_c(Descriptor *self TSRMLS_DC) { - if (self->layout) { - free_layout(self->layout); - } - if (self->fill_handlers) { - upb_handlers_unref(self->fill_handlers, &self->fill_handlers); - } - if (self->fill_method) { - upb_pbdecodermethod_unref(self->fill_method, &self->fill_method); - } - if (self->json_fill_method) { - upb_json_parsermethod_unref(self->json_fill_method, - &self->json_fill_method); - } - if (self->pb_serialize_handlers) { - upb_handlers_unref(self->pb_serialize_handlers, - &self->pb_serialize_handlers); - } - if (self->json_serialize_handlers) { - upb_handlers_unref(self->json_serialize_handlers, - &self->json_serialize_handlers); - } - if (self->json_serialize_handlers_preserve) { - upb_handlers_unref(self->json_serialize_handlers_preserve, - &self->json_serialize_handlers_preserve); - } -} - -static void descriptor_init_c_instance(Descriptor *desc TSRMLS_DC) { - zend_object_std_init(&desc->std, descriptor_type TSRMLS_CC); - desc->msgdef = NULL; - desc->layout = NULL; - desc->klass = NULL; - desc->fill_handlers = NULL; - desc->fill_method = NULL; - desc->json_fill_method = NULL; - desc->pb_serialize_handlers = NULL; - desc->json_serialize_handlers = NULL; - desc->json_serialize_handlers_preserve = NULL; -} - -// ----------------------------------------------------------------------------- -// EnumDescriptor -// ----------------------------------------------------------------------------- - -static zend_function_entry enum_descriptor_methods[] = { - ZEND_FE_END -}; - -DEFINE_CLASS(EnumDescriptor, enum_descriptor, - "Google\\Protobuf\\Internal\\EnumDescriptor"); - -static void enum_descriptor_free_c(EnumDescriptor *self TSRMLS_DC) { -} - -static void enum_descriptor_init_c_instance(EnumDescriptor *self TSRMLS_DC) { - zend_object_std_init(&self->std, enum_descriptor_type TSRMLS_CC); - self->enumdef = NULL; - self->klass = NULL; -} - -// ----------------------------------------------------------------------------- -// FieldDescriptor -// ----------------------------------------------------------------------------- - -upb_fieldtype_t to_fieldtype(upb_descriptortype_t type) { - switch (type) { -#define CASE(descriptor_type, type) \ - case UPB_DESCRIPTOR_TYPE_##descriptor_type: \ - return UPB_TYPE_##type; - - CASE(FLOAT, FLOAT); - CASE(DOUBLE, DOUBLE); - CASE(BOOL, BOOL); - CASE(STRING, STRING); - CASE(BYTES, BYTES); - CASE(MESSAGE, MESSAGE); - CASE(GROUP, MESSAGE); - CASE(ENUM, ENUM); - CASE(INT32, INT32); - CASE(INT64, INT64); - CASE(UINT32, UINT32); - CASE(UINT64, UINT64); - CASE(SINT32, INT32); - CASE(SINT64, INT64); - CASE(FIXED32, UINT32); - CASE(FIXED64, UINT64); - CASE(SFIXED32, INT32); - CASE(SFIXED64, INT64); - -#undef CONVERT - - } - - zend_error(E_ERROR, "Unknown field type."); - return 0; -} diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index e5a5f307..06dc1195 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -197,19 +197,18 @@ static const void *newoneofhandlerdata(upb_handlers *h, static void *startseq_handler(void* closure, const void* hd) { MessageHeader* msg = closure; const size_t *ofs = hd; - return (void*)(*DEREF(msg, *ofs, zval**)); + return CACHED_PTR_TO_ZVAL_PTR(DEREF(message_data(msg), *ofs, CACHED_VALUE*)); } // Handlers that append primitive values to a repeated field. -#define DEFINE_APPEND_HANDLER(type, ctype) \ - static bool append##type##_handler(void* closure, const void* hd, \ - ctype val) { \ - zval* array = (zval*)closure; \ - TSRMLS_FETCH(); \ - RepeatedField* intern = \ - (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); \ - repeated_field_push_native(intern, &val TSRMLS_CC); \ - return true; \ +#define DEFINE_APPEND_HANDLER(type, ctype) \ + static bool append##type##_handler(void* closure, const void* hd, \ + ctype val) { \ + zval* array = (zval*)closure; \ + TSRMLS_FETCH(); \ + RepeatedField* intern = UNBOX(RepeatedField, array); \ + repeated_field_push_native(intern, &val); \ + return true; \ } DEFINE_APPEND_HANDLER(bool, bool) @@ -226,15 +225,19 @@ static void* appendstr_handler(void *closure, size_t size_hint) { zval* array = (zval*)closure; TSRMLS_FETCH(); - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); + RepeatedField* intern = UNBOX(RepeatedField, array); +#if PHP_MAJOR_VERSION < 7 zval* str; MAKE_STD_ZVAL(str); - ZVAL_STRING(str, "", 1); - - repeated_field_push_native(intern, &str TSRMLS_CC); + PHP_PROTO_ZVAL_STRING(str, "", 1); + repeated_field_push_native(intern, &str); return (void*)str; +#else + zend_string* str = zend_string_init("", 0, 1); + repeated_field_push_native(intern, &str); + return intern; +#endif } // Appends a 'bytes' string to a repeated field. @@ -243,24 +246,58 @@ static void* appendbytes_handler(void *closure, size_t size_hint) { zval* array = (zval*)closure; TSRMLS_FETCH(); - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); + RepeatedField* intern = UNBOX(RepeatedField, array); +#if PHP_MAJOR_VERSION < 7 zval* str; MAKE_STD_ZVAL(str); - ZVAL_STRING(str, "", 1); - - repeated_field_push_native(intern, &str TSRMLS_CC); + PHP_PROTO_ZVAL_STRING(str, "", 1); + repeated_field_push_native(intern, &str); return (void*)str; +#else + zend_string* str = zend_string_init("", 0, 1); + repeated_field_push_native(intern, &str); + return intern; +#endif } + static bool int32_handler(void* closure, const void* hd, + int32_t val) { + MessageHeader* msg = (MessageHeader*)closure; + const size_t *ofs = hd; + DEREF(message_data(msg), *ofs, int32_t) = val; + return true; + } +// Handlers that append primitive values to a repeated field. +#define DEFINE_SINGULAR_HANDLER(type, ctype) \ + static bool type##_handler(void* closure, const void* hd, \ + ctype val) { \ + MessageHeader* msg = (MessageHeader*)closure; \ + const size_t *ofs = hd; \ + DEREF(message_data(msg), *ofs, ctype) = val; \ + return true; \ + } + +DEFINE_SINGULAR_HANDLER(bool, bool) +// DEFINE_SINGULAR_HANDLER(int32, int32_t) +DEFINE_SINGULAR_HANDLER(uint32, uint32_t) +DEFINE_SINGULAR_HANDLER(float, float) +DEFINE_SINGULAR_HANDLER(int64, int64_t) +DEFINE_SINGULAR_HANDLER(uint64, uint64_t) +DEFINE_SINGULAR_HANDLER(double, double) + +#undef DEFINE_SINGULAR_HANDLER + +#if PHP_MAJOR_VERSION < 7 static void *empty_php_string(zval** value_ptr) { SEPARATE_ZVAL_IF_NOT_REF(value_ptr); - zval* str = *value_ptr; - zval_dtor(str); - ZVAL_STRINGL(str, "", 0, 1); - return (void*)str; + return (void*)(*value_ptr); } +#else +static void *empty_php_string(zval* value_ptr) { + return value_ptr; +} +#endif // Sets a non-repeated string field in a message. static void* str_handler(void *closure, @@ -268,7 +305,7 @@ static void* str_handler(void *closure, size_t size_hint) { MessageHeader* msg = closure; const size_t *ofs = hd; - return empty_php_string(DEREF(msg, *ofs, zval**)); + return empty_php_string(DEREF(message_data(msg), *ofs, CACHED_VALUE*)); } // Sets a non-repeated 'bytes' field in a message. @@ -277,52 +314,73 @@ static void* bytes_handler(void *closure, size_t size_hint) { MessageHeader* msg = closure; const size_t *ofs = hd; - return empty_php_string(DEREF(msg, *ofs, zval**)); + return empty_php_string(DEREF(message_data(msg), *ofs, CACHED_VALUE*)); } static size_t stringdata_handler(void* closure, const void* hd, const char* str, size_t len, const upb_bufhandle* handle) { zval* php_str = (zval*)closure; +#if PHP_MAJOR_VERSION < 7 + // Oneof string/bytes fields may have NULL initial value, which doesn't need + // to be freed. + if (Z_TYPE_P(php_str) == IS_STRING && !IS_INTERNED(Z_STRVAL_P(php_str))) { + FREE(Z_STRVAL_P(php_str)); + } + ZVAL_STRINGL(php_str, str, len, 1); +#else + if (Z_TYPE_P(php_str) == IS_STRING) { + zend_string_release(Z_STR_P(php_str)); + } + ZVAL_NEW_STR(php_str, zend_string_init(str, len, 0)); +#endif + return len; +} - char* old_str = Z_STRVAL_P(php_str); - size_t old_len = Z_STRLEN_P(php_str); - assert(old_str != NULL); - - char* new_str = emalloc(old_len + len + 1); +#if PHP_MAJOR_VERSION >= 7 +static size_t zendstringdata_handler(void* closure, const void* hd, + const char* str, size_t len, + const upb_bufhandle* handle) { + RepeatedField* intern = (RepeatedField*)closure; - memcpy(new_str, old_str, old_len); - memcpy(new_str + old_len, str, len); - new_str[old_len + len] = 0; - FREE(old_str); + unsigned char memory[NATIVE_SLOT_MAX_SIZE]; + memset(memory, 0, NATIVE_SLOT_MAX_SIZE); + *(zend_string**)memory = zend_string_init(str, len, 0); - Z_STRVAL_P(php_str) = new_str; - Z_STRLEN_P(php_str) = old_len + len; + HashTable *ht = PHP_PROTO_HASH_OF(intern->array); + int index = zend_hash_num_elements(ht) - 1; + php_proto_zend_hash_index_update( + ht, index, memory, sizeof(zend_string*), NULL); return len; } +#endif // Appends a submessage to a repeated field. static void *appendsubmsg_handler(void *closure, const void *hd) { zval* array = (zval*)closure; TSRMLS_FETCH(); - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); + RepeatedField* intern = UNBOX(RepeatedField, array); const submsg_handlerdata_t *submsgdata = hd; - zval* subdesc_php = get_def_obj((void*)submsgdata->md); - Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC); + Descriptor* subdesc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj((void*)submsgdata->md)); zend_class_entry* subklass = subdesc->klass; MessageHeader* submsg; +#if PHP_MAJOR_VERSION < 7 zval* val = NULL; MAKE_STD_ZVAL(val); - Z_TYPE_P(val) = IS_OBJECT; - Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC); - - repeated_field_push_native(intern, &val TSRMLS_CC); + ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); + repeated_field_push_native(intern, &val); + submsg = UNBOX(MessageHeader, val); +#else + zend_object* obj = subklass->create_object(subklass TSRMLS_CC); + repeated_field_push_native(intern, &obj); + submsg = (MessageHeader*)((char*)obj - XtOffsetOf(MessageHeader, std)); +#endif + custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); - submsg = zend_object_store_get_object(val TSRMLS_CC); return submsg; } @@ -330,26 +388,35 @@ static void *appendsubmsg_handler(void *closure, const void *hd) { static void *submsg_handler(void *closure, const void *hd) { MessageHeader* msg = closure; const submsg_handlerdata_t* submsgdata = hd; - zval* subdesc_php = get_def_obj((void*)submsgdata->md); TSRMLS_FETCH(); - Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC); + Descriptor* subdesc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj((void*)submsgdata->md)); zend_class_entry* subklass = subdesc->klass; zval* submsg_php; MessageHeader* submsg; - if (Z_TYPE_P(*DEREF(msg, submsgdata->ofs, zval**)) == IS_NULL) { + if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(message_data(msg), submsgdata->ofs, + CACHED_VALUE*))) == IS_NULL) { +#if PHP_MAJOR_VERSION < 7 zval* val = NULL; MAKE_STD_ZVAL(val); - Z_TYPE_P(val) = IS_OBJECT; - Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC); - - zval_ptr_dtor(DEREF(msg, submsgdata->ofs, zval**)); - *DEREF(msg, submsgdata->ofs, zval**) = val; + ZVAL_OBJ(val, subklass->create_object(subklass TSRMLS_CC)); + MessageHeader* intern = UNBOX(MessageHeader, val); + custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); + php_proto_zval_ptr_dtor(*DEREF(message_data(msg), submsgdata->ofs, zval**)); + *DEREF(message_data(msg), submsgdata->ofs, zval**) = val; +#else + zend_object* obj = subklass->create_object(subklass TSRMLS_CC); + ZVAL_OBJ(DEREF(message_data(msg), submsgdata->ofs, zval*), obj); + MessageHeader* intern = UNBOX_HASHTABLE_VALUE(MessageHeader, obj); + custom_data_init(subklass, intern PHP_PROTO_TSRMLS_CC); +#endif } - submsg_php = *DEREF(msg, submsgdata->ofs, zval**); + submsg_php = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), submsgdata->ofs, CACHED_VALUE*)); - submsg = zend_object_store_get_object(submsg_php TSRMLS_CC); + submsg = UNBOX(MessageHeader, submsg_php); return submsg; } @@ -372,32 +439,52 @@ typedef struct { // submessage. When the submessage ends, another handler is called to insert the // value into the map. typedef struct { - zval* map; char key_storage[NATIVE_SLOT_MAX_SIZE]; char value_storage[NATIVE_SLOT_MAX_SIZE]; -} map_parse_frame_t; +} map_parse_frame_data_t; -static void map_slot_init(void* memory, upb_fieldtype_t type) { +PHP_PROTO_WRAP_OBJECT_START(map_parse_frame_t) + map_parse_frame_data_t* data; // Place needs to be consistent with + // MessageHeader. + zval* map; + // In php7, we cannot allocate zval dynamically. So we need to add zval here + // to help decoding. + zval key_zval; + zval value_zval; +PHP_PROTO_WRAP_OBJECT_END +typedef struct map_parse_frame_t map_parse_frame_t; + +static void map_slot_init(void* memory, upb_fieldtype_t type, zval* cache) { switch (type) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { +#if PHP_MAJOR_VERSION < 7 // Store zval** in memory in order to be consistent with the layout of // singular fields. zval** holder = ALLOC(zval*); zval* tmp; MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, "", 0, 1); + PHP_PROTO_ZVAL_STRINGL(tmp, "", 0, 1); *holder = tmp; *(zval***)memory = holder; +#else + *(zval**)memory = cache; + PHP_PROTO_ZVAL_STRINGL(*(zval**)memory, "", 0, 1); +#endif break; } case UPB_TYPE_MESSAGE: { +#if PHP_MAJOR_VERSION < 7 zval** holder = ALLOC(zval*); zval* tmp; MAKE_STD_ZVAL(tmp); ZVAL_NULL(tmp); *holder = tmp; *(zval***)memory = holder; +#else + *(zval**)memory = cache; + ZVAL_NULL(*(zval**)memory); +#endif break; } default: @@ -410,9 +497,13 @@ static void map_slot_uninit(void* memory, upb_fieldtype_t type) { case UPB_TYPE_MESSAGE: case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { +#if PHP_MAJOR_VERSION < 7 zval** holder = *(zval***)memory; - zval_ptr_dtor(holder); + php_proto_zval_ptr_dtor(*holder); FREE(holder); +#else + php_proto_zval_ptr_dtor(*(zval**)memory); +#endif break; } default: @@ -424,7 +515,11 @@ static void map_slot_key(upb_fieldtype_t type, const void* from, const char** keyval, size_t* length) { if (type == UPB_TYPE_STRING) { +#if PHP_MAJOR_VERSION < 7 zval* key_php = **(zval***)from; +#else + zval* key_php = *(zval**)from; +#endif *keyval = Z_STRVAL_P(key_php); *length = Z_STRLEN_P(key_php); } else { @@ -444,6 +539,7 @@ static void map_slot_value(upb_fieldtype_t type, const void* from, memset(to, 0, native_slot_size(type)); switch (type) { +#if PHP_MAJOR_VERSION < 7 case UPB_TYPE_STRING: case UPB_TYPE_BYTES: case UPB_TYPE_MESSAGE: { @@ -451,6 +547,17 @@ static void map_slot_value(upb_fieldtype_t type, const void* from, Z_ADDREF_PP((zval**)to); break; } +#else + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + *(zend_string**)to = Z_STR_P(*(zval**)from); + zend_string_addref(*(zend_string**)to); + break; + case UPB_TYPE_MESSAGE: + *(zend_object**)to = Z_OBJ_P(*(zval**)from); + ++GC_REFCOUNT(*(zend_object**)to); + break; +#endif default: len = native_slot_size(type); memcpy(to, from, len); @@ -462,13 +569,17 @@ static void map_slot_value(upb_fieldtype_t type, const void* from, static void *startmapentry_handler(void *closure, const void *hd) { MessageHeader* msg = closure; const map_handlerdata_t* mapdata = hd; - zval* map = *DEREF(msg, mapdata->ofs, zval**); + zval* map = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), mapdata->ofs, CACHED_VALUE*)); map_parse_frame_t* frame = ALLOC(map_parse_frame_t); + frame->data = ALLOC(map_parse_frame_data_t); frame->map = map; - map_slot_init(&frame->key_storage, mapdata->key_field_type); - map_slot_init(&frame->value_storage, mapdata->value_field_type); + map_slot_init(&frame->data->key_storage, mapdata->key_field_type, + &frame->key_zval); + map_slot_init(&frame->data->value_storage, mapdata->value_field_type, + &frame->value_zval); return frame; } @@ -480,19 +591,20 @@ static bool endmap_handler(void* closure, const void* hd, upb_status* s) { const map_handlerdata_t* mapdata = hd; TSRMLS_FETCH(); - Map *map = (Map *)zend_object_store_get_object(frame->map TSRMLS_CC); + Map *map = UNBOX(Map, frame->map); const char* keyval = NULL; upb_value v; size_t length; - map_slot_key(map->key_type, &frame->key_storage, &keyval, &length); - map_slot_value(map->value_type, &frame->value_storage, &v); + map_slot_key(map->key_type, &frame->data->key_storage, &keyval, &length); + map_slot_value(map->value_type, &frame->data->value_storage, &v); map_index_set(map, keyval, length, v); - map_slot_uninit(&frame->key_storage, mapdata->key_field_type); - map_slot_uninit(&frame->value_storage, mapdata->value_field_type); + map_slot_uninit(&frame->data->key_storage, mapdata->key_field_type); + map_slot_uninit(&frame->data->value_storage, mapdata->value_field_type); + FREE(frame->data); FREE(frame); return true; @@ -528,14 +640,15 @@ static map_handlerdata_t* new_map_handlerdata( } // Handlers that set primitive values in oneofs. -#define DEFINE_ONEOF_HANDLER(type, ctype) \ - static bool oneof##type##_handler(void *closure, const void *hd, \ - ctype val) { \ - const oneof_handlerdata_t *oneofdata = hd; \ - DEREF(closure, oneofdata->case_ofs, uint32_t) = \ - oneofdata->oneof_case_num; \ - DEREF(closure, oneofdata->ofs, ctype) = val; \ - return true; \ +#define DEFINE_ONEOF_HANDLER(type, ctype) \ + static bool oneof##type##_handler(void* closure, const void* hd, \ + ctype val) { \ + const oneof_handlerdata_t* oneofdata = hd; \ + MessageHeader* msg = (MessageHeader*)closure; \ + DEREF(message_data(closure), oneofdata->case_ofs, uint32_t) = \ + oneofdata->oneof_case_num; \ + DEREF(message_data(closure), oneofdata->ofs, ctype) = val; \ + return true; \ } DEFINE_ONEOF_HANDLER(bool, bool) @@ -548,74 +661,71 @@ DEFINE_ONEOF_HANDLER(double, double) #undef DEFINE_ONEOF_HANDLER -// Handlers for strings in a oneof. -static void *oneofstr_handler(void *closure, - const void *hd, - size_t size_hint) { - MessageHeader* msg = closure; - const oneof_handlerdata_t *oneofdata = hd; - - DEREF(msg, oneofdata->case_ofs, uint32_t) = - oneofdata->oneof_case_num; - DEREF(msg, oneofdata->ofs, zval**) = - &(msg->std.properties_table)[oneofdata->property_ofs]; - - return empty_php_string(DEREF(msg, oneofdata->ofs, zval**)); -} - +// Handlers for string/bytes in a oneof. static void *oneofbytes_handler(void *closure, const void *hd, size_t size_hint) { MessageHeader* msg = closure; const oneof_handlerdata_t *oneofdata = hd; - DEREF(msg, oneofdata->case_ofs, uint32_t) = + DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num; - DEREF(msg, oneofdata->ofs, zval**) = + DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) = &(msg->std.properties_table)[oneofdata->property_ofs]; + return empty_php_string(DEREF( + message_data(msg), oneofdata->ofs, CACHED_VALUE*)); +} + +static void *oneofstr_handler(void *closure, + const void *hd, + size_t size_hint) { // TODO(teboring): Add it back. // rb_enc_associate(str, kRubyString8bitEncoding); - - SEPARATE_ZVAL_IF_NOT_REF(DEREF(msg, oneofdata->ofs, zval**)); - zval* str = *DEREF(msg, oneofdata->ofs, zval**); - zval_dtor(str); - ZVAL_STRINGL(str, "", 0, 1); - return (void*)str; + return oneofbytes_handler(closure, hd, size_hint); } // Handler for a submessage field in a oneof. static void* oneofsubmsg_handler(void* closure, const void* hd) { MessageHeader* msg = closure; const oneof_handlerdata_t *oneofdata = hd; - uint32_t oldcase = DEREF(msg, oneofdata->case_ofs, uint32_t); - zval* subdesc_php = get_def_obj((void*)oneofdata->md); + uint32_t oldcase = DEREF(message_data(msg), oneofdata->case_ofs, uint32_t); TSRMLS_FETCH(); - Descriptor* subdesc = zend_object_store_get_object(subdesc_php TSRMLS_CC); + Descriptor* subdesc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj((void*)oneofdata->md)); zend_class_entry* subklass = subdesc->klass; zval* submsg_php; MessageHeader* submsg; if (oldcase != oneofdata->oneof_case_num) { - DEREF(msg, oneofdata->ofs, zval**) = + // Ideally, we should clean up the old data. However, we don't even know the + // type of the old data. So, we will defer the desctruction of the old data + // to the time that containing message's destroyed or the same oneof field + // is accessed again and find that the old data hasn't been cleaned. + DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*) = &(msg->std.properties_table)[oneofdata->property_ofs]; - } - if (Z_TYPE_P(*DEREF(msg, oneofdata->ofs, zval**)) == IS_NULL) { - zval* val = NULL; - MAKE_STD_ZVAL(val); - Z_TYPE_P(val) = IS_OBJECT; - Z_OBJVAL_P(val) = subklass->create_object(subklass TSRMLS_CC); + // Old data was't cleaned when the oneof was accessed from another field. + if (Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF( + message_data(msg), oneofdata->ofs, CACHED_VALUE*))) != IS_NULL) { + php_proto_zval_ptr_dtor( + CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*))); + } - zval_ptr_dtor(DEREF(msg, oneofdata->ofs, zval**)); - *DEREF(msg, oneofdata->ofs, zval**) = val; + // Create new message. + ZVAL_OBJ(CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)), + subklass->create_object(subklass TSRMLS_CC)); } - DEREF(msg, oneofdata->case_ofs, uint32_t) = + DEREF(message_data(msg), oneofdata->case_ofs, uint32_t) = oneofdata->oneof_case_num; - submsg_php = *DEREF(msg, oneofdata->ofs, zval**); - submsg = zend_object_store_get_object(submsg_php TSRMLS_CC); + submsg_php = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), oneofdata->ofs, CACHED_VALUE*)); + submsg = UNBOX(MessageHeader, submsg_php); + custom_data_init(subklass, submsg PHP_PROTO_TSRMLS_CC); return submsg; } @@ -652,7 +762,11 @@ static void add_handlers_for_repeated_field(upb_handlers *h, upb_handlers_setstartstr(h, f, is_bytes ? appendbytes_handler : appendstr_handler, NULL); +#if PHP_MAJOR_VERSION < 7 upb_handlers_setstring(h, f, stringdata_handler, NULL); +#else + upb_handlers_setstring(h, f, zendstringdata_handler, NULL); +#endif break; } case UPB_TYPE_MESSAGE: { @@ -670,16 +784,26 @@ static void add_handlers_for_singular_field(upb_handlers *h, const upb_fielddef *f, size_t offset) { switch (upb_fielddef_type(f)) { - case UPB_TYPE_BOOL: - case UPB_TYPE_INT32: - case UPB_TYPE_UINT32: - case UPB_TYPE_ENUM: - case UPB_TYPE_FLOAT: - case UPB_TYPE_INT64: - case UPB_TYPE_UINT64: - case UPB_TYPE_DOUBLE: - upb_msg_setscalarhandler(h, f, offset, -1); - break; + +#define SET_HANDLER(utype, ltype) \ + case utype: { \ + upb_handlerattr attr = UPB_HANDLERATTR_INITIALIZER; \ + upb_handlerattr_sethandlerdata(&attr, newhandlerdata(h, offset)); \ + upb_handlers_set##ltype(h, f, ltype##_handler, &attr); \ + break; \ + } + + SET_HANDLER(UPB_TYPE_BOOL, bool); + SET_HANDLER(UPB_TYPE_INT32, int32); + SET_HANDLER(UPB_TYPE_UINT32, uint32); + SET_HANDLER(UPB_TYPE_ENUM, int32); + SET_HANDLER(UPB_TYPE_FLOAT, float); + SET_HANDLER(UPB_TYPE_INT64, int64); + SET_HANDLER(UPB_TYPE_UINT64, uint64); + SET_HANDLER(UPB_TYPE_DOUBLE, double); + +#undef SET_HANDLER + case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { bool is_bytes = upb_fielddef_type(f) == UPB_TYPE_BYTES; @@ -730,9 +854,11 @@ static void add_handlers_for_mapentry(const upb_msgdef* msgdef, upb_handlers* h, upb_handlers_setendmsg(h, endmap_handler, &attr); add_handlers_for_singular_field(h, key_field, - offsetof(map_parse_frame_t, key_storage)); + offsetof(map_parse_frame_data_t, + key_storage)); add_handlers_for_singular_field(h, value_field, - offsetof(map_parse_frame_t, value_storage)); + offsetof(map_parse_frame_data_t, + value_storage)); } // Set up handlers for a oneof field. @@ -787,8 +913,8 @@ static void add_handlers_for_message(const void* closure, upb_handlers* h) { const upb_msgdef* msgdef = upb_handlers_msgdef(h); TSRMLS_FETCH(); - Descriptor* desc = (Descriptor*)zend_object_store_get_object( - get_def_obj((void*)msgdef) TSRMLS_CC); + Descriptor* desc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj((void*)msgdef)); upb_msg_field_iter i; // If this is a mapentry message type, set up a special set of handlers and @@ -810,13 +936,11 @@ static void add_handlers_for_message(const void* closure, !upb_msg_field_done(&i); upb_msg_field_next(&i)) { const upb_fielddef *f = upb_msg_iter_field(&i); - size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + - sizeof(MessageHeader); + size_t offset = desc->layout->fields[upb_fielddef_index(f)].offset; if (upb_fielddef_containingoneof(f)) { size_t oneof_case_offset = - desc->layout->fields[upb_fielddef_index(f)].case_offset + - sizeof(MessageHeader); + desc->layout->fields[upb_fielddef_index(f)].case_offset; int property_cache_index = desc->layout->fields[upb_fielddef_index(f)].cache_index; add_handlers_for_oneof_field(h, f, offset, oneof_case_offset, @@ -883,6 +1007,8 @@ static const upb_json_parsermethod *msgdef_jsonparsermethod(Descriptor* desc) { static void putmsg(zval* msg, const Descriptor* desc, upb_sink* sink, int depth TSRMLS_DC); +static void putrawmsg(MessageHeader* msg, const Descriptor* desc, + upb_sink* sink, int depth TSRMLS_DC); static void putstr(zval* str, const upb_fielddef* f, upb_sink* sink); @@ -891,6 +1017,8 @@ static void putrawstr(const char* str, int len, const upb_fielddef* f, static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink, int depth TSRMLS_DC); +static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f, + upb_sink* sink, int depth TSRMLS_DC); static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, int depth TSRMLS_DC); @@ -933,8 +1061,14 @@ static void put_optional_value(const void* memory, int len, const upb_fielddef* putrawstr(memory, len, f, sink); break; case UPB_TYPE_MESSAGE: { - zval* submsg = *(zval**)memory; - putsubmsg(submsg, f, sink, depth TSRMLS_CC); +#if PHP_MAJOR_VERSION < 7 + MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); +#else + MessageHeader *submsg = + (MessageHeader*)((char*)(*(zend_object**)memory) - + XtOffsetOf(MessageHeader, std)); +#endif + putrawsubmsg(submsg, f, sink, depth TSRMLS_CC); break; } default: @@ -947,7 +1081,11 @@ static const char* raw_value(void* memory, const upb_fielddef* f) { switch (upb_fielddef_type(f)) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: +#if PHP_MAJOR_VERSION < 7 return Z_STRVAL_PP((zval**)memory); +#else + return ZSTR_VAL(*(zend_string**)memory); +#endif break; default: return memory; @@ -958,8 +1096,11 @@ static int raw_value_len(void* memory, int len, const upb_fielddef* f) { switch (upb_fielddef_type(f)) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: +#if PHP_MAJOR_VERSION < 7 return Z_STRLEN_PP((zval**)memory); - break; +#else + return ZSTR_LEN(*(zend_string**)memory); +#endif default: return len; } @@ -967,7 +1108,6 @@ static int raw_value_len(void* memory, int len, const upb_fielddef* f) { static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int depth TSRMLS_DC) { - Map* self; upb_sink subsink; const upb_fielddef* key_field; const upb_fielddef* value_field; @@ -975,8 +1115,7 @@ static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, int len, size; assert(map != NULL); - Map* intern = - (Map*)zend_object_store_get_object(map TSRMLS_CC); + Map* intern = UNBOX(Map, map); size = upb_strtable_count(&intern->table); if (size == 0) return; @@ -1013,6 +1152,12 @@ static void putmap(zval* map, const upb_fielddef* f, upb_sink* sink, static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, int depth TSRMLS_DC) { + MessageHeader* msg = UNBOX(MessageHeader, msg_php); + putrawmsg(msg, desc, sink, depth TSRMLS_CC); +} + +static void putrawmsg(MessageHeader* msg, const Descriptor* desc, + upb_sink* sink, int depth TSRMLS_DC) { upb_msg_field_iter i; upb_status status; @@ -1025,21 +1170,18 @@ static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, "Maximum recursion depth exceeded during encoding."); } - MessageHeader* msg = zend_object_store_get_object(msg_php TSRMLS_CC); - for (upb_msg_field_begin(&i, desc->msgdef); !upb_msg_field_done(&i); upb_msg_field_next(&i)) { upb_fielddef* f = upb_msg_iter_field(&i); - uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset + - sizeof(MessageHeader); + uint32_t offset = desc->layout->fields[upb_fielddef_index(f)].offset; if (upb_fielddef_containingoneof(f)) { uint32_t oneof_case_offset = - desc->layout->fields[upb_fielddef_index(f)].case_offset + - sizeof(MessageHeader); + desc->layout->fields[upb_fielddef_index(f)].case_offset; // For a oneof, check that this field is actually present -- skip all the // below if not. - if (DEREF(msg, oneof_case_offset, uint32_t) != upb_fielddef_number(f)) { + if (DEREF(message_data(msg), oneof_case_offset, uint32_t) != + upb_fielddef_number(f)) { continue; } // Otherwise, fall through to the appropriate singular-field handler @@ -1047,31 +1189,36 @@ static void putmsg(zval* msg_php, const Descriptor* desc, upb_sink* sink, } if (is_map_field(f)) { - zval* map = *DEREF(msg, offset, zval**); + zval* map = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), offset, CACHED_VALUE*)); if (map != NULL) { putmap(map, f, sink, depth TSRMLS_CC); } } else if (upb_fielddef_isseq(f)) { - zval* array = *DEREF(msg, offset, zval**); + zval* array = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), offset, CACHED_VALUE*)); if (array != NULL) { putarray(array, f, sink, depth TSRMLS_CC); } } else if (upb_fielddef_isstring(f)) { - zval* str = *DEREF(msg, offset, zval**); + zval* str = CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), offset, CACHED_VALUE*)); if (Z_STRLEN_P(str) > 0) { putstr(str, f, sink); } } else if (upb_fielddef_issubmsg(f)) { - putsubmsg(*DEREF(msg, offset, zval**), f, sink, depth TSRMLS_CC); + putsubmsg(CACHED_PTR_TO_ZVAL_PTR( + DEREF(message_data(msg), offset, CACHED_VALUE*)), + f, sink, depth TSRMLS_CC); } else { upb_selector_t sel = getsel(f, upb_handlers_getprimitivehandlertype(f)); -#define T(upbtypeconst, upbtype, ctype, default_value) \ - case upbtypeconst: { \ - ctype value = DEREF(msg, offset, ctype); \ - if (value != default_value) { \ - upb_sink_put##upbtype(sink, sel, value); \ - } \ +#define T(upbtypeconst, upbtype, ctype, default_value) \ + case upbtypeconst: { \ + ctype value = DEREF(message_data(msg), offset, ctype); \ + if (value != default_value) { \ + upb_sink_put##upbtype(sink, sel, value); \ + } \ } break; switch (upb_fielddef_type(f)) { @@ -1138,18 +1285,23 @@ static void putrawstr(const char* str, int len, const upb_fielddef* f, upb_sink_endstr(sink, getsel(f, UPB_HANDLER_ENDSTR)); } -static void putsubmsg(zval* submsg, const upb_fielddef* f, upb_sink* sink, +static void putsubmsg(zval* submsg_php, const upb_fielddef* f, upb_sink* sink, int depth TSRMLS_DC) { - upb_sink subsink; + if (Z_TYPE_P(submsg_php) == IS_NULL) return; + + MessageHeader *submsg = UNBOX(MessageHeader, submsg_php); + putrawsubmsg(submsg, f, sink, depth TSRMLS_CC); +} - if (Z_TYPE_P(submsg) == IS_NULL) return; +static void putrawsubmsg(MessageHeader* submsg, const upb_fielddef* f, + upb_sink* sink, int depth TSRMLS_DC) { + upb_sink subsink; - zval* php_descriptor = get_def_obj(upb_fielddef_msgsubdef(f)); Descriptor* subdesc = - (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(upb_fielddef_msgsubdef(f))); upb_sink_startsubmsg(sink, getsel(f, UPB_HANDLER_STARTSUBMSG), &subsink); - putmsg(submsg, subdesc, &subsink, depth + 1 TSRMLS_CC); + putrawmsg(submsg, subdesc, &subsink, depth + 1 TSRMLS_CC); upb_sink_endsubmsg(sink, getsel(f, UPB_HANDLER_ENDSUBMSG)); } @@ -1161,9 +1313,10 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, int size, i; assert(array != NULL); - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(array TSRMLS_CC); - size = zend_hash_num_elements(HASH_OF(intern->array)); + RepeatedField* intern = UNBOX(RepeatedField, array); + HashTable *ht = PHP_PROTO_HASH_OF(intern->array); + size = zend_hash_num_elements(ht); + // size = zend_hash_num_elements(PHP_PROTO_HASH_OF(intern->array)); if (size == 0) return; upb_sink_startseq(sink, getsel(f, UPB_HANDLER_STARTSEQ), &subsink); @@ -1190,12 +1343,28 @@ static void putarray(zval* array, const upb_fielddef* f, upb_sink* sink, T(UPB_TYPE_UINT64, uint64, uint64_t) case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - putstr(*((zval**)memory), f, &subsink); + case UPB_TYPE_BYTES: { +#if PHP_MAJOR_VERSION < 7 + const char* rawstr = Z_STRVAL_P(*(zval**)memory); + int len = Z_STRLEN_P(*(zval**)memory); +#else + const char* rawstr = ZSTR_VAL(*(zend_string**)memory); + int len = ZSTR_LEN(*(zend_string**)memory); +#endif + putrawstr(rawstr, len, f, &subsink); break; - case UPB_TYPE_MESSAGE: - putsubmsg(*((zval**)memory), f, &subsink, depth TSRMLS_CC); + } + case UPB_TYPE_MESSAGE: { +#if PHP_MAJOR_VERSION < 7 + MessageHeader *submsg = UNBOX(MessageHeader, *(zval**)memory); +#else + MessageHeader *submsg = + (MessageHeader*)((char*)(*(zend_object**)memory) - + XtOffsetOf(MessageHeader, std)); +#endif + putrawsubmsg(submsg, f, &subsink, depth TSRMLS_CC); break; + } #undef T } @@ -1235,9 +1404,8 @@ static const upb_handlers* msgdef_json_serialize_handlers( // ----------------------------------------------------------------------------- PHP_METHOD(Message, serializeToString) { - zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = - (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); + UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis()))); stringsink sink; stringsink_init(&sink); @@ -1253,7 +1421,7 @@ PHP_METHOD(Message, serializeToString) { putmsg(getThis(), desc, upb_pb_encoder_input(encoder), 0 TSRMLS_CC); - RETVAL_STRINGL(sink.ptr, sink.len, 1); + PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1); stackenv_uninit(&se); stringsink_uninit(&sink); @@ -1261,13 +1429,12 @@ PHP_METHOD(Message, serializeToString) { } PHP_METHOD(Message, mergeFromString) { - zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = - (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); - MessageHeader* msg = zend_object_store_get_object(getThis() TSRMLS_CC); + UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis()))); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); char *data = NULL; - int data_len; + PHP_PROTO_SIZE data_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) { return; @@ -1290,9 +1457,8 @@ PHP_METHOD(Message, mergeFromString) { } PHP_METHOD(Message, jsonEncode) { - zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = - (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); + UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis()))); zend_bool preserve_proto_fieldnames = false; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", @@ -1314,7 +1480,7 @@ PHP_METHOD(Message, jsonEncode) { putmsg(getThis(), desc, upb_json_printer_input(printer), 0 TSRMLS_CC); - RETVAL_STRINGL(sink.ptr, sink.len, 1); + PHP_PROTO_RETVAL_STRINGL(sink.ptr, sink.len, 1); stackenv_uninit(&se); stringsink_uninit(&sink); @@ -1322,10 +1488,9 @@ PHP_METHOD(Message, jsonEncode) { } PHP_METHOD(Message, jsonDecode) { - zval* php_descriptor = get_ce_obj(Z_OBJCE_P(getThis())); Descriptor* desc = - (Descriptor*)zend_object_store_get_object(php_descriptor TSRMLS_CC); - MessageHeader* msg = zend_object_store_get_object(getThis() TSRMLS_CC); + UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(Z_OBJCE_P(getThis()))); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); char *data = NULL; int data_len; diff --git a/php/ext/google/protobuf/map.c b/php/ext/google/protobuf/map.c index fae152e3..a5d48446 100644 --- a/php/ext/google/protobuf/map.c +++ b/php/ext/google/protobuf/map.c @@ -103,16 +103,16 @@ static bool table_key(Map* self, zval* key, *out_length = Z_STRLEN_P(key); break; -#define CASE_TYPE(upb_type, type, c_type, php_type) \ - case UPB_TYPE_##upb_type: { \ - c_type type##_value; \ - if (!protobuf_convert_to_##type(key, &type##_value)) { \ - return false; \ - } \ - native_slot_set(self->key_type, NULL, buf, key TSRMLS_CC); \ - *out_key = buf; \ - *out_length = native_slot_size(self->key_type); \ - break; \ +#define CASE_TYPE(upb_type, type, c_type, php_type) \ + case UPB_TYPE_##upb_type: { \ + c_type type##_value; \ + if (!protobuf_convert_to_##type(key, &type##_value)) { \ + return false; \ + } \ + native_slot_set_by_array(self->key_type, NULL, buf, key TSRMLS_CC); \ + *out_key = buf; \ + *out_length = native_slot_size(self->key_type); \ + break; \ } CASE_TYPE(BOOL, bool, int8_t, BOOL) CASE_TYPE(INT32, int32, int32_t, LONG) @@ -148,7 +148,7 @@ static zend_function_entry map_field_methods[] = { // Forward declare static functions. -static bool map_field_write_dimension(zval *object, zval *key, +static void map_field_write_dimension(zval *object, zval *key, zval *value TSRMLS_DC); // ----------------------------------------------------------------------------- @@ -163,8 +163,7 @@ static void map_begin_internal(Map *map, MapIter *iter) { upb_strtable_begin(&iter->it, &map->table); } -static HashTable *map_field_get_gc(zval *object, zval ***table, - int *n TSRMLS_DC) { +static HashTable *map_field_get_gc(zval *object, CACHED_VALUE **table, int *n) { // TODO(teboring): Unfortunately, zend engine does not support garbage // collection for custom array. We have to use zend engine's native array // instead. @@ -173,111 +172,101 @@ static HashTable *map_field_get_gc(zval *object, zval ***table, return NULL; } -void map_field_init(TSRMLS_D) { - zend_class_entry class_type; - const char* class_name = "Google\\Protobuf\\Internal\\MapField"; - INIT_CLASS_ENTRY_EX(class_type, class_name, strlen(class_name), - map_field_methods); - - map_field_type = zend_register_internal_class(&class_type TSRMLS_CC); - map_field_type->create_object = map_field_create; - - zend_class_implements(map_field_type TSRMLS_CC, 2, spl_ce_ArrayAccess, - spl_ce_Countable); - - map_field_handlers = PEMALLOC(zend_object_handlers); - memcpy(map_field_handlers, zend_get_std_object_handlers(), - sizeof(zend_object_handlers)); - map_field_handlers->write_dimension = map_field_write_dimension; - map_field_handlers->get_gc = map_field_get_gc; +// Define map value element free function. +#if PHP_MAJOR_VERSION < 7 +static inline void php_proto_map_string_release(void *value) { + zval_ptr_dtor(value); } -zend_object_value map_field_create(zend_class_entry *ce TSRMLS_DC) { - zend_object_value retval = {0}; - Map *intern; - - intern = emalloc(sizeof(Map)); - memset(intern, 0, sizeof(Map)); - - zend_object_std_init(&intern->std, ce TSRMLS_CC); - object_properties_init(&intern->std, ce); - - // Table value type is always UINT64: this ensures enough space to store the - // native_slot value. - if (!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64)) { - zend_error(E_USER_ERROR, "Could not allocate table."); +static inline void php_proto_map_object_release(void *value) { + zval_ptr_dtor(value); +} +#else +static inline void php_proto_map_string_release(void *value) { + zend_string* object = *(zend_string**)value; + zend_string_release(object); +} +static inline void php_proto_map_object_release(void *value) { + zend_object* object = *(zend_object**)value; + if(--GC_REFCOUNT(object) == 0) { + zend_objects_store_del(object); } - - retval.handle = zend_objects_store_put( - intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, - (zend_objects_free_object_storage_t)map_field_free, NULL TSRMLS_CC); - retval.handlers = map_field_handlers; - - return retval; } +#endif -void map_field_free(void *object TSRMLS_DC) { - Map *map = (Map *)object; - - switch (map->value_type) { +// Define object free method. +PHP_PROTO_OBJECT_FREE_START(Map, map_field) +MapIter it; +int len; +for (map_begin_internal(intern, &it); !map_done(&it); map_next(&it)) { + upb_value value = map_iter_value(&it, &len); + void *mem = upb_value_memory(&value); + switch (intern->value_type) { case UPB_TYPE_MESSAGE: + php_proto_map_object_release(mem); + break; case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - MapIter it; - int len; - for (map_begin_internal(map, &it); !map_done(&it); map_next(&it)) { - upb_value value = map_iter_value(&it, &len); - void *mem = upb_value_memory(&value); - zval_ptr_dtor(mem); - } + case UPB_TYPE_BYTES: + php_proto_map_string_release(mem); break; - } default: break; } - - upb_strtable_uninit(&map->table); - zend_object_std_dtor(&map->std TSRMLS_CC); - efree(object); } - -void map_field_create_with_field(zend_class_entry *ce, const upb_fielddef *field, - zval **map_field TSRMLS_DC) { +upb_strtable_uninit(&intern->table); +PHP_PROTO_OBJECT_FREE_END + +PHP_PROTO_OBJECT_DTOR_START(Map, map_field) +PHP_PROTO_OBJECT_DTOR_END + +// Define object create method. +PHP_PROTO_OBJECT_CREATE_START(Map, map_field) +// Table value type is always UINT64: this ensures enough space to store the +// native_slot value. +if (!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64)) { + zend_error(E_USER_ERROR, "Could not allocate table."); +} +PHP_PROTO_OBJECT_CREATE_END(Map, map_field) + +// Init class entry. +PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\MapField", Map, + map_field) +zend_class_implements(map_field_type TSRMLS_CC, 2, spl_ce_ArrayAccess, + spl_ce_Countable); +map_field_handlers->write_dimension = map_field_write_dimension; +map_field_handlers->get_gc = map_field_get_gc; +PHP_PROTO_INIT_CLASS_END + +void map_field_create_with_field(const zend_class_entry *ce, + const upb_fielddef *field, + CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) { const upb_fielddef *key_field = map_field_key(field); const upb_fielddef *value_field = map_field_value(field); map_field_create_with_type( ce, upb_fielddef_type(key_field), upb_fielddef_type(value_field), - field_type_class(value_field TSRMLS_CC), map_field TSRMLS_CC); + field_type_class(value_field TSRMLS_CC), map_field PHP_PROTO_TSRMLS_CC); } -void map_field_create_with_type(zend_class_entry *ce, upb_fieldtype_t key_type, +void map_field_create_with_type(const zend_class_entry *ce, + upb_fieldtype_t key_type, upb_fieldtype_t value_type, const zend_class_entry *msg_ce, - zval **map_field TSRMLS_DC) { - MAKE_STD_ZVAL(*map_field); - Z_TYPE_PP(map_field) = IS_OBJECT; - Z_OBJVAL_PP(map_field) = - map_field_type->create_object(map_field_type TSRMLS_CC); - - Map* intern = - (Map*)zend_object_store_get_object(*map_field TSRMLS_CC); - + CACHED_VALUE *map_field PHP_PROTO_TSRMLS_DC) { + CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(CACHED_PTR_TO_ZVAL_PTR(map_field), + map_field_type); + Map *intern = UNBOX(Map, CACHED_TO_ZVAL_PTR(*map_field)); intern->key_type = key_type; intern->value_type = value_type; intern->msg_ce = msg_ce; } -static void map_field_free_element(void *object) { -} - // ----------------------------------------------------------------------------- // MapField Handlers // ----------------------------------------------------------------------------- static bool map_field_read_dimension(zval *object, zval *key, int type, - zval **retval TSRMLS_DC) { - Map *intern = - (Map *)zend_object_store_get_object(object TSRMLS_CC); + CACHED_VALUE *retval TSRMLS_DC) { + Map *intern = UNBOX(Map, object); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; @@ -292,7 +281,7 @@ static bool map_field_read_dimension(zval *object, zval *key, int type, if (upb_strtable_lookup2(&intern->table, keyval, length, &v)) { void* mem = upb_value_memory(&v); - native_slot_get(intern->value_type, mem, retval TSRMLS_CC); + native_slot_get_by_array(intern->value_type, mem, retval TSRMLS_CC); return true; } else { zend_error(E_USER_ERROR, "Given key doesn't exist."); @@ -310,9 +299,9 @@ bool map_index_set(Map *intern, const char* keyval, int length, upb_value v) { return true; } -static bool map_field_write_dimension(zval *object, zval *key, +static void map_field_write_dimension(zval *object, zval *key, zval *value TSRMLS_DC) { - Map *intern = (Map *)zend_object_store_get_object(object TSRMLS_CC); + Map *intern = UNBOX(Map, object); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; @@ -320,14 +309,14 @@ static bool map_field_write_dimension(zval *object, zval *key, upb_value v; void* mem; if (!table_key(intern, key, keybuf, &keyval, &length TSRMLS_CC)) { - return false; + return; } mem = upb_value_memory(&v); memset(mem, 0, native_slot_size(intern->value_type)); - if (!native_slot_set(intern->value_type, intern->msg_ce, mem, - value TSRMLS_CC)) { - return false; + if (!native_slot_set_by_array(intern->value_type, intern->msg_ce, mem, + value TSRMLS_CC)) { + return; } #ifndef NDEBUG v.ctype = UPB_CTYPE_UINT64; @@ -337,14 +326,12 @@ static bool map_field_write_dimension(zval *object, zval *key, upb_strtable_remove2(&intern->table, keyval, length, NULL); if (!upb_strtable_insert2(&intern->table, keyval, length, v)) { zend_error(E_USER_ERROR, "Could not insert into table"); - return false; + return; } - - return true; } static bool map_field_unset_dimension(zval *object, zval *key TSRMLS_DC) { - Map *intern = (Map *)zend_object_store_get_object(object TSRMLS_CC); + Map *intern = UNBOX(Map, object); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; @@ -375,8 +362,7 @@ PHP_METHOD(MapField, __construct) { return; } - Map* intern = - (Map*)zend_object_store_get_object(getThis() TSRMLS_CC); + Map *intern = UNBOX(Map, getThis()); intern->key_type = to_fieldtype(key_type); intern->value_type = to_fieldtype(value_type); intern->msg_ce = klass; @@ -404,7 +390,7 @@ PHP_METHOD(MapField, offsetExists) { return; } - Map *intern = (Map *)zend_object_store_get_object(getThis() TSRMLS_CC); + Map *intern = UNBOX(Map, getThis()); char keybuf[TABLE_KEY_BUF_LENGTH]; const char* keyval = NULL; @@ -427,7 +413,7 @@ PHP_METHOD(MapField, offsetGet) { return; } map_field_read_dimension(getThis(), index, BP_VAR_R, - return_value_ptr TSRMLS_CC); + ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); } PHP_METHOD(MapField, offsetSet) { @@ -449,8 +435,7 @@ PHP_METHOD(MapField, offsetUnset) { } PHP_METHOD(MapField, count) { - Map *intern = - (Map *)zend_object_store_get_object(getThis() TSRMLS_CC); + Map *intern = UNBOX(Map, getThis()); if (zend_parse_parameters_none() == FAILURE) { return; diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c index 59ce6ae6..cabc3987 100644 --- a/php/ext/google/protobuf/message.c +++ b/php/ext/google/protobuf/message.c @@ -53,40 +53,64 @@ static zend_function_entry message_methods[] = { // Forward declare static functions. +#if PHP_MAJOR_VERSION < 7 static void message_set_property(zval* object, zval* member, zval* value, - const zend_literal* key TSRMLS_DC); + php_proto_zend_literal key TSRMLS_DC); static zval* message_get_property(zval* object, zval* member, int type, const zend_literal* key TSRMLS_DC); static zval** message_get_property_ptr_ptr(zval* object, zval* member, int type, - const zend_literal* key TSRMLS_DC); -static HashTable* message_get_properties(zval* object TSRMLS_DC); + php_proto_zend_literal key TSRMLS_DC); static HashTable* message_get_gc(zval* object, zval*** table, int* n TSRMLS_DC); - -static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC); -static void message_free(void* object TSRMLS_DC); +#else +static void message_set_property(zval* object, zval* member, zval* value, + void** cache_slot); +static zval* message_get_property(zval* object, zval* member, int type, + void** cache_slot, zval* rv); +static zval* message_get_property_ptr_ptr(zval* object, zval* member, int type, + void** cache_slot); +static HashTable* message_get_gc(zval* object, zval** table, int* n); +#endif +static HashTable* message_get_properties(zval* object TSRMLS_DC); // ----------------------------------------------------------------------------- // PHP Message Handlers // ----------------------------------------------------------------------------- -void message_init(TSRMLS_D) { - zend_class_entry class_type; - INIT_CLASS_ENTRY(class_type, "Google\\Protobuf\\Internal\\Message", - message_methods); - message_type = zend_register_internal_class(&class_type TSRMLS_CC); - - message_handlers = PEMALLOC(zend_object_handlers); - memcpy(message_handlers, zend_get_std_object_handlers(), - sizeof(zend_object_handlers)); +// Define object free method. +PHP_PROTO_OBJECT_FREE_START(MessageHeader, message) + FREE(intern->data); +PHP_PROTO_OBJECT_FREE_END + +PHP_PROTO_OBJECT_DTOR_START(MessageHeader, message) +PHP_PROTO_OBJECT_DTOR_END + +// Define object create method. +PHP_PROTO_OBJECT_CREATE_START(MessageHeader, message) +// Because php call this create func before calling the sub-message's +// constructor defined in PHP, it's possible that the decriptor of this class +// hasn't been added to descritpor pool (when the class is first +// instantiated). In that case, we will defer the initialization of the custom +// data to the parent Message's constructor, which will be called by +// sub-message's constructors after the descriptor has been added. +PHP_PROTO_OBJECT_CREATE_END(MessageHeader, message) + +// Init class entry. +PHP_PROTO_INIT_CLASS_START("Google\\Protobuf\\Internal\\Message", + MessageHeader, message) message_handlers->write_property = message_set_property; message_handlers->read_property = message_get_property; message_handlers->get_property_ptr_ptr = message_get_property_ptr_ptr; message_handlers->get_properties = message_get_properties; message_handlers->get_gc = message_get_gc; -} +PHP_PROTO_INIT_CLASS_END +#if PHP_MAJOR_VERSION < 7 static void message_set_property(zval* object, zval* member, zval* value, - const zend_literal* key TSRMLS_DC) { + php_proto_zend_literal key TSRMLS_DC) { +#else +static void message_set_property(zval* object, zval* member, zval* value, + void** cache_slot) { +#endif if (Z_TYPE_P(member) != IS_STRING) { zend_error(E_USER_ERROR, "Unexpected type for field name"); return; @@ -100,7 +124,7 @@ static void message_set_property(zval* object, zval* member, zval* value, const upb_fielddef* field; - MessageHeader* self = zend_object_store_get_object(object TSRMLS_CC); + MessageHeader* self = UNBOX(MessageHeader, object); field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member)); if (field == NULL) { @@ -110,46 +134,55 @@ static void message_set_property(zval* object, zval* member, zval* value, layout_set(self->descriptor->layout, self, field, value TSRMLS_CC); } +#if PHP_MAJOR_VERSION < 7 static zval* message_get_property(zval* object, zval* member, int type, const zend_literal* key TSRMLS_DC) { +#else +static zval* message_get_property(zval* object, zval* member, int type, + void** cache_slot, zval* rv) { +#endif if (Z_TYPE_P(member) != IS_STRING) { zend_error(E_USER_ERROR, "Property name has to be a string."); - return EG(uninitialized_zval_ptr); + return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; } if (Z_OBJCE_P(object) != EG(scope)) { // User cannot get property directly (e.g., $a = $m->a) zend_error(E_USER_ERROR, "Cannot access private property."); - return EG(uninitialized_zval_ptr); + return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; } - zend_property_info* property_info = NULL; - - // All properties should have been declared in the generated code and have - // corresponding zvals in properties_table. - ulong h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); - if (zend_hash_quick_find(&Z_OBJCE_P(object)->properties_info, - Z_STRVAL_P(member), Z_STRLEN_P(member) + 1, h, - (void**)&property_info) != SUCCESS) { - zend_error(E_USER_ERROR, "Property does not exist."); - return EG(uninitialized_zval_ptr); - } - - MessageHeader* self = - (MessageHeader*)zend_object_store_get_object(object TSRMLS_CC); - + MessageHeader* self = UNBOX(MessageHeader, object); const upb_fielddef* field; field = upb_msgdef_ntofz(self->descriptor->msgdef, Z_STRVAL_P(member)); if (field == NULL) { - return EG(uninitialized_zval_ptr); + return PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL; } + + zend_property_info* property_info; +#if PHP_MAJOR_VERSION < 7 + property_info = + zend_get_property_info(Z_OBJCE_P(object), member, true TSRMLS_CC); return layout_get( self->descriptor->layout, message_data(self), field, &Z_OBJ_P(object)->properties_table[property_info->offset] TSRMLS_CC); +#else + property_info = + zend_get_property_info(Z_OBJCE_P(object), Z_STR_P(member), true); + return layout_get( + self->descriptor->layout, message_data(self), field, + OBJ_PROP(Z_OBJ_P(object), property_info->offset) TSRMLS_CC); +#endif } +#if PHP_MAJOR_VERSION < 7 static zval** message_get_property_ptr_ptr(zval* object, zval* member, int type, - const zend_literal* key TSRMLS_DC) { + php_proto_zend_literal key + TSRMLS_DC) { +#else +static zval* message_get_property_ptr_ptr(zval* object, zval* member, int type, + void** cache_slot) { +#endif return NULL; } @@ -157,68 +190,37 @@ static HashTable* message_get_properties(zval* object TSRMLS_DC) { return NULL; } -static HashTable* message_get_gc(zval* object, zval*** table, int* n TSRMLS_DC) { - zend_object* zobj = Z_OBJ_P(object); - *table = zobj->properties_table; - *n = zobj->ce->default_properties_count; - return NULL; +static HashTable* message_get_gc(zval* object, CACHED_VALUE** table, + int* n TSRMLS_DC) { + zend_object* zobj = Z_OBJ_P(object); + *table = zobj->properties_table; + *n = zobj->ce->default_properties_count; + return NULL; } // ----------------------------------------------------------------------------- // C Message Utilities // ----------------------------------------------------------------------------- -void* message_data(void* msg) { - return ((uint8_t*)msg) + sizeof(MessageHeader); +void* message_data(MessageHeader* msg) { + return msg->data; } -static void message_free(void* object TSRMLS_DC) { - MessageHeader* msg = (MessageHeader*)object; - int i; - - for (i = 0; i < msg->std.ce->default_properties_count; i++) { - zval_ptr_dtor(&msg->std.properties_table[i]); - } - efree(msg->std.properties_table); - efree(msg); -} - -static zend_object_value message_create(zend_class_entry* ce TSRMLS_DC) { - zend_object_value return_value; - - zval* php_descriptor = get_ce_obj(ce); - - Descriptor* desc = zend_object_store_get_object(php_descriptor TSRMLS_CC); - MessageHeader* msg = (MessageHeader*)ALLOC_N( - uint8_t, sizeof(MessageHeader) + desc->layout->size); - memset(message_data(msg), 0, desc->layout->size); - +void custom_data_init(const zend_class_entry* ce, + MessageHeader* intern PHP_PROTO_TSRMLS_DC) { + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_ce_obj(ce)); + intern->data = ALLOC_N(uint8_t, desc->layout->size); + memset(message_data(intern), 0, desc->layout->size); // We wrap first so that everything in the message object is GC-rooted in // case a collection happens during object creation in layout_init(). - msg->descriptor = desc; - - zend_object_std_init(&msg->std, ce TSRMLS_CC); - object_properties_init(&msg->std, ce); - layout_init(desc->layout, message_data(msg), - msg->std.properties_table TSRMLS_CC); - - return_value.handle = zend_objects_store_put( - msg, (zend_objects_store_dtor_t)zend_objects_destroy_object, message_free, - NULL TSRMLS_CC); - - return_value.handlers = message_handlers; - return return_value; + intern->descriptor = desc; + layout_init(desc->layout, message_data(intern), + intern->std.properties_table PHP_PROTO_TSRMLS_CC); } -void message_create_with_type(zend_class_entry* ce, zval** message TSRMLS_DC) { - MAKE_STD_ZVAL(*message); - Z_TYPE_PP(message) = IS_OBJECT; - Z_OBJVAL_PP(message) = ce->create_object(ce TSRMLS_CC); - Z_DELREF_PP(message); -} - -void build_class_from_descriptor(zval* php_descriptor TSRMLS_DC) { - Descriptor* desc = UNBOX(Descriptor, php_descriptor); +void build_class_from_descriptor( + PHP_PROTO_HASHTABLE_VALUE php_descriptor TSRMLS_DC) { + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, php_descriptor); // Map entries don't have existing php class. if (upb_msgdef_mapentry(desc->msgdef)) { @@ -243,26 +245,18 @@ void build_class_from_descriptor(zval* php_descriptor TSRMLS_DC) { // modified. As a result, the first created instance will be a normal zend // object. Here, we manually modify it to our message in such a case. PHP_METHOD(Message, __construct) { - if (Z_OBJVAL_P(getThis()).handlers != message_handlers) { - zend_class_entry* ce = Z_OBJCE_P(getThis()); - zval_dtor(getThis()); - Z_OBJVAL_P(getThis()) = message_create(ce TSRMLS_CC); + zend_class_entry* ce = Z_OBJCE_P(getThis()); + if (EXPECTED(class_added(ce))) { + MessageHeader* intern = UNBOX(MessageHeader, getThis()); + custom_data_init(ce, intern PHP_PROTO_TSRMLS_CC); } } PHP_METHOD(Message, clear) { - MessageHeader* msg = - (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); Descriptor* desc = msg->descriptor; zend_class_entry* ce = desc->klass; - int i; - - for (i = 0; i < msg->std.ce->default_properties_count; i++) { - zval_ptr_dtor(&msg->std.properties_table[i]); - } - efree(msg->std.properties_table); - zend_object_std_init(&msg->std, ce TSRMLS_CC); object_properties_init(&msg->std, ce); layout_init(desc->layout, message_data(msg), msg->std.properties_table TSRMLS_CC); @@ -275,10 +269,8 @@ PHP_METHOD(Message, mergeFrom) { return; } - MessageHeader* from = - (MessageHeader*)zend_object_store_get_object(value TSRMLS_CC); - MessageHeader* to = - (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC); + MessageHeader* from = UNBOX(MessageHeader, value); + MessageHeader* to = UNBOX(MessageHeader, getThis()); if(from->descriptor != to->descriptor) { zend_error(E_USER_ERROR, "Cannot merge messages with different class."); @@ -289,36 +281,37 @@ PHP_METHOD(Message, mergeFrom) { } PHP_METHOD(Message, readOneof) { - long index; + PHP_PROTO_LONG index; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &index) == FAILURE) { return; } - MessageHeader* msg = - (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index); int property_cache_index = msg->descriptor->layout->fields[upb_fielddef_index(field)].cache_index; - zval** cache_ptr = &(msg->std.properties_table)[property_cache_index]; + zval* property_ptr = OBJ_PROP(Z_OBJ_P(getThis()), property_cache_index); + // Unlike singular fields, oneof fields share cached property. So we cannot + // let lay_get modify the cached property. Instead, we pass in the return + // value directly. layout_get(msg->descriptor->layout, message_data(msg), field, - &return_value TSRMLS_CC); + ZVAL_PTR_TO_CACHED_PTR(return_value) TSRMLS_CC); } PHP_METHOD(Message, writeOneof) { - long index; + PHP_PROTO_LONG index; zval* value; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &index, &value) == FAILURE) { return; } - MessageHeader* msg = - (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); const upb_fielddef* field = upb_msgdef_itof(msg->descriptor->msgdef, index); @@ -327,19 +320,18 @@ PHP_METHOD(Message, writeOneof) { PHP_METHOD(Message, whichOneof) { char* oneof_name; - int length; + PHP_PROTO_SIZE length; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &oneof_name, &length) == FAILURE) { return; } - MessageHeader* msg = - (MessageHeader*)zend_object_store_get_object(getThis() TSRMLS_CC); + MessageHeader* msg = UNBOX(MessageHeader, getThis()); const upb_oneofdef* oneof = upb_msgdef_ntoo(msg->descriptor->msgdef, oneof_name, length); const char* oneof_case_name = layout_get_oneof_case( msg->descriptor->layout, message_data(msg), oneof TSRMLS_CC); - RETURN_STRING(oneof_case_name, 1); + PHP_PROTO_RETURN_STRING(oneof_case_name, 1); } diff --git a/php/ext/google/protobuf/protobuf.c b/php/ext/google/protobuf/protobuf.c index ea85b999..6a848b27 100644 --- a/php/ext/google/protobuf/protobuf.c +++ b/php/ext/google/protobuf/protobuf.c @@ -55,39 +55,60 @@ static void add_to_table(HashTable* t, const void* def, void* value) { uint nIndex = (ulong)def & t->nTableMask; zval* pDest = NULL; - zend_hash_index_update(t, (zend_ulong)def, &value, sizeof(zval*), (void**)&pDest); + php_proto_zend_hash_index_update(t, (zend_ulong)def, &value, sizeof(zval*), + (void**)&pDest); } static void* get_from_table(const HashTable* t, const void* def) { void** value; - if (zend_hash_index_find(t, (zend_ulong)def, (void**)&value) == FAILURE) { + if (php_proto_zend_hash_index_find(t, (zend_ulong)def, (void**)&value) == + FAILURE) { zend_error(E_ERROR, "PHP object not found for given definition.\n"); return NULL; } return *value; } +static bool exist_in_table(const HashTable* t, const void* def) { + void** value; + return (php_proto_zend_hash_index_find(t, (zend_ulong)def, (void**)&value) == + SUCCESS); +} + static void add_to_list(HashTable* t, void* value) { zval* pDest = NULL; - zend_hash_next_index_insert(t, &value, sizeof(void*), (void**)&pDest); + php_proto_zend_hash_next_index_insert(t, &value, sizeof(void*), + (void**)&pDest); } -void add_def_obj(const void* def, zval* value) { +void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value) { +#if PHP_MAJOR_VERSION < 7 Z_ADDREF_P(value); +#else + ++GC_REFCOUNT(value); +#endif add_to_table(upb_def_to_php_obj_map, def, value); } -zval* get_def_obj(const void* def) { - return (zval*)get_from_table(upb_def_to_php_obj_map, def); +PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void* def) { + return (PHP_PROTO_HASHTABLE_VALUE)get_from_table(upb_def_to_php_obj_map, def); } -void add_ce_obj(const void* ce, zval* value) { +void add_ce_obj(const void* ce, PHP_PROTO_HASHTABLE_VALUE value) { +#if PHP_MAJOR_VERSION < 7 Z_ADDREF_P(value); +#else + ++GC_REFCOUNT(value); +#endif add_to_table(ce_to_php_obj_map, ce, value); } -zval* get_ce_obj(const void* ce) { - return (zval*)get_from_table(ce_to_php_obj_map, ce); +PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce) { + return (PHP_PROTO_HASHTABLE_VALUE)get_from_table(ce_to_php_obj_map, ce); +} + +bool class_added(const void* ce) { + return exist_in_table(ce_to_php_obj_map, ce); } // ----------------------------------------------------------------------------- @@ -125,12 +146,23 @@ static PHP_GINIT_FUNCTION(protobuf) { static PHP_GSHUTDOWN_FUNCTION(protobuf) { } +#if PHP_MAJOR_VERSION >= 7 +static void php_proto_hashtable_descriptor_release(zval* value) { + void* ptr = Z_PTR_P(value); + zend_object* object = *(zend_object**)ptr; + if(--GC_REFCOUNT(object) == 0) { + zend_objects_store_del(object); + } + efree(ptr); +} +#endif + static PHP_RINIT_FUNCTION(protobuf) { ALLOC_HASHTABLE(upb_def_to_php_obj_map); - zend_hash_init(upb_def_to_php_obj_map, 16, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(upb_def_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0); ALLOC_HASHTABLE(ce_to_php_obj_map); - zend_hash_init(ce_to_php_obj_map, 16, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(ce_to_php_obj_map, 16, NULL, HASHTABLE_VALUE_DTOR, 0); generated_pool = NULL; generated_pool_php = NULL; @@ -145,10 +177,12 @@ static PHP_RSHUTDOWN_FUNCTION(protobuf) { zend_hash_destroy(ce_to_php_obj_map); FREE_HASHTABLE(ce_to_php_obj_map); +#if PHP_MAJOR_VERSION < 7 if (generated_pool_php != NULL) { zval_dtor(generated_pool_php); FREE_ZVAL(generated_pool_php); } +#endif return 0; } @@ -170,6 +204,7 @@ static PHP_MINIT_FUNCTION(protobuf) { static PHP_MSHUTDOWN_FUNCTION(protobuf) { PEFREE(message_handlers); PEFREE(repeated_field_handlers); + PEFREE(repeated_field_iter_handlers); PEFREE(map_field_handlers); return 0; diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 2287f7e6..02f06f35 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -42,6 +42,323 @@ #define MAX_LENGTH_OF_INT64 20 #define SIZEOF_INT64 8 +// ----------------------------------------------------------------------------- +// PHP7 Wrappers +// ---------------------------------------------------------------------------- + +#if PHP_MAJOR_VERSION < 7 + +#define php_proto_zend_literal const zend_literal* +#define PHP_PROTO_CASE_IS_BOOL IS_BOOL +#define PHP_PROTO_SIZE int +#define PHP_PROTO_LONG long +#define PHP_PROTO_TSRMLS_DC TSRMLS_DC +#define PHP_PROTO_TSRMLS_CC TSRMLS_CC + +// PHP String + +#define PHP_PROTO_ZVAL_STRING(zval_ptr, s, copy) \ + ZVAL_STRING(zval_ptr, s, copy) +#define PHP_PROTO_ZVAL_STRINGL(zval_ptr, s, len, copy) \ + ZVAL_STRINGL(zval_ptr, s, len, copy) +#define PHP_PROTO_RETURN_STRING(s, copy) RETURN_STRING(s, copy) +#define PHP_PROTO_RETURN_STRINGL(s, len, copy) RETURN_STRINGL(s, len, copy) +#define PHP_PROTO_RETVAL_STRINGL(s, len, copy) RETVAL_STRINGL(s, len, copy) +#define php_proto_zend_make_printable_zval(from, to) \ + { \ + int use_copy; \ + zend_make_printable_zval(from, to, &use_copy); \ + } + +// PHP Array + +#define PHP_PROTO_HASH_OF(array) Z_ARRVAL_P(array) + +#define php_proto_zend_hash_index_update(ht, h, pData, nDataSize, pDest) \ + zend_hash_index_update(ht, h, pData, nDataSize, pDest) + +#define php_proto_zend_hash_index_find(ht, h, pDest) \ + zend_hash_index_find(ht, h, pDest) + +#define php_proto_zend_hash_next_index_insert(ht, pData, nDataSize, pDest) \ + zend_hash_next_index_insert(ht, pData, nDataSize, pDest) + +#define php_proto_zend_hash_get_current_data_ex(ht, pDest, pos) \ + zend_hash_get_current_data_ex(ht, pDest, pos) + +// PHP Object + +#define PHP_PROTO_WRAP_OBJECT_START(name) \ + struct name { \ + zend_object std; +#define PHP_PROTO_WRAP_OBJECT_END \ + }; + +#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ + void LOWWERNAME##_init(TSRMLS_D) { \ + zend_class_entry class_type; \ + const char* class_name = CLASSNAME; \ + INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ + LOWWERNAME##_methods); \ + LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ + LOWWERNAME##_type->create_object = LOWWERNAME##_create; \ + LOWWERNAME##_handlers = PEMALLOC(zend_object_handlers); \ + memcpy(LOWWERNAME##_handlers, zend_get_std_object_handlers(), \ + sizeof(zend_object_handlers)); +#define PHP_PROTO_INIT_CLASS_END \ + } + +#define PHP_PROTO_OBJECT_CREATE_START(NAME, LOWWERNAME) \ + static zend_object_value LOWWERNAME##_create( \ + zend_class_entry* ce TSRMLS_DC) { \ + PHP_PROTO_ALLOC_CLASS_OBJECT(NAME, ce); \ + zend_object_std_init(&intern->std, ce TSRMLS_CC); \ + object_properties_init(&intern->std, ce); +#define PHP_PROTO_OBJECT_CREATE_END(NAME, LOWWERNAME) \ + PHP_PROTO_FREE_CLASS_OBJECT(NAME, LOWWERNAME##_free, LOWWERNAME##_handlers); \ + } + +#define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \ + void lowername##_free(void* object TSRMLS_DC) { \ + classname* intern = object; +#define PHP_PROTO_OBJECT_FREE_END \ + zend_object_std_dtor(&intern->std TSRMLS_CC); \ + efree(intern); \ + } + +#define PHP_PROTO_OBJECT_DTOR_START(classname, lowername) +#define PHP_PROTO_OBJECT_DTOR_END + +#define CACHED_VALUE zval* +#define CACHED_TO_ZVAL_PTR(VALUE) (VALUE) +#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (*VALUE) +#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (&VALUE) + +#define CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(zval_ptr, class_type) \ + ZVAL_OBJ(zval_ptr, class_type->create_object(class_type TSRMLS_CC)); + +#define PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(value) \ + SEPARATE_ZVAL_IF_NOT_REF(value) + +#define PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL EG(uninitialized_zval_ptr) + +#define OBJ_PROP(PROPERTIES, OFFSET) (PROPERTIES)->properties_table[OFFSET] + +#define php_proto_zval_ptr_dtor(zval_ptr) \ + zval_ptr_dtor(&(zval_ptr)) + +#define PHP_PROTO_ALLOC_CLASS_OBJECT(class_object, class_type) \ + class_object* intern; \ + intern = (class_object*)emalloc(sizeof(class_object)); \ + memset(intern, 0, sizeof(class_object)); + +#define PHP_PROTO_FREE_CLASS_OBJECT(class_object, class_object_free, handler) \ + zend_object_value retval = {0}; \ + retval.handle = zend_objects_store_put( \ + intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, \ + class_object_free, NULL TSRMLS_CC); \ + retval.handlers = handler; \ + return retval; + +#define PHP_PROTO_ALLOC_ARRAY(zval_ptr) \ + ALLOC_HASHTABLE(Z_ARRVAL_P(zval_ptr)); \ + Z_TYPE_P(zval_ptr) = IS_ARRAY; + +#define ZVAL_OBJ(zval_ptr, call_create) \ + Z_TYPE_P(zval_ptr) = IS_OBJECT; \ + Z_OBJVAL_P(zval_ptr) = call_create; + +#define UNBOX(class_name, val) \ + (class_name*)zend_object_store_get_object(val TSRMLS_CC); + +#define UNBOX_HASHTABLE_VALUE(class_name, val) UNBOX(class_name, val) + +#define HASHTABLE_VALUE_DTOR ZVAL_PTR_DTOR + +#define PHP_PROTO_HASHTABLE_VALUE zval* + +#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \ + OBJ_TYPE* OBJ; \ + PHP_PROTO_HASHTABLE_VALUE WRAPPED_OBJ; \ + MAKE_STD_ZVAL(WRAPPED_OBJ); \ + ZVAL_OBJ(WRAPPED_OBJ, \ + OBJ_CLASS_ENTRY->create_object(OBJ_CLASS_ENTRY TSRMLS_CC)); \ + OBJ = UNBOX_HASHTABLE_VALUE(OBJ_TYPE, WRAPPED_OBJ); \ + Z_DELREF_P(desc_php); + +#define PHP_PROTO_CE_DECLARE zend_class_entry** +#define PHP_PROTO_CE_UNREF(ce) (*ce) + +#define php_proto_zend_lookup_class(name, name_length, ce) \ + zend_lookup_class(name, name_length, ce TSRMLS_CC) + +#else // PHP_MAJOR_VERSION >= 7 + +#define php_proto_zend_literal void** +#define PHP_PROTO_CASE_IS_BOOL IS_TRUE: case IS_FALSE +#define PHP_PROTO_SIZE size_t +#define PHP_PROTO_LONG zend_long +#define PHP_PROTO_TSRMLS_DC +#define PHP_PROTO_TSRMLS_CC + +// PHP String + +#define PHP_PROTO_ZVAL_STRING(zval_ptr, s, copy) \ + ZVAL_STRING(zval_ptr, s) +#define PHP_PROTO_ZVAL_STRINGL(zval_ptr, s, len, copy) \ + ZVAL_STRINGL(zval_ptr, s, len) +#define PHP_PROTO_RETURN_STRING(s, copy) RETURN_STRING(s) +#define PHP_PROTO_RETURN_STRINGL(s, len, copy) RETURN_STRINGL(s, len) +#define PHP_PROTO_RETVAL_STRINGL(s, len, copy) RETVAL_STRINGL(s, len) +#define php_proto_zend_make_printable_zval(from, to) \ + zend_make_printable_zval(from, to) + +// PHP Array + +#define PHP_PROTO_HASH_OF(array) Z_ARRVAL_P(&array) + +static inline int php_proto_zend_hash_index_update(HashTable* ht, ulong h, + void* pData, uint nDataSize, + void** pDest) { + void* result = NULL; + result = zend_hash_index_update_mem(ht, h, pData, nDataSize); + if (pDest != NULL) *pDest = result; + return result != NULL ? SUCCESS : FAILURE; +} + +static inline int php_proto_zend_hash_index_find(const HashTable* ht, ulong h, + void** pDest) { + void* result = NULL; + result = zend_hash_index_find_ptr(ht, h); + if (pDest != NULL) *pDest = result; + return result != NULL ? SUCCESS : FAILURE; +} + +static inline int php_proto_zend_hash_next_index_insert(HashTable* ht, + void* pData, + uint nDataSize, + void** pDest) { + void* result = NULL; + result = zend_hash_next_index_insert_mem(ht, pData, nDataSize); + if (pDest != NULL) *pDest = result; + return result != NULL ? SUCCESS : FAILURE; +} + +static inline int php_proto_zend_hash_get_current_data_ex(HashTable* ht, + void** pDest, + HashPosition* pos) { + void* result = NULL; + result = zend_hash_get_current_data_ex(ht, pos); + if (pDest != NULL) *pDest = result; + return result != NULL ? SUCCESS : FAILURE; +} + +// PHP Object + +#define PHP_PROTO_WRAP_OBJECT_START(name) struct name { +#define PHP_PROTO_WRAP_OBJECT_END \ + zend_object std; \ + }; + +#define PHP_PROTO_INIT_CLASS_START(CLASSNAME, CAMELNAME, LOWWERNAME) \ + void LOWWERNAME##_init(TSRMLS_D) { \ + zend_class_entry class_type; \ + const char* class_name = CLASSNAME; \ + INIT_CLASS_ENTRY_EX(class_type, CLASSNAME, strlen(CLASSNAME), \ + LOWWERNAME##_methods); \ + LOWWERNAME##_type = zend_register_internal_class(&class_type TSRMLS_CC); \ + LOWWERNAME##_type->create_object = LOWWERNAME##_create; \ + LOWWERNAME##_handlers = PEMALLOC(zend_object_handlers); \ + memcpy(LOWWERNAME##_handlers, zend_get_std_object_handlers(), \ + sizeof(zend_object_handlers)); \ + LOWWERNAME##_handlers->free_obj = LOWWERNAME##_free; \ + LOWWERNAME##_handlers->dtor_obj = LOWWERNAME##_dtor; \ + LOWWERNAME##_handlers->offset = XtOffsetOf(CAMELNAME, std); +#define PHP_PROTO_INIT_CLASS_END \ + } + +#define PHP_PROTO_OBJECT_FREE_START(classname, lowername) \ + void lowername##_free(zend_object* object) { \ + classname* intern = \ + (classname*)((char*)object - XtOffsetOf(classname, std)); +#define PHP_PROTO_OBJECT_FREE_END \ + } + +#define PHP_PROTO_OBJECT_DTOR_START(classname, lowername) \ + void lowername##_dtor(zend_object* object) { \ + classname* intern = \ + (classname*)((char*)object - XtOffsetOf(classname, std)); +#define PHP_PROTO_OBJECT_DTOR_END \ + zend_object_std_dtor(object TSRMLS_CC); \ + } + +#define PHP_PROTO_OBJECT_CREATE_START(NAME, LOWWERNAME) \ + static zend_object* LOWWERNAME##_create(zend_class_entry* ce TSRMLS_DC) { \ + PHP_PROTO_ALLOC_CLASS_OBJECT(NAME, ce); \ + zend_object_std_init(&intern->std, ce TSRMLS_CC); \ + object_properties_init(&intern->std, ce); +#define PHP_PROTO_OBJECT_CREATE_END(NAME, LOWWERNAME) \ + PHP_PROTO_FREE_CLASS_OBJECT(NAME, LOWWERNAME##_free, LOWWERNAME##_handlers); \ + } + +#define CACHED_VALUE zval +#define CACHED_TO_ZVAL_PTR(VALUE) (&VALUE) +#define CACHED_PTR_TO_ZVAL_PTR(VALUE) (VALUE) +#define ZVAL_PTR_TO_CACHED_PTR(VALUE) (VALUE) + +#define CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(zval_ptr, class_type) \ + ZVAL_OBJ(zval_ptr, class_type->create_object(class_type)); + +#define PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(value) ; + +#define PHP_PROTO_GLOBAL_UNINITIALIZED_ZVAL &EG(uninitialized_zval) + +#define php_proto_zval_ptr_dtor(zval_ptr) \ + zval_ptr_dtor(zval_ptr) + +#define PHP_PROTO_ALLOC_CLASS_OBJECT(class_object, class_type) \ + class_object* intern; \ + int size = sizeof(class_object) + zend_object_properties_size(class_type); \ + intern = ecalloc(1, size); \ + memset(intern, 0, size); + +#define PHP_PROTO_FREE_CLASS_OBJECT(class_object, class_object_free, handler) \ + intern->std.handlers = handler; \ + return &intern->std; + +#define PHP_PROTO_ALLOC_ARRAY(zval_ptr) \ + ZVAL_NEW_ARR(zval_ptr) + +#define UNBOX(class_name, val) \ + (class_name*)((char*)Z_OBJ_P(val) - XtOffsetOf(class_name, std)); + +#define UNBOX_HASHTABLE_VALUE(class_name, val) \ + (class_name*)((char*)val - XtOffsetOf(class_name, std)) + +#define HASHTABLE_VALUE_DTOR php_proto_hashtable_descriptor_release + +#define PHP_PROTO_HASHTABLE_VALUE zend_object* + +#define CREATE_HASHTABLE_VALUE(OBJ, WRAPPED_OBJ, OBJ_TYPE, OBJ_CLASS_ENTRY) \ + OBJ_TYPE* OBJ; \ + PHP_PROTO_HASHTABLE_VALUE WRAPPED_OBJ; \ + WRAPPED_OBJ = OBJ_CLASS_ENTRY->create_object(OBJ_CLASS_ENTRY); \ + OBJ = UNBOX_HASHTABLE_VALUE(OBJ_TYPE, WRAPPED_OBJ); \ + --GC_REFCOUNT(WRAPPED_OBJ); + +#define PHP_PROTO_CE_DECLARE zend_class_entry* +#define PHP_PROTO_CE_UNREF(ce) (ce) + +static inline int php_proto_zend_lookup_class( + const char* name, int name_length, zend_class_entry** ce TSRMLS_DC) { + zend_string *zstr_name = zend_string_init(name, name_length, 0); + *ce = zend_lookup_class(zstr_name); + zend_string_release(zstr_name); + return *ce != NULL ? SUCCESS : FAILURE; +} + +#endif // PHP_MAJOR_VERSION >= 7 + // ----------------------------------------------------------------------------- // Forward Declaration // ---------------------------------------------------------------------------- @@ -55,7 +372,8 @@ struct MessageHeader; struct MessageLayout; struct RepeatedField; struct RepeatedFieldIter; -struct MapField; +struct Map; +struct Oneof; typedef struct DescriptorPool DescriptorPool; typedef struct Descriptor Descriptor; @@ -66,7 +384,8 @@ typedef struct MessageHeader MessageHeader; typedef struct MessageLayout MessageLayout; typedef struct RepeatedField RepeatedField; typedef struct RepeatedFieldIter RepeatedFieldIter; -typedef struct MapField MapField; +typedef struct Map Map; +typedef struct Oneof Oneof; // ----------------------------------------------------------------------------- // Globals. @@ -88,13 +407,14 @@ void message_init(TSRMLS_D); // Global map from upb {msg,enum}defs to wrapper Descriptor/EnumDescriptor // instances. -void add_def_obj(const void* def, zval* value); -zval* get_def_obj(const void* def); +void add_def_obj(const void* def, PHP_PROTO_HASHTABLE_VALUE value); +PHP_PROTO_HASHTABLE_VALUE get_def_obj(const void* def); // Global map from PHP class entries to wrapper Descriptor/EnumDescriptor // instances. -void add_ce_obj(const void* ce, zval* value); -zval* get_ce_obj(const void* ce); +void add_ce_obj(const void* ce, PHP_PROTO_HASHTABLE_VALUE value); +PHP_PROTO_HASHTABLE_VALUE get_ce_obj(const void* ce); +bool class_added(const void* ce); extern zend_class_entry* map_field_type; extern zend_class_entry* repeated_field_type; @@ -103,20 +423,25 @@ extern zend_class_entry* repeated_field_type; // Descriptor. // ----------------------------------------------------------------------------- -struct DescriptorPool { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(DescriptorPool) upb_symtab* symtab; HashTable* pending_list; -}; +PHP_PROTO_WRAP_OBJECT_END PHP_METHOD(DescriptorPool, getGeneratedPool); PHP_METHOD(DescriptorPool, internalAddGeneratedFile); -extern zval* generated_pool_php; // wrapper of generated pool +// wrapper of generated pool +#if PHP_MAJOR_VERSION < 7 +extern zval* generated_pool_php; +void descriptor_pool_free(void* object TSRMLS_DC); +#else +extern zend_object *generated_pool_php; +void descriptor_pool_free(zend_object* object); +#endif extern DescriptorPool* generated_pool; // The actual generated pool -struct Descriptor { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(Descriptor) const upb_msgdef* msgdef; MessageLayout* layout; zend_class_entry* klass; // begins as NULL @@ -126,23 +451,21 @@ struct Descriptor { const upb_handlers* pb_serialize_handlers; const upb_handlers* json_serialize_handlers; const upb_handlers* json_serialize_handlers_preserve; -}; +PHP_PROTO_WRAP_OBJECT_END extern zend_class_entry* descriptor_type; void descriptor_name_set(Descriptor *desc, const char *name); -struct FieldDescriptor { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(FieldDescriptor) const upb_fielddef* fielddef; -}; +PHP_PROTO_WRAP_OBJECT_END -struct EnumDescriptor { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(EnumDescriptor) const upb_enumdef* enumdef; zend_class_entry* klass; // begins as NULL // VALUE module; // begins as nil -}; +PHP_PROTO_WRAP_OBJECT_END extern zend_class_entry* enum_descriptor_type; @@ -150,13 +473,15 @@ extern zend_class_entry* enum_descriptor_type; // Message class creation. // ----------------------------------------------------------------------------- -void* message_data(void* msg); -void message_create_with_type(zend_class_entry* ce, zval** message TSRMLS_DC); +void* message_data(MessageHeader* msg); +void custom_data_init(const zend_class_entry* ce, + MessageHeader* msg PHP_PROTO_TSRMLS_DC); // Build PHP class for given descriptor. Instead of building from scratch, this // function modifies existing class which has been partially defined in PHP // code. -void build_class_from_descriptor(zval* php_descriptor TSRMLS_DC); +void build_class_from_descriptor( + PHP_PROTO_HASHTABLE_VALUE php_descriptor TSRMLS_DC); extern zend_object_handlers* message_handlers; @@ -227,18 +552,17 @@ struct MessageLayout { size_t size; }; -struct MessageHeader { - zend_object std; // Stores properties table and class info of PHP instance. - // This is needed for MessageHeader to be accessed via PHP. +PHP_PROTO_WRAP_OBJECT_START(MessageHeader) + void* data; // Point to the real message data. + // Place needs to be consistent with map_parse_frame_data_t. Descriptor* descriptor; // Kept alive by self.class.descriptor reference. - // The real message data is appended after MessageHeader. -}; +PHP_PROTO_WRAP_OBJECT_END MessageLayout* create_layout(const upb_msgdef* msgdef); void layout_init(MessageLayout* layout, void* storage, - zval** properties_table TSRMLS_DC); + CACHED_VALUE* properties_table PHP_PROTO_TSRMLS_DC); zval* layout_get(MessageLayout* layout, const void* storage, - const upb_fielddef* field, zval** cache TSRMLS_DC); + const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC); void layout_set(MessageLayout* layout, MessageHeader* header, const upb_fielddef* field, zval* val TSRMLS_DC); void layout_merge(MessageLayout* layout, MessageHeader* from, @@ -308,7 +632,12 @@ PHP_METHOD(Util, checkRepeatedField); size_t native_slot_size(upb_fieldtype_t type); bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, void* memory, zval* value TSRMLS_DC); -void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache); +// String/Message is stored differently in array/map from normal message fields. +// So we need to make a special method to handle that. +bool native_slot_set_by_array(upb_fieldtype_t type, + const zend_class_entry* klass, void* memory, + zval* value TSRMLS_DC); +void native_slot_init(upb_fieldtype_t type, void* memory, void* cache); // For each property, in order to avoid conversion between the zval object and // the actual data type during parsing/serialization, the containing message // object use the custom memory layout to store the actual data type for each @@ -317,8 +646,13 @@ void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache); // for providing such a zval object. Instead the caller needs to provide one // (cache) and update it with the actual data (memory). void native_slot_get(upb_fieldtype_t type, const void* memory, - zval** cache TSRMLS_DC); -void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC); + CACHED_VALUE* cache TSRMLS_DC); +// String/Message is stored differently in array/map from normal message fields. +// So we need to make a special method to handle that. +void native_slot_get_by_array(upb_fieldtype_t type, const void* memory, + CACHED_VALUE* cache TSRMLS_DC); +void native_slot_get_default(upb_fieldtype_t type, + CACHED_VALUE* cache TSRMLS_DC); // ----------------------------------------------------------------------------- // Map Field. @@ -326,13 +660,12 @@ void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC); extern zend_object_handlers* map_field_handlers; -typedef struct { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(Map) upb_fieldtype_t key_type; upb_fieldtype_t value_type; const zend_class_entry* msg_ce; // class entry for value message upb_strtable table; -} Map; +PHP_PROTO_WRAP_OBJECT_END typedef struct { Map* self; @@ -349,14 +682,14 @@ upb_value map_iter_value(MapIter* iter, int* len); const upb_fielddef* map_entry_key(const upb_msgdef* msgdef); const upb_fielddef* map_entry_value(const upb_msgdef* msgdef); -zend_object_value map_field_create(zend_class_entry *ce TSRMLS_DC); -void map_field_create_with_field(zend_class_entry *ce, const upb_fielddef *field, - zval **map_field TSRMLS_DC); -void map_field_create_with_type(zend_class_entry *ce, upb_fieldtype_t key_type, +void map_field_create_with_field(const zend_class_entry* ce, + const upb_fielddef* field, + CACHED_VALUE* map_field PHP_PROTO_TSRMLS_DC); +void map_field_create_with_type(const zend_class_entry* ce, + upb_fieldtype_t key_type, upb_fieldtype_t value_type, - const zend_class_entry *msg_ce, - zval **map_field TSRMLS_DC); -void map_field_free(void* object TSRMLS_DC); + const zend_class_entry* msg_ce, + CACHED_VALUE* map_field PHP_PROTO_TSRMLS_DC); void* upb_value_memory(upb_value* v); #define MAP_KEY_FIELD 1 @@ -382,33 +715,36 @@ PHP_METHOD(MapField, count); // ----------------------------------------------------------------------------- extern zend_object_handlers* repeated_field_handlers; +extern zend_object_handlers* repeated_field_iter_handlers; -struct RepeatedField { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(RepeatedField) +#if PHP_MAJOR_VERSION < 7 zval* array; +#else + zval array; +#endif upb_fieldtype_t type; const zend_class_entry* msg_ce; // class entry for containing message // (for message field only). -}; +PHP_PROTO_WRAP_OBJECT_END -struct RepeatedFieldIter { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(RepeatedFieldIter) RepeatedField* repeated_field; long position; -}; - -void repeated_field_create_with_field(zend_class_entry* ce, - const upb_fielddef* field, - zval** repeated_field TSRMLS_DC); -void repeated_field_create_with_type(zend_class_entry* ce, upb_fieldtype_t type, - const zend_class_entry* msg_ce, - zval** repeated_field TSRMLS_DC); +PHP_PROTO_WRAP_OBJECT_END + +void repeated_field_create_with_field( + zend_class_entry* ce, const upb_fielddef* field, + CACHED_VALUE* repeated_field PHP_PROTO_TSRMLS_DC); +void repeated_field_create_with_type( + zend_class_entry* ce, upb_fieldtype_t type, const zend_class_entry* msg_ce, + CACHED_VALUE* repeated_field PHP_PROTO_TSRMLS_DC); // Return the element at the index position from the repeated field. There is // not restriction on the type of stored elements. void *repeated_field_index_native(RepeatedField *intern, int index TSRMLS_DC); // Add the element to the end of the repeated field. There is not restriction on // the type of stored elements. -void repeated_field_push_native(RepeatedField *intern, void *value TSRMLS_DC); +void repeated_field_push_native(RepeatedField *intern, void *value); PHP_METHOD(RepeatedField, __construct); PHP_METHOD(RepeatedField, append); @@ -429,12 +765,11 @@ PHP_METHOD(RepeatedFieldIter, valid); // Oneof Field. // ----------------------------------------------------------------------------- -typedef struct { - zend_object std; +PHP_PROTO_WRAP_OBJECT_START(Oneof) upb_oneofdef* oneofdef; int index; // Index of field in oneof. -1 if not set. char value[NATIVE_SLOT_MAX_SIZE]; -} Oneof; +PHP_PROTO_WRAP_OBJECT_END // Oneof case slot value to indicate that no oneof case is set. The value `0` is // safe because field numbers are used as case identifiers, and no field can @@ -446,24 +781,13 @@ typedef struct { // ----------------------------------------------------------------------------- upb_fieldtype_t to_fieldtype(upb_descriptortype_t type); -const zend_class_entry *field_type_class(const upb_fielddef *field TSRMLS_DC); +const zend_class_entry* field_type_class( + const upb_fielddef* field PHP_PROTO_TSRMLS_DC); // ----------------------------------------------------------------------------- // Utilities. // ----------------------------------------------------------------------------- -// PHP <-> C conversion. -#define UNBOX(class_name, val) \ - (class_name*)zend_object_store_get_object(val TSRMLS_CC); - -#define BOX(class_name, wrapper, intern, free_func) \ - MAKE_STD_ZVAL(wrapper); \ - Z_TYPE_P(wrapper) = IS_OBJECT; \ - Z_OBJVAL_P(wrapper) \ - .handle = \ - zend_objects_store_put(intern, NULL, free_func, NULL TSRMLS_CC); \ - Z_OBJVAL_P(wrapper).handlers = zend_get_std_object_handlers(); - // Memory management #define ALLOC(class_name) (class_name*) emalloc(sizeof(class_name)) #define PEMALLOC(class_name) (class_name*) pemalloc(sizeof(class_name), 1) @@ -471,19 +795,15 @@ const zend_class_entry *field_type_class(const upb_fielddef *field TSRMLS_DC); #define FREE(object) efree(object) #define PEFREE(object) pefree(object, 1) -// Create PHP internal instance. -#define CREATE(class_name, intern, init_func) \ - intern = ALLOC(class_name); \ - memset(intern, 0, sizeof(class_name)); \ - init_func(intern TSRMLS_CC); - // String argument. #define STR(str) (str), strlen(str) // Zend Value +#if PHP_MAJOR_VERSION < 7 #define Z_OBJ_P(zval_p) \ ((zend_object*)(EG(objects_store) \ .object_buckets[Z_OBJ_HANDLE_P(zval_p)] \ .bucket.obj.object)) +#endif #endif // __GOOGLE_PROTOBUF_PHP_PROTOBUF_H__ diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index af7c292f..6318f88c 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -57,7 +57,7 @@ size_t native_slot_size(upb_fieldtype_t type) { } } -static bool native_slot_is_default(upb_fieldtype_t type, void* memory) { +static bool native_slot_is_default(upb_fieldtype_t type, const void* memory) { switch (type) { #define CASE_TYPE(upb_type, c_type) \ case UPB_TYPE_##upb_type: { \ @@ -75,15 +75,17 @@ static bool native_slot_is_default(upb_fieldtype_t type, void* memory) { #undef CASE_TYPE case UPB_TYPE_STRING: case UPB_TYPE_BYTES: - return Z_STRLEN_PP(DEREF(memory, zval**)) == 0; + return Z_STRLEN_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) == + 0; case UPB_TYPE_MESSAGE: - return Z_TYPE_PP(DEREF(memory, zval**)) == IS_NULL; + return Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR(DEREF(memory, CACHED_VALUE*))) == + IS_NULL; default: return false; } } bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, - void* memory, zval* value TSRMLS_DC) { + void* memory, zval* value PHP_PROTO_TSRMLS_DC) { switch (type) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { @@ -95,14 +97,14 @@ bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); return false; } - if (*(zval**)memory != NULL) { + + zval* cached_zval = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (EXPECTED(cached_zval != NULL)) { +#if PHP_MAJOR_VERSION < 7 REPLACE_ZVAL_VALUE((zval**)memory, value, 1); - } else { - // Handles repeated/map string field. Memory provided by - // RepeatedField/Map is not initialized. - MAKE_STD_ZVAL(DEREF(memory, zval*)); - ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value), Z_STRLEN_P(value), - 1); +#else + zend_assign_to_variable(cached_zval, value, IS_CV); +#endif } break; } @@ -115,13 +117,18 @@ bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, zend_error(E_USER_ERROR, "Given message does not have correct class."); return false; } - if (EXPECTED(DEREF(memory, zval*) != value)) { - if (DEREF(memory, zval*) != NULL) { - zval_ptr_dtor((zval**)memory); - } - DEREF(memory, zval*) = value; - Z_ADDREF_P(value); + + zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (EXPECTED(property_ptr != value)) { + php_proto_zval_ptr_dtor(property_ptr); } + +#if PHP_MAJOR_VERSION < 7 + DEREF(memory, zval*) = value; + Z_ADDREF_P(value); +#else + ZVAL_ZVAL(property_ptr, value, 1, 0); +#endif break; } @@ -151,7 +158,59 @@ bool native_slot_set(upb_fieldtype_t type, const zend_class_entry* klass, return true; } -void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache) { +bool native_slot_set_by_array(upb_fieldtype_t type, + const zend_class_entry* klass, void* memory, + zval* value TSRMLS_DC) { + switch (type) { + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: { + if (!protobuf_convert_to_string(value)) { + return false; + } + if (type == UPB_TYPE_STRING && + !is_structurally_valid_utf8(Z_STRVAL_P(value), Z_STRLEN_P(value))) { + zend_error(E_USER_ERROR, "Given string is not UTF8 encoded."); + return false; + } + + // Handles repeated/map string field. Memory provided by + // RepeatedField/Map is not initialized. +#if PHP_MAJOR_VERSION < 7 + MAKE_STD_ZVAL(DEREF(memory, zval*)); + PHP_PROTO_ZVAL_STRINGL(DEREF(memory, zval*), Z_STRVAL_P(value), + Z_STRLEN_P(value), 1); +#else + *(zend_string**)memory = zend_string_dup(Z_STR_P(value), 0); +#endif + break; + } + case UPB_TYPE_MESSAGE: { + if (Z_TYPE_P(value) != IS_OBJECT) { + zend_error(E_USER_ERROR, "Given value is not message."); + return false; + } + if (Z_TYPE_P(value) == IS_OBJECT && klass != Z_OBJCE_P(value)) { + zend_error(E_USER_ERROR, "Given message does not have correct class."); + return false; + } +#if PHP_MAJOR_VERSION < 7 + if (EXPECTED(DEREF(memory, zval*) != value)) { + DEREF(memory, zval*) = value; + Z_ADDREF_P(value); + } +#else + DEREF(memory, zend_object*) = Z_OBJ_P(value); + ++GC_REFCOUNT(Z_OBJ_P(value)); +#endif + break; + } + default: + return native_slot_set(type, klass, memory, value TSRMLS_CC); + } + return true; +} + +void native_slot_init(upb_fieldtype_t type, void* memory, void* cache) { zval* tmp = NULL; switch (type) { case UPB_TYPE_FLOAT: @@ -166,7 +225,7 @@ void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: case UPB_TYPE_MESSAGE: - DEREF(memory, zval**) = cache; + DEREF(memory, CACHED_VALUE*) = cache; break; case UPB_TYPE_ENUM: case UPB_TYPE_INT32: @@ -187,38 +246,38 @@ void native_slot_init(upb_fieldtype_t type, void* memory, zval** cache) { } void native_slot_get(upb_fieldtype_t type, const void* memory, - zval** cache TSRMLS_DC) { + CACHED_VALUE* cache TSRMLS_DC) { switch (type) { -#define CASE(upb_type, php_type, c_type) \ - case UPB_TYPE_##upb_type: \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_##php_type(*cache, DEREF(memory, c_type)); \ - return; +#define CASE(upb_type, php_type, c_type) \ + case UPB_TYPE_##upb_type: \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \ + return; -CASE(FLOAT, DOUBLE, float) -CASE(DOUBLE, DOUBLE, double) -CASE(BOOL, BOOL, int8_t) -CASE(INT32, LONG, int32_t) -CASE(ENUM, LONG, uint32_t) + CASE(FLOAT, DOUBLE, float) + CASE(DOUBLE, DOUBLE, double) + CASE(BOOL, BOOL, int8_t) + CASE(INT32, LONG, int32_t) + CASE(ENUM, LONG, uint32_t) #undef CASE #if SIZEOF_LONG == 4 -#define CASE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - char buffer[MAX_LENGTH_OF_INT64]; \ - sprintf(buffer, "%lld", DEREF(memory, c_type)); \ - ZVAL_STRING(*cache, buffer, 1); \ - return; \ - } +#define CASE(upb_type, c_type) \ + case UPB_TYPE_##upb_type: { \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + char buffer[MAX_LENGTH_OF_INT64]; \ + sprintf(buffer, "%lld", DEREF(memory, c_type)); \ + PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), buffer, 1); \ + return; \ + } #else -#define CASE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_LONG(*cache, DEREF(memory, c_type)); \ - return; \ - } +#define CASE(upb_type, c_type) \ + case UPB_TYPE_##upb_type: { \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), DEREF(memory, c_type)); \ + return; \ + } #endif CASE(UINT64, uint64_t) CASE(INT64, int64_t) @@ -227,32 +286,34 @@ CASE(INT64, int64_t) case UPB_TYPE_UINT32: { // Prepend bit-1 for negative numbers, so that uint32 value will be // consistent on both 32-bit and 64-bit architectures. - SEPARATE_ZVAL_IF_NOT_REF(cache); + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); int value = DEREF(memory, int32_t); if (sizeof(int) == 8) { value |= (-((value >> 31) & 0x1) & 0xFFFFFFFF00000000); } - ZVAL_LONG(*cache, value); + ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), value); return; } case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { - // For optional string/bytes fields, the cache is owned by the containing - // message and should have been updated during setting/decoding. However, - // for repeated string/bytes fields, the cache is provided by zend engine - // and has not been updated. - zval* value = DEREF(memory, zval*); - if (*cache != value) { - ZVAL_STRINGL(*cache, Z_STRVAL_P(value), Z_STRLEN_P(value), 1); + // For optional string/bytes/message fields, the cache is owned by the + // containing message and should have been updated during + // setting/decoding. However, oneof accessor call this function by + // providing the return value directly, which is not the same as the cache + // value. + zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) { + PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), Z_STRVAL_P(value), + Z_STRLEN_P(value), 1); } break; } case UPB_TYPE_MESSAGE: { // Same as above for string/bytes fields. - zval* value = DEREF(memory, zval*); - if (*cache != value) { - ZVAL_ZVAL(*cache, value, 1, 0); + zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (CACHED_PTR_TO_ZVAL_PTR(cache) != value) { + ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0); } return; } @@ -261,12 +322,46 @@ CASE(INT64, int64_t) } } -void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC) { +void native_slot_get_by_array(upb_fieldtype_t type, const void* memory, + CACHED_VALUE* cache TSRMLS_DC) { switch (type) { -#define CASE(upb_type, php_type) \ - case UPB_TYPE_##upb_type: \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_##php_type(*cache, 0); \ + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: { +#if PHP_MAJOR_VERSION < 7 + zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) { + PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), + Z_STRVAL_P(value), Z_STRLEN_P(value), 1); + } +#else + ZVAL_NEW_STR(cache, zend_string_dup(*(zend_string**)memory, 0)); +#endif + return; + } + case UPB_TYPE_MESSAGE: { +#if PHP_MAJOR_VERSION < 7 + zval* value = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + if (EXPECTED(CACHED_PTR_TO_ZVAL_PTR(cache) != value)) { + ZVAL_ZVAL(CACHED_PTR_TO_ZVAL_PTR(cache), value, 1, 0); + } +#else + ++GC_REFCOUNT(*(zend_object**)memory); + ZVAL_OBJ(cache, *(zend_object**)memory); +#endif + return; + } + default: + native_slot_get(type, memory, cache TSRMLS_CC); + } +} + +void native_slot_get_default(upb_fieldtype_t type, + CACHED_VALUE* cache TSRMLS_DC) { + switch (type) { +#define CASE(upb_type, php_type) \ + case UPB_TYPE_##upb_type: \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + ZVAL_##php_type(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \ return; CASE(FLOAT, DOUBLE) @@ -279,19 +374,19 @@ void native_slot_get_default(upb_fieldtype_t type, zval** cache TSRMLS_DC) { #undef CASE #if SIZEOF_LONG == 4 -#define CASE(upb_type) \ - case UPB_TYPE_##upb_type: { \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_STRING(*cache, "0", 1); \ - return; \ - } +#define CASE(upb_type) \ + case UPB_TYPE_##upb_type: { \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + PHP_PROTO_ZVAL_STRING(CACHED_PTR_TO_ZVAL_PTR(cache), "0", 1); \ + return; \ + } #else -#define CASE(upb_type) \ - case UPB_TYPE_##upb_type: { \ - SEPARATE_ZVAL_IF_NOT_REF(cache); \ - ZVAL_LONG(*cache, 0); \ - return; \ - } +#define CASE(upb_type) \ + case UPB_TYPE_##upb_type: { \ + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); \ + ZVAL_LONG(CACHED_PTR_TO_ZVAL_PTR(cache), 0); \ + return; \ + } #endif CASE(UINT64) CASE(INT64) @@ -299,13 +394,13 @@ CASE(INT64) case UPB_TYPE_STRING: case UPB_TYPE_BYTES: { - SEPARATE_ZVAL_IF_NOT_REF(cache); - ZVAL_STRINGL(*cache, "", 0, 1); + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); + PHP_PROTO_ZVAL_STRINGL(CACHED_PTR_TO_ZVAL_PTR(cache), "", 0, 1); break; } case UPB_TYPE_MESSAGE: { - SEPARATE_ZVAL_IF_NOT_REF(cache); - ZVAL_NULL(*cache); + PHP_PROTO_SEPARATE_ZVAL_IF_NOT_REF(cache); + ZVAL_NULL(CACHED_PTR_TO_ZVAL_PTR(cache)); return; } default: @@ -359,14 +454,15 @@ const upb_fielddef* map_entry_value(const upb_msgdef* msgdef) { return value_field; } -const zend_class_entry* field_type_class(const upb_fielddef* field TSRMLS_DC) { +const zend_class_entry* field_type_class( + const upb_fielddef* field PHP_PROTO_TSRMLS_DC) { if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { - zval* desc_php = get_def_obj(upb_fielddef_subdef(field)); - Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); + Descriptor* desc = UNBOX_HASHTABLE_VALUE( + Descriptor, get_def_obj(upb_fielddef_subdef(field))); return desc->klass; } else if (upb_fielddef_type(field) == UPB_TYPE_ENUM) { - zval* desc_php = get_def_obj(upb_fielddef_subdef(field)); - EnumDescriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); + EnumDescriptor* desc = UNBOX_HASHTABLE_VALUE( + EnumDescriptor, get_def_obj(upb_fielddef_subdef(field))); return desc->klass; } return NULL; @@ -501,7 +597,7 @@ void free_layout(MessageLayout* layout) { } void layout_init(MessageLayout* layout, void* storage, - zval** properties_table TSRMLS_DC) { + CACHED_VALUE* properties_table PHP_PROTO_TSRMLS_DC) { int i; upb_msg_field_iter it; for (upb_msg_field_begin(&it, layout->msgdef), i = 0; !upb_msg_field_done(&it); @@ -510,20 +606,27 @@ void layout_init(MessageLayout* layout, void* storage, void* memory = slot_memory(layout, storage, field); uint32_t* oneof_case = slot_oneof_case(layout, storage, field); int cache_index = slot_property_cache(layout, storage, field); - zval** property_ptr = &properties_table[cache_index]; + CACHED_VALUE* property_ptr = &properties_table[cache_index]; if (upb_fielddef_containingoneof(field)) { memset(memory, 0, NATIVE_SLOT_MAX_SIZE); *oneof_case = ONEOF_CASE_NONE; } else if (is_map_field(field)) { zval_ptr_dtor(property_ptr); - map_field_create_with_field(map_field_type, field, property_ptr TSRMLS_CC); - DEREF(memory, zval**) = property_ptr; +#if PHP_MAJOR_VERSION < 7 + MAKE_STD_ZVAL(*property_ptr); +#endif + map_field_create_with_field(map_field_type, field, + property_ptr PHP_PROTO_TSRMLS_CC); + DEREF(memory, CACHED_VALUE*) = property_ptr; } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { zval_ptr_dtor(property_ptr); +#if PHP_MAJOR_VERSION < 7 + MAKE_STD_ZVAL(*property_ptr); +#endif repeated_field_create_with_field(repeated_field_type, field, - property_ptr TSRMLS_CC); - DEREF(memory, zval**) = property_ptr; + property_ptr PHP_PROTO_TSRMLS_CC); + DEREF(memory, CACHED_VALUE*) = property_ptr; } else { native_slot_init(upb_fielddef_type(field), memory, property_ptr); } @@ -537,7 +640,7 @@ static void* value_memory(const upb_fielddef* field, void* memory) { case UPB_TYPE_STRING: case UPB_TYPE_BYTES: case UPB_TYPE_MESSAGE: - memory = DEREF(memory, zval**); + memory = DEREF(memory, CACHED_VALUE*); break; default: // No operation @@ -547,7 +650,7 @@ static void* value_memory(const upb_fielddef* field, void* memory) { } zval* layout_get(MessageLayout* layout, const void* storage, - const upb_fielddef* field, zval** cache TSRMLS_DC) { + const upb_fielddef* field, CACHED_VALUE* cache TSRMLS_DC) { void* memory = slot_memory(layout, storage, field); uint32_t* oneof_case = slot_oneof_case(layout, storage, field); @@ -558,13 +661,13 @@ zval* layout_get(MessageLayout* layout, const void* storage, native_slot_get(upb_fielddef_type(field), value_memory(field, memory), cache TSRMLS_CC); } - return *cache; + return CACHED_PTR_TO_ZVAL_PTR(cache); } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - return *cache; + return CACHED_PTR_TO_ZVAL_PTR(cache); } else { native_slot_get(upb_fielddef_type(field), value_memory(field, memory), cache TSRMLS_CC); - return *cache; + return CACHED_PTR_TO_ZVAL_PTR(cache); } } @@ -583,8 +686,7 @@ void layout_set(MessageLayout* layout, MessageHeader* header, switch (type) { case UPB_TYPE_MESSAGE: { const upb_msgdef* msg = upb_fielddef_msgsubdef(field); - zval* desc_php = get_def_obj(msg); - Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg)); ce = desc->klass; // Intentionally fall through. } @@ -593,9 +695,9 @@ void layout_set(MessageLayout* layout, MessageHeader* header, int property_cache_index = header->descriptor->layout->fields[upb_fielddef_index(field)] .cache_index; - DEREF(memory, zval**) = + DEREF(memory, CACHED_VALUE*) = &(header->std.properties_table)[property_cache_index]; - memory = DEREF(memory, zval**); + memory = DEREF(memory, CACHED_VALUE*); break; } default: @@ -606,27 +708,130 @@ void layout_set(MessageLayout* layout, MessageHeader* header, *oneof_case = upb_fielddef_number(field); } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { // Works for both repeated and map fields - memory = DEREF(memory, zval**); - if (EXPECTED(DEREF(memory, zval*) != val)) { - zval_ptr_dtor(memory); - DEREF(memory, zval*) = val; - Z_ADDREF_P(val); + memory = DEREF(memory, void**); + zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); + + if (EXPECTED(property_ptr != val)) { +#if PHP_MAJOR_VERSION < 7 + REPLACE_ZVAL_VALUE((zval**)memory, val, 1); +#else + php_proto_zval_ptr_dtor(property_ptr); + ZVAL_ZVAL(property_ptr, val, 1, 0); +#endif } } else { upb_fieldtype_t type = upb_fielddef_type(field); zend_class_entry *ce = NULL; if (type == UPB_TYPE_MESSAGE) { const upb_msgdef* msg = upb_fielddef_msgsubdef(field); - zval* desc_php = get_def_obj(msg); - Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg)); ce = desc->klass; } native_slot_set(type, ce, value_memory(field, memory), val TSRMLS_CC); } } +static native_slot_merge(const upb_fielddef* field, const void* from_memory, + void* to_memory PHP_PROTO_TSRMLS_DC) { + upb_fieldtype_t type = upb_fielddef_type(field); + zend_class_entry* ce = NULL; + if (!native_slot_is_default(type, from_memory)) { + switch (type) { +#define CASE_TYPE(upb_type, c_type) \ + case UPB_TYPE_##upb_type: { \ + DEREF(to_memory, c_type) = DEREF(from_memory, c_type); \ + break; \ + } + CASE_TYPE(INT32, int32_t) + CASE_TYPE(UINT32, uint32_t) + CASE_TYPE(ENUM, int32_t) + CASE_TYPE(INT64, int64_t) + CASE_TYPE(UINT64, uint64_t) + CASE_TYPE(FLOAT, float) + CASE_TYPE(DOUBLE, double) + CASE_TYPE(BOOL, int8_t) + +#undef CASE_TYPE + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: + native_slot_set(type, NULL, value_memory(field, to_memory), + CACHED_PTR_TO_ZVAL_PTR(DEREF( + from_memory, CACHED_VALUE*)) PHP_PROTO_TSRMLS_CC); + break; + case UPB_TYPE_MESSAGE: { + const upb_msgdef* msg = upb_fielddef_msgsubdef(field); + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg)); + ce = desc->klass; + if (native_slot_is_default(type, to_memory)) { +#if PHP_MAJOR_VERSION < 7 + SEPARATE_ZVAL_IF_NOT_REF((zval**)value_memory(field, to_memory)); +#endif + CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR( + CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)), ce); + MessageHeader* submsg = + UNBOX(MessageHeader, + CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*))); + custom_data_init(ce, submsg PHP_PROTO_TSRMLS_CC); + } + + MessageHeader* sub_from = + UNBOX(MessageHeader, + CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*))); + MessageHeader* sub_to = + UNBOX(MessageHeader, + CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*))); + + layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC); + break; + } + } + } +} + +static native_slot_merge_by_array(const upb_fielddef* field, const void* from_memory, + void* to_memory PHP_PROTO_TSRMLS_DC) { + upb_fieldtype_t type = upb_fielddef_type(field); + switch (type) { + case UPB_TYPE_STRING: + case UPB_TYPE_BYTES: { +#if PHP_MAJOR_VERSION < 7 + MAKE_STD_ZVAL(DEREF(to_memory, zval*)); + PHP_PROTO_ZVAL_STRINGL(DEREF(to_memory, zval*), + Z_STRVAL_P(*(zval**)from_memory), + Z_STRLEN_P(*(zval**)from_memory), 1); +#else + DEREF(to_memory, zend_string*) = + zend_string_dup(*(zend_string**)from_memory, 0); +#endif + break; + } + case UPB_TYPE_MESSAGE: { + const upb_msgdef* msg = upb_fielddef_msgsubdef(field); + Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(msg)); + zend_class_entry* ce = desc->klass; +#if PHP_MAJOR_VERSION < 7 + MAKE_STD_ZVAL(DEREF(to_memory, zval*)); + CREATE_OBJ_ON_ALLOCATED_ZVAL_PTR(DEREF(to_memory, zval*), ce); +#else + DEREF(to_memory, zend_object*) = ce->create_object(ce TSRMLS_CC); +#endif + MessageHeader* sub_from = UNBOX_HASHTABLE_VALUE( + MessageHeader, DEREF(from_memory, PHP_PROTO_HASHTABLE_VALUE)); + MessageHeader* sub_to = UNBOX_HASHTABLE_VALUE( + MessageHeader, DEREF(to_memory, PHP_PROTO_HASHTABLE_VALUE)); + custom_data_init(ce, sub_to PHP_PROTO_TSRMLS_CC); + + layout_merge(desc->layout, sub_from, sub_to PHP_PROTO_TSRMLS_CC); + break; + } + default: + native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC); + break; + } +} + void layout_merge(MessageLayout* layout, MessageHeader* from, - MessageHeader* to TSRMLS_DC) { + MessageHeader* to PHP_PROTO_TSRMLS_DC) { int i, j; upb_msg_field_iter it; @@ -639,11 +844,10 @@ void layout_merge(MessageLayout* layout, MessageHeader* from, if (upb_fielddef_containingoneof(field)) { uint32_t oneof_case_offset = - layout->fields[upb_fielddef_index(field)].case_offset + - sizeof(MessageHeader); + layout->fields[upb_fielddef_index(field)].case_offset; // For a oneof, check that this field is actually present -- skip all the // below if not. - if (DEREF(((uint8_t*)from + oneof_case_offset), uint32_t) != + if (DEREF((message_data(from) + oneof_case_offset), uint32_t) != upb_fielddef_number(field)) { continue; } @@ -658,7 +862,7 @@ void layout_merge(MessageLayout* layout, MessageHeader* from, case UPB_TYPE_BYTES: { int property_cache_index = layout->fields[upb_fielddef_index(field)].cache_index; - DEREF(to_memory, zval**) = + DEREF(to_memory, CACHED_VALUE*) = &(to->std.properties_table)[property_cache_index]; break; } @@ -676,141 +880,57 @@ void layout_merge(MessageLayout* layout, MessageHeader* from, int size, key_length, value_length; MapIter map_it; - zval* to_map_php = *DEREF(to_memory, zval**); - zval* from_map_php = *DEREF(from_memory, zval**); - Map* to_map = zend_object_store_get_object(to_map_php TSRMLS_CC); - Map* from_map = zend_object_store_get_object(from_map_php TSRMLS_CC); + zval* to_map_php = + CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)); + zval* from_map_php = + CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*)); + Map* to_map = UNBOX(Map, to_map_php); + Map* from_map = UNBOX(Map, from_map_php); size = upb_strtable_count(&from_map->table); if (size == 0) continue; + const upb_msgdef *mapentry_def = upb_fielddef_msgsubdef(field); + const upb_fielddef *value_field = upb_msgdef_itof(mapentry_def, 2); + for (map_begin(from_map_php, &map_it TSRMLS_CC); !map_done(&map_it); map_next(&map_it)) { const char* key = map_iter_key(&map_it, &key_length); - upb_value value = map_iter_value(&map_it, &value_length); - void* mem = upb_value_memory(&value); - switch (to_map->value_type) { - case UPB_TYPE_MESSAGE: { - zval* new_message; - message_create_with_type(to_map->msg_ce, &new_message TSRMLS_CC); - Z_ADDREF_P(new_message); - - zval* subdesc_php = get_ce_obj(to_map->msg_ce); - Descriptor* subdesc = - zend_object_store_get_object(subdesc_php TSRMLS_CC); - MessageHeader* sub_from = - (MessageHeader*)zend_object_store_get_object(DEREF(mem, zval*) - TSRMLS_CC); - MessageHeader* sub_to = - (MessageHeader*)zend_object_store_get_object( - new_message TSRMLS_CC); - layout_merge(subdesc->layout, sub_from, sub_to TSRMLS_CC); - DEREF(mem, zval*) = new_message; - break; - } - case UPB_TYPE_BYTES: - case UPB_TYPE_STRING: - Z_ADDREF_PP((zval**)mem); - break; - default: - break; - } - map_index_set(to_map, key, key_length, value); + upb_value from_value = map_iter_value(&map_it, &value_length); + upb_value to_value; + void* from_mem = upb_value_memory(&from_value); + void* to_mem = upb_value_memory(&to_value); + memset(to_mem, 0, native_slot_size(to_map->value_type)); + + native_slot_merge_by_array(value_field, from_mem, + to_mem PHP_PROTO_TSRMLS_CC); + + map_index_set(to_map, key, key_length, to_value); } } else if (upb_fielddef_label(field) == UPB_LABEL_REPEATED) { - zval* to_array_php = *DEREF(to_memory, zval**); - zval* from_array_php = *DEREF(from_memory, zval**); - RepeatedField* to_array = - zend_object_store_get_object(to_array_php TSRMLS_CC); - RepeatedField* from_array = - zend_object_store_get_object(from_array_php TSRMLS_CC); - - int size = zend_hash_num_elements(HASH_OF(from_array->array)); + zval* to_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(to_memory, CACHED_VALUE*)); + zval* from_array_php = CACHED_PTR_TO_ZVAL_PTR(DEREF(from_memory, CACHED_VALUE*)); + RepeatedField* to_array = UNBOX(RepeatedField, to_array_php); + RepeatedField* from_array = UNBOX(RepeatedField, from_array_php); + + int size = zend_hash_num_elements(PHP_PROTO_HASH_OF(from_array->array)); if (size > 0) { for (j = 0; j < size; j++) { - void* memory = NULL; - zend_hash_index_find(HASH_OF(from_array->array), j, (void**)&memory); - switch (to_array->type) { - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: { - zval* str; - MAKE_STD_ZVAL(str); - ZVAL_STRINGL(str, Z_STRVAL_PP((zval**)memory), - Z_STRLEN_PP((zval**)memory), 1); - memory = &str; - break; - } - case UPB_TYPE_MESSAGE: { - zval* new_message; - message_create_with_type(from_array->msg_ce, &new_message TSRMLS_CC); - Z_ADDREF_P(new_message); - - zval* subdesc_php = get_ce_obj(from_array->msg_ce); - Descriptor* subdesc = - zend_object_store_get_object(subdesc_php TSRMLS_CC); - MessageHeader* sub_from = - (MessageHeader*)zend_object_store_get_object( - DEREF(memory, zval*) TSRMLS_CC); - MessageHeader* sub_to = - (MessageHeader*)zend_object_store_get_object( - new_message TSRMLS_CC); - layout_merge(subdesc->layout, sub_from, sub_to TSRMLS_CC); - - memory = &new_message; - } - default: - break; - } - repeated_field_push_native(to_array, memory TSRMLS_CC); + void* from_memory = NULL; + void* to_memory = + ALLOC_N(char, native_slot_size(upb_fielddef_type(field))); + memset(to_memory, 0, native_slot_size(upb_fielddef_type(field))); + php_proto_zend_hash_index_find(PHP_PROTO_HASH_OF(from_array->array), + j, (void**)&from_memory); + native_slot_merge_by_array(field, from_memory, + to_memory PHP_PROTO_TSRMLS_CC); + repeated_field_push_native(to_array, to_memory); + FREE(to_memory); } } } else { - upb_fieldtype_t type = upb_fielddef_type(field); - zend_class_entry *ce = NULL; - if (!native_slot_is_default(type, from_memory)) { - switch (type) { -#define CASE_TYPE(upb_type, c_type) \ - case UPB_TYPE_##upb_type: { \ - DEREF(to_memory, c_type) = DEREF(from_memory, c_type); \ - break; \ - } - CASE_TYPE(INT32, int32_t) - CASE_TYPE(UINT32, uint32_t) - CASE_TYPE(ENUM, int32_t) - CASE_TYPE(INT64, int64_t) - CASE_TYPE(UINT64, uint64_t) - CASE_TYPE(FLOAT, float) - CASE_TYPE(DOUBLE, double) - CASE_TYPE(BOOL, int8_t) - -#undef CASE_TYPE - case UPB_TYPE_STRING: - case UPB_TYPE_BYTES: - native_slot_set(type, NULL, value_memory(field, to_memory), - *DEREF(from_memory, zval**) TSRMLS_CC); - break; - case UPB_TYPE_MESSAGE: { - const upb_msgdef* msg = upb_fielddef_msgsubdef(field); - zval* desc_php = get_def_obj(msg); - Descriptor* desc = zend_object_store_get_object(desc_php TSRMLS_CC); - ce = desc->klass; - if (native_slot_is_default(type, to_memory)) { - zval* new_message = NULL; - message_create_with_type(ce, &new_message TSRMLS_CC); - native_slot_set(type, ce, value_memory(field, to_memory), - new_message TSRMLS_CC); - } - MessageHeader* sub_from = - (MessageHeader*)zend_object_store_get_object( - *DEREF(from_memory, zval**) TSRMLS_CC); - MessageHeader* sub_to = - (MessageHeader*)zend_object_store_get_object( - *DEREF(to_memory, zval**) TSRMLS_CC); - layout_merge(desc->layout, sub_from, sub_to TSRMLS_CC); - } - } - } + native_slot_merge(field, from_memory, to_memory PHP_PROTO_TSRMLS_CC); } } } diff --git a/php/ext/google/protobuf/type_check.c b/php/ext/google/protobuf/type_check.c index fe9b18f0..fada8d6a 100644 --- a/php/ext/google/protobuf/type_check.c +++ b/php/ext/google/protobuf/type_check.c @@ -325,9 +325,18 @@ CONVERT_TO_FLOAT(double); bool protobuf_convert_to_bool(zval* from, int8_t* to) { switch (Z_TYPE_P(from)) { +#if PHP_MAJOR_VERSION < 7 case IS_BOOL: *to = (int8_t)Z_BVAL_P(from); break; +#else + case IS_TRUE: + *to = 1; + break; + case IS_FALSE: + *to = 0; + break; +#endif case IS_LONG: *to = (int8_t)(Z_LVAL_P(from) != 0); break; @@ -357,12 +366,16 @@ bool protobuf_convert_to_string(zval* from) { case IS_STRING: { return true; } +#if PHP_MAJOR_VERSION < 7 case IS_BOOL: +#else + case IS_TRUE: + case IS_FALSE: +#endif case IS_LONG: case IS_DOUBLE: { - int use_copy; zval tmp; - zend_make_printable_zval(from, &tmp, &use_copy); + php_proto_zend_make_printable_zval(from, &tmp); ZVAL_COPY_VALUE(from, &tmp); return true; } @@ -417,34 +430,45 @@ PHP_METHOD(Util, checkMessage) { PHP_METHOD(Util, checkRepeatedField) { zval* val; - long type; + PHP_PROTO_LONG type; const zend_class_entry* klass = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl|C", &val, &type, &klass) == FAILURE) { return; } +#if PHP_MAJOR_VERSION >= 7 + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); + } +#endif + if (Z_TYPE_P(val) == IS_ARRAY) { - HashTable* table = Z_ARRVAL_P(val); + HashTable* table = HASH_OF(val); HashPosition pointer; void* memory; + +#if PHP_MAJOR_VERSION < 7 zval* repeated_field; + MAKE_STD_ZVAL(repeated_field); +#else + zval repeated_field; +#endif repeated_field_create_with_type(repeated_field_type, to_fieldtype(type), klass, &repeated_field TSRMLS_CC); - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(repeated_field TSRMLS_CC); for (zend_hash_internal_pointer_reset_ex(table, &pointer); - zend_hash_get_current_data_ex(table, (void**)&memory, &pointer) == - SUCCESS; + php_proto_zend_hash_get_current_data_ex(table, (void**)&memory, + &pointer) == SUCCESS; zend_hash_move_forward_ex(table, &pointer)) { - repeated_field_handlers->write_dimension(repeated_field, NULL, - *(zval**)memory TSRMLS_CC); + repeated_field_handlers->write_dimension( + CACHED_TO_ZVAL_PTR(repeated_field), NULL, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory) TSRMLS_CC); } - Z_DELREF_P(repeated_field); - RETURN_ZVAL(repeated_field, 1, 0); + Z_DELREF_P(CACHED_TO_ZVAL_PTR(repeated_field)); + RETURN_ZVAL(CACHED_TO_ZVAL_PTR(repeated_field), 1, 0); } else if (Z_TYPE_P(val) == IS_OBJECT) { if (!instanceof_function(Z_OBJCE_P(val), repeated_field_type TSRMLS_CC)) { @@ -452,8 +476,7 @@ PHP_METHOD(Util, checkRepeatedField) { repeated_field_type->name); return; } - RepeatedField* intern = - (RepeatedField*)zend_object_store_get_object(val TSRMLS_CC); + RepeatedField* intern = UNBOX(RepeatedField, val); if (to_fieldtype(type) != intern->type) { zend_error(E_USER_ERROR, "Incorrect repeated field type."); return; @@ -474,43 +497,55 @@ PHP_METHOD(Util, checkRepeatedField) { PHP_METHOD(Util, checkMapField) { zval* val; - long key_type, value_type; + PHP_PROTO_LONG key_type, value_type; const zend_class_entry* klass = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zll|C", &val, &key_type, &value_type, &klass) == FAILURE) { return; } +#if PHP_MAJOR_VERSION >= 7 + if (Z_ISREF_P(val)) { + ZVAL_DEREF(val); + } +#endif + if (Z_TYPE_P(val) == IS_ARRAY) { HashTable* table = Z_ARRVAL_P(val); HashPosition pointer; - zval key, *map_field; + zval key; void* value; +#if PHP_MAJOR_VERSION < 7 + zval* map_field; + MAKE_STD_ZVAL(map_field); +#else + zval map_field; +#endif + map_field_create_with_type(map_field_type, to_fieldtype(key_type), to_fieldtype(value_type), klass, &map_field TSRMLS_CC); - Map* intern = - (Map*)zend_object_store_get_object(map_field TSRMLS_CC); for (zend_hash_internal_pointer_reset_ex(table, &pointer); - zend_hash_get_current_data_ex(table, (void**)&value, &pointer) == - SUCCESS; + php_proto_zend_hash_get_current_data_ex(table, (void**)&value, + &pointer) == SUCCESS; zend_hash_move_forward_ex(table, &pointer)) { zend_hash_get_current_key_zval_ex(table, &key, &pointer); - map_field_handlers->write_dimension(map_field, &key, - *(zval**)value TSRMLS_CC); + map_field_handlers->write_dimension( + CACHED_TO_ZVAL_PTR(map_field), &key, + CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC); } - Z_DELREF_P(map_field); - RETURN_ZVAL(map_field, 1, 0); + Z_DELREF_P(CACHED_TO_ZVAL_PTR(map_field)); + RETURN_ZVAL(CACHED_TO_ZVAL_PTR(map_field), 1, 0); } else if (Z_TYPE_P(val) == IS_OBJECT) { if (!instanceof_function(Z_OBJCE_P(val), map_field_type TSRMLS_CC)) { zend_error(E_USER_ERROR, "Given value is not an instance of %s.", map_field_type->name); return; } - Map* intern = (Map*)zend_object_store_get_object(val TSRMLS_CC); + Map* intern = UNBOX(Map, val); if (to_fieldtype(key_type) != intern->key_type) { zend_error(E_USER_ERROR, "Incorrect map field key type."); return; diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php index 68c10c08..f65bd9b8 100644 --- a/php/src/Google/Protobuf/Internal/MapField.php +++ b/php/src/Google/Protobuf/Internal/MapField.php @@ -284,6 +284,9 @@ class MapField implements \ArrayAccess, \IteratorAggregate, \Countable GPBUtil::checkString($value, true); break; case GPBType::MESSAGE: + if (is_null($value)) { + trigger_error("Map element cannot be null.", E_USER_ERROR); + } GPBUtil::checkMessage($value, $this->klass); break; default: diff --git a/php/src/Google/Protobuf/Internal/RepeatedField.php b/php/src/Google/Protobuf/Internal/RepeatedField.php index 0dc5d9d2..2ad4709a 100644 --- a/php/src/Google/Protobuf/Internal/RepeatedField.php +++ b/php/src/Google/Protobuf/Internal/RepeatedField.php @@ -225,6 +225,10 @@ class RepeatedField implements \ArrayAccess, \IteratorAggregate, \Countable GPBUtil::checkString($value, true); break; case GPBType::MESSAGE: + if (is_null($value)) { + trigger_error("RepeatedField element cannot be null.", + E_USER_ERROR); + } GPBUtil::checkMessage($value, $this->klass); break; default: diff --git a/php/tests/array_test.php b/php/tests/array_test.php index a4cad719..b55408da 100644 --- a/php/tests/array_test.php +++ b/php/tests/array_test.php @@ -751,23 +751,13 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase $arr []= $sub_m; $this->assertSame(1, $arr[0]->getA()); - $null = null; - $arr []= $null; - $this->assertNull($arr[1]); - - $this->assertEquals(2, count($arr)); - - for ($i = 0; $i < count($arr); $i++) { - $arr[$i] = $null; - $this->assertNull($arr[$i]); - } + $this->assertEquals(1, count($arr)); // Test set. + $sub_m = new TestMessage_Sub(); + $sub_m->setA(2); $arr [0]= $sub_m; - $this->assertSame(1, $arr[0]->getA()); - - $arr [1]= $null; - $this->assertNull($arr[1]); + $this->assertSame(2, $arr[0]->getA()); } /** @@ -817,6 +807,27 @@ class RepeatedFieldTest extends PHPUnit_Framework_TestCase $arr []= new TestMessage; } + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMessageAppendNullFail() + { + $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $null = null; + $arr []= $null; + } + + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMessageSetNullFail() + { + $arr = new RepeatedField(GPBType::MESSAGE, TestMessage_Sub::class); + $arr []= new TestMessage_Sub(); + $null = null; + $arr[0] = $null; + } + ######################################################### # Test offset type ######################################################### diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh index 45a2841f..484e2edf 100755 --- a/php/tests/gdb_test.sh +++ b/php/tests/gdb_test.sh @@ -3,10 +3,8 @@ # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which # phpunit` --bootstrap autoload.php tmp_test.php # -gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php array_test.php +gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php # -# # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so -# memory_leak_test.php +# gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php # -# # USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -# -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php +# USE_ZEND_ALLOC=0 valgrind --leak-check=yes php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php diff --git a/php/tests/map_field_test.php b/php/tests/map_field_test.php index d4ec44fc..2fda9135 100644 --- a/php/tests/map_field_test.php +++ b/php/tests/map_field_test.php @@ -616,11 +616,7 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { $arr[0] = $sub_m; $this->assertSame(1, $arr[0]->getA()); - $null = NULL; - $arr[1] = $null; - $this->assertNull($arr[1]); - - $this->assertEquals(2, count($arr)); + $this->assertEquals(1, count($arr)); } /** @@ -653,6 +649,17 @@ class MapFieldTest extends PHPUnit_Framework_TestCase { $arr[0] = new TestMessage_Sub(); } + /** + * @expectedException PHPUnit_Framework_Error + */ + public function testMessageSetNullFail() + { + $arr = + new MapField(GPBType::INT32, GPBType::MESSAGE, TestMessage::class); + $null = NULL; + $arr[0] = $null; + } + ######################################################### # Test memory leak ######################################################### diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 5dd79519..68b6f5be 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -83,7 +83,8 @@ $n = new TestMessage(); $n->mergeFromString($data); assert(1 === $n->getOneofMessage()->getA()); -$from = new TestMessage(); -$to = new TestMessage(); -TestUtil::setTestMessage($from); -$to->mergeFrom($from); +# $from = new TestMessage(); +# $to = new TestMessage(); +# TestUtil::setTestMessage($from); +# $to->mergeFrom($from); +# TestUtil::assertTestMessage($to); diff --git a/php/tests/test_util.php b/php/tests/test_util.php index 61f94aa1..9dbcbb62 100644 --- a/php/tests/test_util.php +++ b/php/tests/test_util.php @@ -51,8 +51,6 @@ class TestUtil public static function setTestMessage(TestMessage $m) { - $sub = new TestMessage_Sub(); - $m->setOptionalInt32(-42); $m->setOptionalInt64(-43); $m->setOptionalUint32(42); @@ -69,6 +67,7 @@ class TestUtil $m->setOptionalString('a'); $m->setOptionalBytes('b'); $m->setOptionalEnum(TestEnum::ONE); + $sub = new TestMessage_Sub(); $m->setOptionalMessage($sub); $m->getOptionalMessage()->SetA(33); diff --git a/tests.sh b/tests.sh index 68ba7cc7..8c56172d 100755 --- a/tests.sh +++ b/tests.sh @@ -371,12 +371,9 @@ use_php() { PHP=`which php` PHP_CONFIG=`which php-config` PHPIZE=`which phpize` - rm $PHP - rm $PHP_CONFIG - rm $PHPIZE - cp "/usr/bin/php$VERSION" $PHP - cp "/usr/bin/php-config$VERSION" $PHP_CONFIG - cp "/usr/bin/phpize$VERSION" $PHPIZE + ln -sfn "/usr/local/php-${VERSION}/bin/php" $PHP + ln -sfn "/usr/local/php-${VERSION}/bin/php-config" $PHP_CONFIG + ln -sfn "/usr/local/php-${VERSION}/bin/phpize" $PHPIZE generate_php_test_proto } @@ -403,18 +400,13 @@ use_php_bc() { } build_php5.5() { - PHP=`which php` - PHP_CONFIG=`which php-config` - PHPIZE=`which phpize` - ln -sfn "/usr/local/php-5.5/bin/php" $PHP - ln -sfn "/usr/local/php-5.5/bin/php-config" $PHP_CONFIG - ln -sfn "/usr/local/php-5.5/bin/phpize" $PHPIZE - generate_php_test_proto + use_php 5.5 pushd php rm -rf vendor cp -r /usr/local/vendor-5.5 vendor - ./vendor/bin/phpunit + wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit + phpunit popd pushd conformance # TODO(teboring): Add it back @@ -423,51 +415,21 @@ build_php5.5() { } build_php5.5_c() { - PHP=`which php` - PHP_CONFIG=`which php-config` - PHPIZE=`which phpize` - ln -sfn "/usr/local/php-5.5/bin/php" $PHP - ln -sfn "/usr/local/php-5.5/bin/php-config" $PHP_CONFIG - ln -sfn "/usr/local/php-5.5/bin/phpize" $PHPIZE - generate_php_test_proto - wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit - + use_php 5.5 + wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance - make test_php_c + # make test_php_c popd } build_php5.5_zts_c() { use_php_zts 5.5 - wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit + wget https://phar.phpunit.de/phpunit-4.8.0.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance - make test_php_c - popd -} - -build_php5.5_32() { - use_php_bc 5.5 - pushd php - rm -rf vendor - cp -r /usr/local/vendor-5.5 vendor - ./vendor/bin/phpunit - popd - # TODO(teboring): Add conformance test. - # pushd conformance - # make test_php - # popd -} - -build_php5.5_c_32() { - use_php_bc 5.5 - wget https://phar.phpunit.de/phpunit-old.phar -O /usr/bin/phpunit - cd php/tests && /bin/bash ./test.sh && cd ../.. - # TODO(teboring): Add conformance test. - # pushd conformance # make test_php_c - # popd + popd } build_php5.6() { @@ -475,7 +437,8 @@ build_php5.6() { pushd php rm -rf vendor cp -r /usr/local/vendor-5.6 vendor - ./vendor/bin/phpunit + wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit + phpunit popd pushd conformance # TODO(teboring): Add it back @@ -485,9 +448,19 @@ build_php5.6() { build_php5.6_c() { use_php 5.6 + wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance - make test_php_c + # make test_php_c + popd +} + +build_php5.6_zts_c() { + use_php_zts 5.6 + wget https://phar.phpunit.de/phpunit-5.7.0.phar -O /usr/bin/phpunit + cd php/tests && /bin/bash ./test.sh && cd ../.. + pushd conformance + # make test_php_c popd } @@ -511,7 +484,7 @@ build_php5.6_mac() { # Test cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance - make test_php_c + # make test_php_c popd } @@ -520,7 +493,8 @@ build_php7.0() { pushd php rm -rf vendor cp -r /usr/local/vendor-7.0 vendor - ./vendor/bin/phpunit + wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit + phpunit popd pushd conformance # TODO(teboring): Add it back @@ -530,9 +504,43 @@ build_php7.0() { build_php7.0_c() { use_php 7.0 + wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit cd php/tests && /bin/bash ./test.sh && cd ../.. pushd conformance - make test_php_c + # make test_php_c + popd +} + +build_php7.0_zts_c() { + use_php_zts 7.0 + wget https://phar.phpunit.de/phpunit-5.6.0.phar -O /usr/bin/phpunit + cd php/tests && /bin/bash ./test.sh && cd ../.. + pushd conformance + # make test_php_c + popd +} + +build_php7.0_mac() { + generate_php_test_proto + # Install PHP + curl -s https://php-osx.liip.ch/install.sh | bash -s 7.0 + PHP_FOLDER=`find /usr/local -type d -name "php7-7.0*"` # The folder name may change upon time + export PATH="$PHP_FOLDER/bin:$PATH" + + # Install phpunit + curl https://phar.phpunit.de/phpunit-5.6.0.phar -L -o phpunit.phar + chmod +x phpunit.phar + sudo mv phpunit.phar /usr/local/bin/phpunit + + # Install valgrind + echo "#! /bin/bash" > valgrind + chmod ug+x valgrind + sudo mv valgrind /usr/local/bin/valgrind + + # Test + cd php/tests && /bin/bash ./test.sh && cd ../.. + pushd conformance + # make test_php_c popd } @@ -542,13 +550,10 @@ build_php_all() { build_php7.0 build_php5.5_c build_php5.6_c - # build_php7.0_c + build_php7.0_c build_php5.5_zts_c -} - -build_php_all_32() { - build_php5.5_32 - build_php5.5_c_32 + build_php5.6_zts_c + build_php7.0_zts_c } # Note: travis currently does not support testing more than one language so the -- cgit v1.2.3 From 7be088202bad3a89498db2e9b19afda9f3929430 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 19 Apr 2017 20:03:34 -0700 Subject: Enum defined without package have incorrect class name. (#2988) Fix the bug by sharing the code for generating class name for both message and enum. --- php/tests/generated_class_test.php | 12 ++-- php/tests/memory_leak_test.php | 3 + php/tests/proto/test.proto | 6 ++ php/tests/proto/test_no_namespace.proto | 4 +- src/google/protobuf/compiler/php/php_generator.cc | 82 ++++++++++------------- 5 files changed, 54 insertions(+), 53 deletions(-) diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 39e6c6c4..41d63a60 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -1,7 +1,7 @@ setOptionalNoNamespaceMessage(new NoNameSpaceMessage()); + $m->getRepeatedNoNamespaceMessage()[] = new NoNameSpaceMessage(); } public function testEnumWithoutNamespace() { - $m = new NoNameSpaceEnum(); + $m = new TestMessage(); + $m->setOptionalNoNamespaceEnum(NoNameSpaceEnum::VALUE_A); + $m->getRepeatedNoNamespaceEnum()[] = NoNameSpaceEnum::VALUE_A; } ######################################################### diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 68b6f5be..6b7077f0 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -2,6 +2,8 @@ # phpunit has memory leak by itself. Thus, it cannot be used to test memory leak. +require_once('generated/NoNamespaceEnum.php'); +require_once('generated/NoNamespaceMessage.php'); require_once('generated/PrefixTestPrefix.php'); require_once('generated/Bar/TestInclude.php'); require_once('generated/Foo/TestEnum.php'); @@ -13,6 +15,7 @@ require_once('generated/Foo/TestPhpDoc.php'); require_once('generated/Foo/TestUnpackedMessage.php'); require_once('generated/GPBMetadata/Proto/Test.php'); require_once('generated/GPBMetadata/Proto/TestInclude.php'); +require_once('generated/GPBMetadata/Proto/TestNoNamespace.php'); require_once('generated/GPBMetadata/Proto/TestPrefix.php'); require_once('test_util.php'); diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index 1a47a3f2..cc9bf8c8 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -1,6 +1,7 @@ syntax = "proto3"; import 'proto/test_include.proto'; +import 'proto/test_no_namespace.proto'; import 'proto/test_prefix.proto'; package foo; @@ -96,6 +97,11 @@ message TestMessage { // Reserved for non-existing field test. // int32 non_exist = 89; + + NoNamespaceMessage optional_no_namespace_message = 91; + NoNamespaceEnum optional_no_namespace_enum = 92; + repeated NoNamespaceMessage repeated_no_namespace_message = 93; + repeated NoNamespaceEnum repeated_no_namespace_enum = 94; } enum TestEnum { diff --git a/php/tests/proto/test_no_namespace.proto b/php/tests/proto/test_no_namespace.proto index b8c4fdf2..b0f66002 100644 --- a/php/tests/proto/test_no_namespace.proto +++ b/php/tests/proto/test_no_namespace.proto @@ -1,10 +1,10 @@ syntax = "proto3"; -message NoNameSpaceMessage { +message NoNamespaceMessage { int32 a = 1; } -enum NoNameSpaceEnum { +enum NoNamespaceEnum { VALUE_A = 0; VALUE_B = 1; } diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index db72ea1a..32f40b2e 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -84,33 +84,6 @@ std::string RenameEmpty(const std::string& name) { } } -std::string MessagePrefix(const Descriptor* message) { - // Empty cannot be php class name. - if (message->name() == "Empty" && - message->file()->package() == "google.protobuf") { - return "GPB"; - } else { - return (message->file()->options()).php_class_prefix(); - } -} - -std::string MessageName(const Descriptor* message, bool is_descriptor) { - string message_name = message->name(); - const Descriptor* descriptor = message->containing_type(); - while (descriptor != NULL) { - message_name = descriptor->name() + '_' + message_name; - descriptor = descriptor->containing_type(); - } - message_name = MessagePrefix(message) + message_name; - - if (message->file()->package() == "") { - return message_name; - } else { - return PhpName(message->file()->package(), is_descriptor) + '\\' + - message_name; - } -} - std::string MessageFullName(const Descriptor* message, bool is_descriptor) { if (is_descriptor) { return StringReplace(message->full_name(), @@ -131,19 +104,34 @@ std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) { } } -std::string EnumClassName(const EnumDescriptor* envm) { - string enum_class_name = envm->name(); - const Descriptor* descriptor = envm->containing_type(); - while (descriptor != NULL) { - enum_class_name = descriptor->name() + '_' + enum_class_name; - descriptor = descriptor->containing_type(); +template +std::string ClassNamePrefix(const DescriptorType* desc) { + // Empty cannot be php class name. + if (desc->name() == "Empty" && + desc->file()->package() == "google.protobuf") { + return "GPB"; + } else { + return (desc->file()->options()).php_class_prefix(); } - return enum_class_name; } -std::string EnumName(const EnumDescriptor* envm, bool is_descriptor) { - string enum_name = EnumClassName(envm); - return PhpName(envm->file()->package(), is_descriptor) + '\\' + enum_name; + +template +std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { + string classname = desc->name(); + const Descriptor* containing = desc->containing_type(); + while (containing != NULL) { + classname = containing->name() + '_' + classname; + containing = containing->containing_type(); + } + classname = ClassNamePrefix(desc) + classname; + + if (desc->file()->package() == "") { + return classname; + } else { + return PhpName(desc->file()->package(), is_descriptor) + '\\' + + classname; + } } std::string PhpName(const std::string& full_name, bool is_descriptor) { @@ -231,7 +219,7 @@ std::string GeneratedMetadataFileName(const std::string& proto_file, std::string GeneratedMessageFileName(const Descriptor* message, bool is_descriptor) { - std::string result = MessageName(message, is_descriptor); + std::string result = FullClassName(message, is_descriptor); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -242,7 +230,7 @@ std::string GeneratedMessageFileName(const Descriptor* message, std::string GeneratedEnumFileName(const EnumDescriptor* en, bool is_descriptor) { - std::string result = EnumName(en, is_descriptor); + std::string result = FullClassName(en, is_descriptor); for (int i = 0; i < result.size(); i++) { if (result[i] == '\\') { result[i] = '/'; @@ -456,12 +444,12 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - MessageName(value->message_type(), is_descriptor) + "::class"); + FullClassName(value->message_type(), is_descriptor) + "::class"); } else if (value->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( - ", ^class_name^);\n", + ", \\^class_name^);\n", "class_name", - EnumName(value->enum_type(), is_descriptor) + "::class"); + FullClassName(value->enum_type(), is_descriptor) + "::class"); } else { printer->Print(");\n"); } @@ -474,23 +462,23 @@ void GenerateFieldAccessor(const FieldDescriptor* field, bool is_descriptor, printer->Print( ", \\^class_name^);\n", "class_name", - MessageName(field->message_type(), is_descriptor) + "::class"); + FullClassName(field->message_type(), is_descriptor) + "::class"); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( - ", ^class_name^);\n", + ", \\^class_name^);\n", "class_name", - EnumName(field->enum_type(), is_descriptor) + "::class"); + FullClassName(field->enum_type(), is_descriptor) + "::class"); } else { printer->Print(");\n"); } } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { printer->Print( "GPBUtil::checkMessage($var, \\^class_name^::class);\n", - "class_name", MessageName(field->message_type(), is_descriptor)); + "class_name", FullClassName(field->message_type(), is_descriptor)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) { printer->Print( "GPBUtil::checkEnum($var, \\^class_name^::class);\n", - "class_name", EnumName(field->enum_type(), is_descriptor)); + "class_name", FullClassName(field->enum_type(), is_descriptor)); } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) { printer->Print( "GPBUtil::checkString($var, ^utf8^);\n", -- cgit v1.2.3 From b97cd573e405dd511b09a9fae124427a29741395 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 19 Apr 2017 21:20:55 -0700 Subject: Add test for nested enum for php (#2989) --- php/tests/generated_class_test.php | 9 +++++++++ php/tests/memory_leak_test.php | 2 ++ php/tests/proto/test.proto | 6 ++++++ php/tests/proto/test_no_namespace.proto | 5 +++++ 4 files changed, 22 insertions(+) diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 41d63a60..c5dee2d6 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -295,6 +295,12 @@ class GeneratedClassTest extends TestBase $this->assertEquals(TestEnum::ONE, $m->getOptionalEnum()); } + public function testNestedEnum() + { + $m = new TestMessage(); + $m->setOptionalNestedEnum(\Foo\TestMessage_NestedEnum::ZERO); + } + ######################################################### # Test float field. ######################################################### @@ -835,6 +841,9 @@ class GeneratedClassTest extends TestBase $m = new TestMessage(); $m->setOptionalNoNamespaceMessage(new NoNameSpaceMessage()); $m->getRepeatedNoNamespaceMessage()[] = new NoNameSpaceMessage(); + + $n = new NoNamespaceMessage(); + $n->setB(NoNamespaceMessage_NestedEnum::ZERO); } public function testEnumWithoutNamespace() diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index 6b7077f0..ea7a4c96 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -4,11 +4,13 @@ require_once('generated/NoNamespaceEnum.php'); require_once('generated/NoNamespaceMessage.php'); +require_once('generated/NoNamespaceMessage_NestedEnum.php'); require_once('generated/PrefixTestPrefix.php'); require_once('generated/Bar/TestInclude.php'); require_once('generated/Foo/TestEnum.php'); require_once('generated/Foo/TestIncludePrefixMessage.php'); require_once('generated/Foo/TestMessage.php'); +require_once('generated/Foo/TestMessage_NestedEnum.php'); require_once('generated/Foo/TestMessage_Sub.php'); require_once('generated/Foo/TestPackedMessage.php'); require_once('generated/Foo/TestPhpDoc.php'); diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index cc9bf8c8..b6c14866 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -102,6 +102,12 @@ message TestMessage { NoNamespaceEnum optional_no_namespace_enum = 92; repeated NoNamespaceMessage repeated_no_namespace_message = 93; repeated NoNamespaceEnum repeated_no_namespace_enum = 94; + + enum NestedEnum { + ZERO = 0; + } + + NestedEnum optional_nested_enum = 101; } enum TestEnum { diff --git a/php/tests/proto/test_no_namespace.proto b/php/tests/proto/test_no_namespace.proto index b0f66002..3dd76764 100644 --- a/php/tests/proto/test_no_namespace.proto +++ b/php/tests/proto/test_no_namespace.proto @@ -2,6 +2,11 @@ syntax = "proto3"; message NoNamespaceMessage { int32 a = 1; + + enum NestedEnum { + ZERO = 0; + } + NestedEnum b = 2; } enum NoNamespaceEnum { -- cgit v1.2.3 From 4c57e8475f78ccac80407f03c2d23d30014785f9 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 20 Apr 2017 01:19:03 -0700 Subject: Prepend "PB" to generated classes whose name are reserved words. (#2990) --- php/ext/google/protobuf/def.c | 123 ++++++++++++++-------- php/src/Google/Protobuf/Internal/Message.php | 1 + php/src/Google/Protobuf/descriptor.php | 36 +++++-- php/tests/generated_class_test.php | 11 ++ php/tests/memory_leak_test.php | 3 + php/tests/proto/test.proto | 10 ++ php/tests/proto/test_prefix.proto | 5 + src/google/protobuf/compiler/php/php_generator.cc | 35 ++++-- 8 files changed, 163 insertions(+), 61 deletions(-) diff --git a/php/ext/google/protobuf/def.c b/php/ext/google/protobuf/def.c index 50c0350e..8e563a61 100644 --- a/php/ext/google/protobuf/def.c +++ b/php/ext/google/protobuf/def.c @@ -30,6 +30,9 @@ #include "protobuf.h" +const char* const kReservedNames[] = {"Empty"}; +const int kReservedNamesSize = 1; + // Forward declare. static void descriptor_init_c_instance(Descriptor* intern TSRMLS_DC); static void descriptor_free_c(Descriptor* object TSRMLS_DC); @@ -355,58 +358,90 @@ PHP_METHOD(DescriptorPool, getGeneratedPool) { #endif } -static void convert_to_class_name_inplace(char *class_name, - const char* fullname, - const char* prefix, - const char* package_name) { +static void classname_no_prefix(const char *fullname, const char *package_name, + char *class_name) { size_t i = 0, j; - bool first_char = true; + bool first_char = true, is_reserved = false; size_t pkg_name_len = package_name == NULL ? 0 : strlen(package_name); - size_t prefix_len = prefix == NULL ? 0 : strlen(prefix); size_t message_name_start = package_name == NULL ? 0 : pkg_name_len + 1; size_t message_len = (strlen(fullname) - message_name_start); - // In php, class name cannot be Empty. - if (strcmp("google.protobuf.Empty", fullname) == 0) { - strcpy(class_name, "\\Google\\Protobuf\\GPBEmpty"); - return; + // Submessage is concatenated with its containing messages by '_'. + for (j = message_name_start; j < message_name_start + message_len; j++) { + if (fullname[j] == '.') { + class_name[i++] = '_'; + } else { + class_name[i++] = fullname[j]; + } + } +} + +static const char *classname_prefix(const char *classname, + const char *prefix_given, + const char *package_name) { + size_t i; + bool is_reserved = false; + + if (prefix_given != NULL && strcmp(prefix_given, "") != 0) { + return prefix_given; } - if (pkg_name_len != 0) { - class_name[i++] = '\\'; - for (j = 0; j < pkg_name_len; j++) { + for (i = 0; i < kReservedNamesSize; i++) { + if (strcmp(kReservedNames[i], classname) == 0) { + is_reserved = true; + break; + } + } + + if (is_reserved) { + if (package_name != NULL && strcmp("google.protobuf", package_name) == 0) { + return "GPB"; + } else { + return "PB"; + } + } + + return ""; +} + +static void convert_to_class_name_inplace(const char *package, + const char *prefix, char *classname) { + size_t package_len = package == NULL ? 0 : strlen(package); + size_t prefix_len = prefix == NULL ? 0 : strlen(prefix); + size_t classname_len = strlen(classname); + int i = 0, j; + bool first_char = true; + + int offset = package_len != 0 ? 2 : 0; + + for (j = 0; j < classname_len; j++) { + classname[package_len + prefix_len + classname_len + offset - 1 - j] = + classname[classname_len - j - 1]; + } + + if (package_len != 0) { + classname[i++] = '\\'; + for (j = 0; j < package_len; j++) { // php packages are divided by '\'. - if (package_name[j] == '.') { - class_name[i++] = '\\'; + if (package[j] == '.') { + classname[i++] = '\\'; first_char = true; } else if (first_char) { // PHP package uses camel case. - if (package_name[j] < 'A' || package_name[j] > 'Z') { - class_name[i++] = package_name[j] + 'A' - 'a'; + if (package[j] < 'A' || package[j] > 'Z') { + classname[i++] = package[j] + 'A' - 'a'; } else { - class_name[i++] = package_name[j]; + classname[i++] = package[j]; } first_char = false; } else { - class_name[i++] = package_name[j]; + classname[i++] = package[j]; } } - class_name[i++] = '\\'; + classname[i++] = '\\'; } - if (prefix_len > 0) { - strcpy(class_name + i, prefix); - i += prefix_len; - } - - // Submessage is concatenated with its containing messages by '_'. - for (j = message_name_start; j < message_name_start + message_len; j++) { - if (fullname[j] == '.') { - class_name[i++] = '_'; - } else { - class_name[i++] = fullname[j]; - } - } + memcpy(classname + i, prefix, prefix_len); } PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { @@ -455,25 +490,27 @@ PHP_METHOD(DescriptorPool, internalAddGeneratedFile) { * bytes allocated, one for '.', one for trailing 0, and 3 for 'GPB' if \ * given message is google.protobuf.Empty.*/ \ const char *fullname = upb_##def_type_lower##_fullname(def_type_lower); \ - const char *prefix = upb_filedef_phpprefix(files[0]); \ - size_t klass_name_len = strlen(fullname) + 5; \ - if (prefix != NULL) { \ - klass_name_len += strlen(prefix); \ + const char *prefix_given = upb_filedef_phpprefix(files[0]); \ + size_t classname_len = strlen(fullname) + 5; \ + if (prefix_given != NULL) { \ + classname_len += strlen(prefix_given); \ } \ - char *klass_name = ecalloc(sizeof(char), klass_name_len); \ - convert_to_class_name_inplace(klass_name, fullname, prefix, \ - upb_filedef_package(files[0])); \ + char *classname = ecalloc(sizeof(char), classname_len); \ + const char *package = upb_filedef_package(files[0]); \ + classname_no_prefix(fullname, package, classname); \ + const char *prefix = classname_prefix(classname, prefix_given, package); \ + convert_to_class_name_inplace(package, prefix, classname); \ PHP_PROTO_CE_DECLARE pce; \ - if (php_proto_zend_lookup_class(klass_name, strlen(klass_name), &pce) == \ + if (php_proto_zend_lookup_class(classname, strlen(classname), &pce) == \ FAILURE) { \ zend_error(E_ERROR, "Generated message class %s hasn't been defined", \ - klass_name); \ + classname); \ return; \ } else { \ desc->klass = PHP_PROTO_CE_UNREF(pce); \ } \ add_ce_obj(desc->klass, desc_php); \ - efree(klass_name); \ + efree(classname); \ break; \ } diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 887c86ca..0fb6cdc0 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -71,6 +71,7 @@ class Message return; } $pool = DescriptorPool::getGeneratedPool(); + var_dump(get_class($this)); $this->desc = $pool->getDescriptorByClassName(get_class($this)); foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index 2263af6e..9c744a8a 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -220,20 +220,36 @@ class Descriptor } } +function getClassNamePrefix( + $classname, + $file_proto) +{ + $option = $file_proto->getOptions(); + $prefix = is_null($option) ? "" : $option->getPhpClassPrefix(); + if ($prefix !== "") { + return $prefix; + } + + $reserved_words = array("Empty"); + foreach ($reserved_words as $reserved_word) { + if ($classname === $reserved_word) { + if ($file_proto->getPackage() === "google.protobuf") { + return "GPB"; + } else { + return "PB"; + } + } + } + + return ""; +} + function getClassNameWithoutPackage( $name, $file_proto) { - if ($name === "Empty" && $file_proto->getPackage() === "google.protobuf") { - return "GPBEmpty"; - } else { - $option = $file_proto->getOptions(); - $prefix = is_null($option) ? "" : $option->getPhpClassPrefix(); - // Nested message class names are seperated by '_', and package names - // are seperated by '\'. - return $prefix . implode('_', array_map('ucwords', - explode('.', $name))); - } + $classname = implode('_', array_map('ucwords', explode('.', $name))); + return getClassNamePrefix($classname, $file_proto) . $classname; } function getFullClassName( diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index c5dee2d6..554d2bea 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -865,4 +865,15 @@ class GeneratedClassTest extends TestBase $m->setPrefixMessage($n); $this->assertSame(1, $m->getPrefixMessage()->getA()); } + + ######################################################### + # Test prefix for reserved words. + ######################################################### + + public function testPrefixForReservedWords() + { + $m = new \Foo\TestMessage_Empty(); + $m = new \Foo\PBEmpty(); + $m = new \PrefixEmpty(); + } } diff --git a/php/tests/memory_leak_test.php b/php/tests/memory_leak_test.php index ea7a4c96..361982b5 100644 --- a/php/tests/memory_leak_test.php +++ b/php/tests/memory_leak_test.php @@ -5,11 +5,14 @@ require_once('generated/NoNamespaceEnum.php'); require_once('generated/NoNamespaceMessage.php'); require_once('generated/NoNamespaceMessage_NestedEnum.php'); +require_once('generated/PrefixEmpty.php'); require_once('generated/PrefixTestPrefix.php'); require_once('generated/Bar/TestInclude.php'); +require_once('generated/Foo/PBEmpty.php'); require_once('generated/Foo/TestEnum.php'); require_once('generated/Foo/TestIncludePrefixMessage.php'); require_once('generated/Foo/TestMessage.php'); +require_once('generated/Foo/TestMessage_Empty.php'); require_once('generated/Foo/TestMessage_NestedEnum.php'); require_once('generated/Foo/TestMessage_Sub.php'); require_once('generated/Foo/TestPackedMessage.php'); diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index b6c14866..f0d009c8 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -108,6 +108,11 @@ message TestMessage { } NestedEnum optional_nested_enum = 101; + + // Test prefix for reserved words. + message Empty { + int32 a = 1; + } } enum TestEnum { @@ -116,6 +121,11 @@ enum TestEnum { TWO = 2; } +// Test prefix for reserved words. +message Empty { + int32 a = 1; +} + message TestPackedMessage { repeated int32 repeated_int32 = 90 [packed = true]; repeated int64 repeated_int64 = 91 [packed = true]; diff --git a/php/tests/proto/test_prefix.proto b/php/tests/proto/test_prefix.proto index 04582121..9bfbad7f 100644 --- a/php/tests/proto/test_prefix.proto +++ b/php/tests/proto/test_prefix.proto @@ -5,3 +5,8 @@ option php_class_prefix = "Prefix"; message TestPrefix { int32 a = 1; } + +// Test prefix for reserved words. +message Empty { + int32 a = 1; +} diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 32f40b2e..d24e1e5e 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -49,6 +49,8 @@ const std::string kDescriptorMetadataFile = "GPBMetadata/Google/Protobuf/Internal/Descriptor.php"; const std::string kDescriptorDirName = "Google/Protobuf/Internal"; const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal"; +const char* const kReservedNames[] = {"Empty"}; +const int kReservedNamesSize = 1; namespace google { namespace protobuf { @@ -105,14 +107,31 @@ std::string EnumFullName(const EnumDescriptor* envm, bool is_descriptor) { } template -std::string ClassNamePrefix(const DescriptorType* desc) { - // Empty cannot be php class name. - if (desc->name() == "Empty" && - desc->file()->package() == "google.protobuf") { - return "GPB"; - } else { - return (desc->file()->options()).php_class_prefix(); +std::string ClassNamePrefix(const string& classname, + const DescriptorType* desc) { + const string& prefix = (desc->file()->options()).php_class_prefix(); + if (prefix != "") { + return prefix; + } + + bool is_reserved = false; + + for (int i = 0; i < kReservedNamesSize; i++) { + if (classname == kReservedNames[i]) { + is_reserved = true; + break; + } } + + if (is_reserved) { + if (desc->file()->package() == "google.protobuf") { + return "GPB"; + } else { + return "PB"; + } + } + + return ""; } @@ -124,7 +143,7 @@ std::string FullClassName(const DescriptorType* desc, bool is_descriptor) { classname = containing->name() + '_' + classname; containing = containing->containing_type(); } - classname = ClassNamePrefix(desc) + classname; + classname = ClassNamePrefix(classname, desc) + classname; if (desc->file()->package() == "") { return classname; -- cgit v1.2.3 From 478119fe77d8a11df83125e872d9f73afe353bf1 Mon Sep 17 00:00:00 2001 From: Feng Xiao Date: Thu, 20 Apr 2017 16:30:26 -0700 Subject: Fix python3 issue. --- python/google/protobuf/descriptor_pool.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/google/protobuf/descriptor_pool.py b/python/google/protobuf/descriptor_pool.py index 7bd2506b..29e9f1e3 100644 --- a/python/google/protobuf/descriptor_pool.py +++ b/python/google/protobuf/descriptor_pool.py @@ -257,7 +257,7 @@ class DescriptorPool(object): self._AddFileDescriptor(file_desc) # TODO(jieluo): This is a temporary solution for FieldDescriptor.file. # Remove it when FieldDescriptor.file is added in code gen. - for extension in file_desc.extensions_by_name.itervalues(): + for extension in file_desc.extensions_by_name.values(): self._file_desc_by_toplevel_extension[ extension.full_name] = file_desc -- cgit v1.2.3 From 4523c9c233dbb61d03996a5bbe25d1b5aea51f7f Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Thu, 20 Apr 2017 16:55:56 -0700 Subject: Allow proto files to import descriptor.proto (#2995) descriptor.proto uses proto2 syntax, which is not ready for external usage. However, some proto3 files import descriptor.proto and cannot be used. In this PR, all references (We cheated by only removing extensions, which is enough for now. User should avoid using messages defined in descriptor.proto as field type.) to content in descriptor.proto are removed from generated files. Those that import descriptor.proto can be used like other proto files. --- Makefile.am | 1 + php/src/Google/Protobuf/Internal/MapField.php | 1 - php/src/Google/Protobuf/Internal/Message.php | 1 - php/tests/gdb_test.sh | 2 +- php/tests/proto/test_import_descriptor_proto.proto | 14 ++++++++++++ php/tests/well_known_test.php | 10 +++++++-- src/google/protobuf/compiler/php/php_generator.cc | 26 ++++++++++++++++++++++ tests.sh | 1 + 8 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 php/tests/proto/test_import_descriptor_proto.proto diff --git a/Makefile.am b/Makefile.am index 564bff48..d0f033af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -656,6 +656,7 @@ php_EXTRA_DIST= \ php/tests/map_field_test.php \ php/tests/memory_leak_test.php \ php/tests/php_implementation_test.php \ + php/tests/proto/test_import_descriptor_proto.proto \ php/tests/proto/test_include.proto \ php/tests/proto/test.proto \ php/tests/proto/test_prefix.proto \ diff --git a/php/src/Google/Protobuf/Internal/MapField.php b/php/src/Google/Protobuf/Internal/MapField.php index f65bd9b8..55cc12ce 100644 --- a/php/src/Google/Protobuf/Internal/MapField.php +++ b/php/src/Google/Protobuf/Internal/MapField.php @@ -155,7 +155,6 @@ function checkKey($key_type, &$key) GPBUtil::checkString($key, true); break; default: - var_dump($key_type); trigger_error( "Given type cannot be map key.", E_USER_ERROR); diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 0fb6cdc0..887c86ca 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -71,7 +71,6 @@ class Message return; } $pool = DescriptorPool::getGeneratedPool(); - var_dump(get_class($this)); $this->desc = $pool->getDescriptorByClassName(get_class($this)); foreach ($this->desc->getField() as $field) { $setter = $field->getSetter(); diff --git a/php/tests/gdb_test.sh b/php/tests/gdb_test.sh index 484e2edf..0809bef3 100755 --- a/php/tests/gdb_test.sh +++ b/php/tests/gdb_test.sh @@ -3,7 +3,7 @@ # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which # phpunit` --bootstrap autoload.php tmp_test.php # -gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php encode_decode_test.php +gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so `which phpunit` --bootstrap autoload.php well_known_test.php # # gdb --args php -dextension=../ext/google/protobuf/modules/protobuf.so memory_leak_test.php # diff --git a/php/tests/proto/test_import_descriptor_proto.proto b/php/tests/proto/test_import_descriptor_proto.proto new file mode 100644 index 00000000..2a19940d --- /dev/null +++ b/php/tests/proto/test_import_descriptor_proto.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +import "google/protobuf/descriptor.proto"; + +message TestImportDescriptorProto { + extend google.protobuf.MethodOptions { + int32 a = 72295727; + } +} + +extend google.protobuf.MethodOptions { + int32 a = 72295728; +} + diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php index 40ff1c8f..0c2aec13 100644 --- a/php/tests/well_known_test.php +++ b/php/tests/well_known_test.php @@ -4,8 +4,14 @@ use Google\Protobuf\GPBEmpty; class WellKnownTest extends PHPUnit_Framework_TestCase { - public function testNone() { - $msg = new GPBEmpty(); + public function testNone() + { + $msg = new GPBEmpty(); + } + + public function testImportDescriptorProto() + { + $msg = new TestImportDescriptorProto(); } } diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index d24e1e5e..4d475b1f 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -674,6 +674,12 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor, } else { for (int i = 0; i < file->dependency_count(); i++) { const std::string& name = file->dependency(i)->name(); + // Currently, descriptor.proto is not ready for external usage. Skip to + // import it for now, so that its dependencies can still work as long as + // they don't use protos defined in descriptor.proto. + if (name == kDescriptorFile) { + continue; + } std::string dependency_filename = GeneratedMetadataFileName(name, is_descriptor); printer->Print( @@ -685,6 +691,26 @@ void GenerateAddFileToPool(const FileDescriptor* file, bool is_descriptor, FileDescriptorSet files; FileDescriptorProto* file_proto = files.add_file(); file->CopyTo(file_proto); + + // Filter out descriptor.proto as it cannot be depended on for now. + RepeatedPtrField* dependency = file_proto->mutable_dependency(); + for (RepeatedPtrField::iterator it = dependency->begin(); + it != dependency->end(); ++it) { + if (*it != kDescriptorFile) { + dependency->erase(it); + break; + } + } + + // Filter out all extensions, since we do not support extension yet. + file_proto->clear_extension(); + RepeatedPtrField* message_type = + file_proto->mutable_message_type(); + for (RepeatedPtrField::iterator it = message_type->begin(); + it != message_type->end(); ++it) { + it->clear_extension(); + } + string files_data; files.SerializeToString(&files_data); diff --git a/tests.sh b/tests.sh index 8c56172d..edb37da7 100755 --- a/tests.sh +++ b/tests.sh @@ -362,6 +362,7 @@ generate_php_test_proto() { ../../src/protoc --php_out=generated proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto pushd ../../src ./protoc --php_out=../php/tests/generated google/protobuf/empty.proto + ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto popd popd } -- cgit v1.2.3 From 6fff091c49359ffd8550fc8228c79740b504a4fe Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Fri, 21 Apr 2017 15:00:00 -0700 Subject: Throw exception when parsing invalid data. (#3000) --- Makefile.am | 1 + php/ext/google/protobuf/encode_decode.c | 10 +- .../Protobuf/Internal/GPBDecodeException.php | 47 +++++ php/src/Google/Protobuf/Internal/InputStream.php | 17 +- php/src/Google/Protobuf/Internal/Message.php | 73 ++++---- php/tests/encode_decode_test.php | 198 +++++++++++++++++++++ 6 files changed, 297 insertions(+), 49 deletions(-) create mode 100644 php/src/Google/Protobuf/Internal/GPBDecodeException.php diff --git a/Makefile.am b/Makefile.am index d0f033af..3b57b585 100644 --- a/Makefile.am +++ b/Makefile.am @@ -646,6 +646,7 @@ php_EXTRA_DIST= \ php/src/Google/Protobuf/Internal/EnumBuilderContext.php \ php/src/Google/Protobuf/Internal/GPBUtil.php \ php/src/Google/Protobuf/Internal/FieldOptions_CType.php \ + php/src/Google/Protobuf/Internal/GPBDecodeException.php \ php/src/Google/Protobuf/descriptor.php \ php/src/GPBMetadata/Google/Protobuf/Internal/Descriptor.php \ php/tests/array_test.php \ diff --git a/php/ext/google/protobuf/encode_decode.c b/php/ext/google/protobuf/encode_decode.c index 06dc1195..28bf18f4 100644 --- a/php/ext/google/protobuf/encode_decode.c +++ b/php/ext/google/protobuf/encode_decode.c @@ -261,13 +261,6 @@ static void* appendbytes_handler(void *closure, #endif } - static bool int32_handler(void* closure, const void* hd, - int32_t val) { - MessageHeader* msg = (MessageHeader*)closure; - const size_t *ofs = hd; - DEREF(message_data(msg), *ofs, int32_t) = val; - return true; - } // Handlers that append primitive values to a repeated field. #define DEFINE_SINGULAR_HANDLER(type, ctype) \ static bool type##_handler(void* closure, const void* hd, \ @@ -279,7 +272,7 @@ static void* appendbytes_handler(void *closure, } DEFINE_SINGULAR_HANDLER(bool, bool) -// DEFINE_SINGULAR_HANDLER(int32, int32_t) +DEFINE_SINGULAR_HANDLER(int32, int32_t) DEFINE_SINGULAR_HANDLER(uint32, uint32_t) DEFINE_SINGULAR_HANDLER(float, float) DEFINE_SINGULAR_HANDLER(int64, int64_t) @@ -1435,6 +1428,7 @@ PHP_METHOD(Message, mergeFromString) { char *data = NULL; PHP_PROTO_SIZE data_len; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) { return; diff --git a/php/src/Google/Protobuf/Internal/GPBDecodeException.php b/php/src/Google/Protobuf/Internal/GPBDecodeException.php new file mode 100644 index 00000000..402d542f --- /dev/null +++ b/php/src/Google/Protobuf/Internal/GPBDecodeException.php @@ -0,0 +1,47 @@ += 0 && $byte_limit <= PHP_INT_MAX - $current_position) { + if ($byte_limit >= 0 && + $byte_limit <= PHP_INT_MAX - $current_position && + $byte_limit <= $this->current_limit - $current_position) { $this->current_limit = $current_position + $byte_limit; + $this->recomputeBufferLimits(); } else { - // Negative or overflow. - $this->current_limit = PHP_INT_MAX; + throw new GPBDecodeException("Fail to push limit."); } - // We need to enforce all limits, not just the new one, so if the previous - // limit was before the new requested limit, we continue to enforce the - // previous limit. - $this->current_limit = min($this->current_limit, $old_limit); - - $this->recomputeBufferLimits(); return $old_limit; } @@ -370,7 +367,7 @@ class InputStream } public function incrementRecursionDepthAndPushLimit( - $byte_limit, &$old_limit, &$recursion_budget) + $byte_limit, &$old_limit, &$recursion_budget) { $old_limit = $this->pushLimit($byte_limit); $recursion_limit = --$this->recursion_limit; diff --git a/php/src/Google/Protobuf/Internal/Message.php b/php/src/Google/Protobuf/Internal/Message.php index 887c86ca..cd15e0f0 100644 --- a/php/src/Google/Protobuf/Internal/Message.php +++ b/php/src/Google/Protobuf/Internal/Message.php @@ -224,48 +224,57 @@ class Message switch ($field->getType()) { case GPBType::DOUBLE: if (!GPBWire::readDouble($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside double field."); } break; case GPBType::FLOAT: if (!GPBWire::readFloat($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside float field."); } break; case GPBType::INT64: if (!GPBWire::readInt64($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside int64 field."); } break; case GPBType::UINT64: if (!GPBWire::readUint64($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside uint64 field."); } break; case GPBType::INT32: if (!GPBWire::readInt32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside int32 field."); } break; case GPBType::FIXED64: if (!GPBWire::readFixed64($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside fixed64 field."); } break; case GPBType::FIXED32: if (!GPBWire::readFixed32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside fixed32 field."); } break; case GPBType::BOOL: if (!GPBWire::readBool($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside bool field."); } break; case GPBType::STRING: // TODO(teboring): Add utf-8 check. if (!GPBWire::readString($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside string field."); } break; case GPBType::GROUP: @@ -280,43 +289,51 @@ class Message $value = new $klass; } if (!GPBWire::readMessage($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside message."); } break; case GPBType::BYTES: if (!GPBWire::readString($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside bytes field."); } break; case GPBType::UINT32: if (!GPBWire::readUint32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside uint32 field."); } break; case GPBType::ENUM: // TODO(teboring): Check unknown enum value. if (!GPBWire::readInt32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside enum field."); } break; case GPBType::SFIXED32: if (!GPBWire::readSfixed32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside sfixed32 field."); } break; case GPBType::SFIXED64: if (!GPBWire::readSfixed64($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside sfixed64 field."); } break; case GPBType::SINT32: if (!GPBWire::readSint32($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside sint32 field."); } break; case GPBType::SINT64: if (!GPBWire::readSint64($input, $value)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside sint64 field."); } break; default: @@ -345,24 +362,21 @@ class Message } if ($value_format === GPBWire::NORMAL_FORMAT) { - if (!self::parseFieldFromStreamNoTag($input, $field, $value)) { - return false; - } + self::parseFieldFromStreamNoTag($input, $field, $value); } elseif ($value_format === GPBWire::PACKED_FORMAT) { $length = 0; if (!GPBWire::readInt32($input, $length)) { - return false; + throw new GPBDecodeException( + "Unexpected EOF inside packed length."); } $limit = $input->pushLimit($length); $getter = $field->getGetter(); while ($input->bytesUntilLimit() > 0) { - if (!self::parseFieldFromStreamNoTag($input, $field, $value)) { - return false; - } + self::parseFieldFromStreamNoTag($input, $field, $value); $this->$getter()[] = $value; } $input->popLimit($limit); - return true; + return; } else { return false; } @@ -377,8 +391,6 @@ class Message $setter = $field->getSetter(); $this->$setter($value); } - - return true; } /** @@ -567,7 +579,8 @@ class Message * specified message. * * @param string $data Binary protobuf data. - * @return bool Return true on success. + * @return null. + * @throws Exception Invalid data. */ public function mergeFromString($data) { @@ -595,9 +608,7 @@ class Message continue; } - if (!$this->parseFieldFromStream($tag, $input, $field)) { - return false; - } + $this->parseFieldFromStream($tag, $input, $field); } } diff --git a/php/tests/encode_decode_test.php b/php/tests/encode_decode_test.php index 94adf793..288df569 100644 --- a/php/tests/encode_decode_test.php +++ b/php/tests/encode_decode_test.php @@ -211,6 +211,204 @@ class EncodeDecodeTest extends TestBase $this->assertEquals(-1, $m->getOptionalInt32()); } + /** + * @expectedException Exception + */ + public function testDecodeInvalidInt32() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('08')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidSubMessage() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('9A010108')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidInt64() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('10')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidUInt32() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('18')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidUInt64() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('20')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidSInt32() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('28')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidSInt64() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('30')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidFixed32() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('3D')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidFixed64() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('41')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidSFixed32() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('4D')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidSFixed64() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('51')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidFloat() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('5D')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidDouble() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('61')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidBool() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('68')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidStringLengthMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('72')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidStringDataMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('7201')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidBytesLengthMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('7A')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidBytesDataMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('7A01')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidEnum() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('8001')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidMessageLengthMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('8A01')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidMessageDataMiss() + { + $m = new TestMessage(); + $m->mergeFromString(hex2bin('8A0101')); + } + + /** + * @expectedException Exception + */ + public function testDecodeInvalidPackedMessageLength() + { + $m = new TestPackedMessage(); + $m->mergeFromString(hex2bin('D205')); + } + # TODO(teboring): Add test back when php implementation is ready for json # encode/decode. # public function testJsonEncode() -- cgit v1.2.3 From e64b618b2132237f9901da0dc76bb0d50ac35d71 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Mon, 24 Apr 2017 09:24:43 -0700 Subject: Update php version number to 3.3.0 (#3001) --- php/ext/google/protobuf/package.xml | 26 +++++++++++++++++++++----- php/ext/google/protobuf/protobuf.h | 2 +- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/php/ext/google/protobuf/package.xml b/php/ext/google/protobuf/package.xml index aac73d05..a2a8e066 100644 --- a/php/ext/google/protobuf/package.xml +++ b/php/ext/google/protobuf/package.xml @@ -13,16 +13,16 @@ 2017-01-13 - 3.2.0a1 - 3.2.0a1 + 3.3.0 + 3.3.0 - alpha - alpha + stable + stable 3-Clause BSD License -Second alpha release. +GA release. @@ -87,5 +87,21 @@ First alpha release Second alpha release. + + + 3.3.0 + 3.3.0 + + + stable + stable + + 2017-04-28 + + 3-Clause BSD License + +GA release. + + diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h index 02f06f35..e6d42eba 100644 --- a/php/ext/google/protobuf/protobuf.h +++ b/php/ext/google/protobuf/protobuf.h @@ -37,7 +37,7 @@ #include "upb.h" #define PHP_PROTOBUF_EXTNAME "protobuf" -#define PHP_PROTOBUF_VERSION "3.2.0a1" +#define PHP_PROTOBUF_VERSION "3.3.0" #define MAX_LENGTH_OF_INT64 20 #define SIZEOF_INT64 8 -- cgit v1.2.3 From fba2acd72e8cbf138912295df227ee2c914158c3 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Mon, 24 Apr 2017 12:40:37 -0700 Subject: Add nested enum descriptor in php rumtime. (#3009) --- php/src/Google/Protobuf/Internal/DescriptorPool.php | 3 +++ php/src/Google/Protobuf/descriptor.php | 6 ++++++ php/tests/generated_class_test.php | 3 ++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/php/src/Google/Protobuf/Internal/DescriptorPool.php b/php/src/Google/Protobuf/Internal/DescriptorPool.php index 1ef403cf..2c00dfb6 100644 --- a/php/src/Google/Protobuf/Internal/DescriptorPool.php +++ b/php/src/Google/Protobuf/Internal/DescriptorPool.php @@ -95,6 +95,9 @@ class DescriptorPool foreach ($descriptor->getNestedType() as $nested_type) { $this->addDescriptor($nested_type); } + foreach ($descriptor->getEnumType() as $enum_type) { + $this->addEnumDescriptor($enum_type); + } } public function addEnumDescriptor($descriptor) diff --git a/php/src/Google/Protobuf/descriptor.php b/php/src/Google/Protobuf/descriptor.php index 9c744a8a..fb69eda0 100644 --- a/php/src/Google/Protobuf/descriptor.php +++ b/php/src/Google/Protobuf/descriptor.php @@ -210,6 +210,12 @@ class Descriptor $nested_proto, $file_proto, $message_name_without_package)); } + // Handle nested enum. + foreach ($proto->getEnumType() as $enum_proto) { + $desc->addEnumType(EnumDescriptor::buildFromProto( + $enum_proto, $file_proto, $message_name_without_package)); + } + // Handle oneof fields. foreach ($proto->getOneofDecl() as $oneof_proto) { $desc->addOneofDecl( diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php index 554d2bea..21ee8490 100644 --- a/php/tests/generated_class_test.php +++ b/php/tests/generated_class_test.php @@ -839,7 +839,8 @@ class GeneratedClassTest extends TestBase public function testMessageWithoutNamespace() { $m = new TestMessage(); - $m->setOptionalNoNamespaceMessage(new NoNameSpaceMessage()); + $sub = new NoNameSpaceMessage(); + $m->setOptionalNoNamespaceMessage($sub); $m->getRepeatedNoNamespaceMessage()[] = new NoNameSpaceMessage(); $n = new NoNamespaceMessage(); -- cgit v1.2.3 From 3c0855e94ac4cf6c3c2e899ac88acf4fa56e9770 Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Tue, 25 Apr 2017 10:47:09 -0700 Subject: Add a test case for nested enum, which was missed previously. (#3010) --- php/tests/proto/test_no_namespace.proto | 1 + 1 file changed, 1 insertion(+) diff --git a/php/tests/proto/test_no_namespace.proto b/php/tests/proto/test_no_namespace.proto index 3dd76764..58f13d47 100644 --- a/php/tests/proto/test_no_namespace.proto +++ b/php/tests/proto/test_no_namespace.proto @@ -7,6 +7,7 @@ message NoNamespaceMessage { ZERO = 0; } NestedEnum b = 2; + repeated NestedEnum c = 3; } enum NoNamespaceEnum { -- cgit v1.2.3 From a6189acd18b00611c1dc7042299ad75486f08a1a Mon Sep 17 00:00:00 2001 From: Paul Yang Date: Wed, 26 Apr 2017 16:32:21 -0700 Subject: Add prefix to enum value with reserved name. (#3020) --- php/tests/proto/test.proto | 1 + src/google/protobuf/compiler/php/php_generator.cc | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/php/tests/proto/test.proto b/php/tests/proto/test.proto index f0d009c8..39229254 100644 --- a/php/tests/proto/test.proto +++ b/php/tests/proto/test.proto @@ -119,6 +119,7 @@ enum TestEnum { ZERO = 0; ONE = 1; TWO = 2; + ECHO = 3; // Test reserved name. } // Test prefix for reserved words. diff --git a/src/google/protobuf/compiler/php/php_generator.cc b/src/google/protobuf/compiler/php/php_generator.cc index 4d475b1f..ea850c0f 100644 --- a/src/google/protobuf/compiler/php/php_generator.cc +++ b/src/google/protobuf/compiler/php/php_generator.cc @@ -49,8 +49,8 @@ const std::string kDescriptorMetadataFile = "GPBMetadata/Google/Protobuf/Internal/Descriptor.php"; const std::string kDescriptorDirName = "Google/Protobuf/Internal"; const std::string kDescriptorPackageName = "Google\\Protobuf\\Internal"; -const char* const kReservedNames[] = {"Empty"}; -const int kReservedNamesSize = 1; +const char* const kReservedNames[] = {"Empty", "ECHO"}; +const int kReservedNamesSize = 2; namespace google { namespace protobuf { @@ -559,7 +559,7 @@ void GenerateEnumToPool(const EnumDescriptor* en, io::Printer* printer) { const EnumValueDescriptor* value = en->value(i); printer->Print( "->value(\"^name^\", ^number^)\n", - "name", value->name(), + "name", ClassNamePrefix(value->name(), en) + value->name(), "number", IntToString(value->number())); } printer->Print("->finalizeToPool();\n\n"); @@ -845,7 +845,7 @@ void GenerateEnumFile(const FileDescriptor* file, const EnumDescriptor* en, const EnumValueDescriptor* value = en->value(i); GenerateEnumValueDocComment(&printer, value); printer.Print("const ^name^ = ^number^;\n", - "name", value->name(), + "name", ClassNamePrefix(value->name(), en) + value->name(), "number", IntToString(value->number())); } -- cgit v1.2.3